[MERGE] new kanban view
This branch introduces the new kanban view. It is not completely
compatible with the previous version. Here are a few importants
points to be aware of:
* the kanban view template is rendered directly, not put inside a div.
It means that if a template has more than one root, chaos will ensue
* kanban view has been split into several files, and various js modules
have changed. For example, the KanbanRecord class is now exported by
the 'web_kanban.Record' module. So, require statements need to be
updated
* records do not have access to the view (i.e., record.view.is_action_enabled('edit'))
You can use the 'editable' and 'deletable' key instead
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
odoo.define('journal_dashboard', function (require) {
|
||||
'use strict';
|
||||
|
||||
var kanban_common = require('web_kanban.common');
|
||||
var kanban_widgets = require('web_kanban.widgets');
|
||||
|
||||
var JournalDashboardGraph = kanban_common.AbstractField.extend({
|
||||
var JournalDashboardGraph = kanban_widgets.AbstractField.extend({
|
||||
start: function() {
|
||||
var self = this;
|
||||
self.graph_type = self.$node.attr('graph_type')
|
||||
@@ -86,6 +86,6 @@ var JournalDashboardGraph = kanban_common.AbstractField.extend({
|
||||
});
|
||||
|
||||
|
||||
kanban_common.registry.add('dashboard_graph', JournalDashboardGraph);
|
||||
kanban_widgets.registry.add('dashboard_graph', JournalDashboardGraph);
|
||||
|
||||
});
|
||||
@@ -194,7 +194,7 @@
|
||||
<a type="object" name="toggle_favorite"><i t-att-class="(record.show_on_dashboard.raw_value ? 'oe_star_on' : 'oe_star_off') + ' fa fa-star o_dashboard_star'" title="Click to add/remove from favorite"></i></a>
|
||||
</div>
|
||||
<div class="col-xs-6 text-right">
|
||||
<a t-if="widget.view.is_action_enabled('edit')" type="edit">Settings</a>
|
||||
<a t-if="widget.editable" type="edit">Settings</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -79,12 +79,13 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="posted,reconciled"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button class="oe_inline oe_stat_button" name="button_journal_entries"
|
||||
string="Journal Items" type="object" groups="account.group_account_manager"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="button_journal_entries"
|
||||
string="Journal Items" type="object"
|
||||
groups="account.group_account_manager"
|
||||
attrs="{'invisible':[('move_line_ids','=',[])]}" icon="fa-bars"/>
|
||||
<field name="move_line_ids" invisible="1"/>
|
||||
<button class="oe_inline oe_stat_button" name="button_invoices"
|
||||
<button class="oe_stat_button" name="button_invoices"
|
||||
string="Invoices" type="object"
|
||||
attrs="{'invisible':[('has_invoices','=',False)]}" icon="fa-bars"/>
|
||||
<field name="has_invoices" invisible="1"/>
|
||||
|
||||
@@ -442,8 +442,8 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="open,confirm"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="import_buttons">
|
||||
<button class="oe_inline oe_stat_button" name="button_journal_entries"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="button_journal_entries"
|
||||
string="Journal Items" type="object"
|
||||
attrs="{'invisible':[('move_line_ids','=',[])]}" icon="fa-bars"/>
|
||||
<field name="move_line_ids" invisible="1"/>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button type="action"
|
||||
class="oe_stat_button"
|
||||
id="invoice_button"
|
||||
@@ -85,10 +85,13 @@
|
||||
name="%(account.action_invoice_refund_out_tree)d"
|
||||
attrs="{'invisible': [('customer', '=', False)]}"
|
||||
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}">
|
||||
<div><strong><field name="total_invoiced"/></strong><br/>Invoiced</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value"><field name="total_invoiced"/></span>
|
||||
<span class="o_stat_text">Invoiced</span>
|
||||
</div>
|
||||
</button>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -99,12 +102,12 @@
|
||||
<field name="priority" eval="22"/>
|
||||
<field name="groups_id" eval="[(4, ref('analytic.group_analytic_accounting'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action" name="%(account.action_open_partner_analytic_accounts)d"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(account.action_open_partner_analytic_accounts)d"
|
||||
icon="fa-book">
|
||||
<field string="Contracts" name="contracts_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -132,10 +135,10 @@
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<page name="sales_purchases" position="after">
|
||||
<page string="Accounting" col="4" name="accounting" attrs="{'invisible': [('is_company','=',False),('parent_id','!=',False)]}">
|
||||
<page string="Accounting" name="accounting" attrs="{'invisible': [('is_company','=',False),('parent_id','!=',False)]}">
|
||||
<group>
|
||||
<group string="Sale" name="acc_sale">
|
||||
<button name="%(action_account_partner_followup_note)d" type="action" string="Log a followup note"/><br />
|
||||
<button name="%(action_account_partner_followup_note)d" class="oe_link" type="action" string="Log a followup note" colspan="2"/>
|
||||
<field name="property_payment_term" widget="selection"/>
|
||||
<field name="credit"/>
|
||||
<field name="credit_limit"/>
|
||||
@@ -154,16 +157,16 @@
|
||||
</group>
|
||||
</group>
|
||||
<group string="Bank Accounts" name="bank_accounts">
|
||||
<field name="bank_ids" context="{'default_partner_id': active_id, 'form_view_ref': 'base.view_partner_bank_form'}" nolabel="1">
|
||||
<tree string="Bank Details">
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="acc_number"/>
|
||||
<field name="bank_name"/>
|
||||
<field name="owner_name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<field name="bank_ids" context="{'default_partner_id': active_id, 'form_view_ref': 'base.view_partner_bank_form'}" nolabel="1">
|
||||
<tree string="Bank Details">
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="acc_number"/>
|
||||
<field name="bank_name"/>
|
||||
<field name="owner_name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Accounting" name="accounting_disabled" attrs="{'invisible': ['|',('is_company','=',True),('parent_id','=',False)]}">
|
||||
<div>
|
||||
@@ -174,4 +177,4 @@
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -374,18 +374,18 @@
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_form"/>
|
||||
<field eval="20" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//div[@name="buttons"]' position='inside'>
|
||||
<button class="oe_inline oe_stat_button"
|
||||
<div name="button_box" position='inside'>
|
||||
<button class="oe_stat_button"
|
||||
string="To invoice"
|
||||
icon="fa-money"
|
||||
name="%(action_hr_tree_invoiced_all)d"
|
||||
type="action"
|
||||
context="{'search_default_account_id': [active_id], 'default_account_id': active_id}"/>
|
||||
<button class="oe_inline oe_stat_button" string="Invoices"
|
||||
<button class="oe_stat_button" string="Invoices"
|
||||
icon="fa-book"
|
||||
name="%(action_contract_invoices_all)d"
|
||||
type="action"/>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -79,12 +79,12 @@
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name= "%(action_product_default_list)d" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name= "%(action_product_default_list)d" type="action"
|
||||
groups="analytic.group_analytic_accounting" icon="fa-xing">
|
||||
<field string="Analytic Rules" name="rules_count" widget="statinfo" />
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -93,12 +93,12 @@
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name= "action_view_rules" type="object"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name= "action_view_rules" type="object"
|
||||
groups="analytic.group_analytic_accounting" icon="fa-xing">
|
||||
<field string="Analytic Rules" name="rules_count" widget="statinfo" />
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -99,10 +99,10 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,open"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box oe_right">
|
||||
<button class="oe_inline oe_stat_button" name="open_entries" type="object" icon="fa-pencil">
|
||||
<field string="Entries" name="entry_count" widget="statinfo" />
|
||||
</button>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="open_entries" type="object" icon="fa-pencil">
|
||||
<field string="Entries" name="entry_count" widget="statinfo" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Analytic Account" version="7.0">
|
||||
<sheet string="Analytic Account">
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
</div>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
</xpath>
|
||||
<!-- add Reset Password button -->
|
||||
<xpath expr="//div[@class='oe_right oe_button_box']//button" position="replace">
|
||||
<xpath expr="//div[@name='button_box']//button" position="replace">
|
||||
<button string="Send Reset Password Instructions"
|
||||
class="oe_link"
|
||||
type="object" name="action_reset_password"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@class='oe_kanban_partner_categories']" position="inside">
|
||||
<xpath expr="//div[contains(@class, 'oe_kanban_partner_categories')]" position="inside">
|
||||
<span class="oe_kanban_list_many2many">
|
||||
<field name="category_id"/>
|
||||
</span>
|
||||
|
||||
@@ -121,8 +121,8 @@
|
||||
on_change="onchange_stage_id(stage_id)"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button class="oe_inline oe_stat_button" type="action"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="action"
|
||||
context="{'default_opportunity_id': active_id, 'search_default_opportunity_id': active_id, 'default_partner_id': partner_id, 'default_duration': 1.0}"
|
||||
name="%(crm.crm_phonecall_category_phone_incoming0)d" icon="fa-phone">
|
||||
<field string="Calls" name="calls_count" widget="statinfo"/>
|
||||
@@ -284,7 +284,7 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- CRM Lead Kanban View -->
|
||||
<!-- CRM Lead Kanban View -->
|
||||
<record model="ir.ui.view" id="crm_case_kanban_view_leads">
|
||||
<field name="name">CRM - Leads Kanban</field>
|
||||
<field name="model">crm.lead</field>
|
||||
@@ -300,15 +300,19 @@
|
||||
<field name="message_summary"/>
|
||||
<field name="message_unread"/>
|
||||
<field name="tag_ids"/>
|
||||
<field name="partner_id"/>
|
||||
<templates>
|
||||
<field name="date_deadline"/>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('edit')"><li><a type="edit">Edit Opportunity</a></li></t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')"><li><a type="delete">Delete</a></li></t>
|
||||
<div t-attf-class="#{kanban_color(record.color.raw_value)} o_kanban_small oe_kanban_global_click">
|
||||
<div class="o_dropdown_kanban dropdown">
|
||||
|
||||
<a class="dropdown-toggle btn" data-toggle="dropdown" href="#" >
|
||||
<span class="fa fa-bars fa-lg"/>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
|
||||
<t t-if="widget.editable"><li><a type="edit">Edit Opportunity</a></li></t>
|
||||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
|
||||
<li><a name="%(mail.action_email_compose_message_wizard)d" type="action" >Send Email</a></li>
|
||||
<li><a type="action" name="%(crm.crm_phonecall_category_phone_incoming0)d">Calls</a></li>
|
||||
<li><a name="action_schedule_meeting" type="object">Schedule Meeting</a></li>
|
||||
@@ -317,32 +321,17 @@
|
||||
</div>
|
||||
<div class="oe_kanban_content">
|
||||
<div>
|
||||
<strong><field name="name"/></strong>
|
||||
<t t-if="record.planned_revenue.raw_value">
|
||||
- <b><t t-esc="record.planned_revenue.value"/>
|
||||
<field name="company_currency"/></b>
|
||||
</t>
|
||||
</div>
|
||||
<div>
|
||||
<field name="partner_id"/>
|
||||
</div>
|
||||
<div class="oe_deadline">
|
||||
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())" t-set="red">oe_kanban_text_red</t>
|
||||
<span t-attf-class="#{red || ''}"><field name="date_action"/></span>
|
||||
<t t-if="record.date_action.raw_value"> : </t>
|
||||
<field name="title_action"/>
|
||||
</div>
|
||||
<div class="oe_kanban_footer_left">
|
||||
<field name="tag_ids"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<t t-raw="record.message_summary.raw_value"/>
|
||||
<div>
|
||||
<strong><field name="name"/></strong>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
<div class="text-muted">
|
||||
<span t-if="record.planned_revenue.raw_value"><t t-esc="record.planned_revenue.value"/><field name="company_currency"/></span> <span t-if="record.partner_id.value"> - <t t-esc="record.partner_id.value"/></span>
|
||||
</div>
|
||||
<div class="o_kanban_footer">
|
||||
<field name="priority" widget="priority" groups="base.group_user"/> <t t-raw="record.message_summary.raw_value"/>
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)" t-att-title="record.user_id.value" width="24" height="24" class="oe_kanban_avatar pull-right"/>
|
||||
<div class="pull-left" groups="base.group_user">
|
||||
<field name="priority" widget="priority"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_clear"></div>
|
||||
@@ -417,13 +406,13 @@
|
||||
domain="['&', ('team_ids', '=', team_id), '|', ('type', '=', type), ('type', '=', 'both')]"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div name="buttons" class="oe_right oe_button_box">
|
||||
<button class="oe_inline oe_stat_button" type="action"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="action"
|
||||
name="%(crm.crm_phonecall_category_phone_incoming0)d" icon="fa-phone"
|
||||
context="{'default_opportunity_id': active_id, 'search_default_opportunity_id': active_id, 'default_partner_id': partner_id, 'default_duration': 1.0}">
|
||||
<field string="Calls" name="calls_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" type="object"
|
||||
<button class="oe_stat_button" type="object"
|
||||
context="{'partner_id': partner_id}"
|
||||
name="action_schedule_meeting" icon="fa-calendar">
|
||||
<field string="Meetings" name="meeting_count" widget="statinfo"/>
|
||||
|
||||
@@ -87,19 +87,28 @@
|
||||
<field name="state" nolabel="1" widget="statusbar" clickable="True"/>
|
||||
</header>
|
||||
<sheet string="Phone Call">
|
||||
<div class="oe_right oe_button_box">
|
||||
<button class="oe_inline oe_stat_button" type="object" name="action_button_convert2opportunity"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="object" name="action_button_convert2opportunity"
|
||||
icon="fa-star" attrs="{'invisible':[ '|', ('opportunity_id','!=',False), ('state', 'not in', ('open', 'done'))]}"
|
||||
help="Convert To Opportunity">
|
||||
<div>Convert To<br/>Opportunity</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Convert To</span>
|
||||
<span class="o_stat_text">Opportunity</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<button class="oe_inline oe_stat_button" type="action"
|
||||
<button class="oe_stat_button" type="action"
|
||||
name="%(phonecall_to_phonecall_act)d" icon="fa-phone">
|
||||
<div>Schedule<br/>Other Call</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Schedule</span>
|
||||
<span class="o_stat_text">Other Call</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" name="action_make_meeting" type="object" icon="fa-calendar fa-fw">
|
||||
<div>Schedule<br/>A Meeting</div>
|
||||
<button class="oe_stat_button" name="action_make_meeting" type="object" icon="fa-calendar fa-fw">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Schedule</span>
|
||||
<span class="o_stat_text">A Meeting</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
|
||||
@@ -68,12 +68,8 @@
|
||||
<field name="meeting_count"/>
|
||||
</field>
|
||||
<xpath expr="//div[@class='oe_kanban_partner_links']" position="inside">
|
||||
<a name="%(relate_partner_opportunities)d" type="action" t-if="record.opportunity_count.value>0">
|
||||
<t t-esc="record.opportunity_count.value"/> Opportunities
|
||||
</a>
|
||||
<a name="%(calendar_event_partner)d" type="action" t-if="record.meeting_count.value>0">
|
||||
<t t-esc="record.meeting_count.value"/> Meetings
|
||||
</a>
|
||||
<span class="badge" t-if="record.opportunity_count.value>0"><i class="fa fa-fw fa-star"/><t t-esc="record.opportunity_count.value"/></span>
|
||||
<span class="badge" t-if="record.meeting_count.value>0"><i class="fa fa-fw fa-calendar"/><t t-esc="record.meeting_count.value"/></span>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -89,31 +85,30 @@
|
||||
<field name="user_id" position="after">
|
||||
<field name="team_id" completion="1" groups="base.group_multi_salesteams"/>
|
||||
</field>
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button o_res_partner_tip_opp" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button o_res_partner_tip_opp" type="action"
|
||||
attrs="{'invisible': [('customer', '=', False)]}"
|
||||
name="%(crm.crm_lead_opportunities)d"
|
||||
icon="fa-star"
|
||||
context="{'search_default_partner_id': active_id}">
|
||||
<field string="Opportunities" name="opportunity_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" type="object"
|
||||
<button class="oe_stat_button" type="object"
|
||||
name="schedule_meeting"
|
||||
icon="fa-calendar"
|
||||
context="{'partner_id': active_id}">
|
||||
<field string="Meetings" name="meeting_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" type="action"
|
||||
<button class="oe_stat_button" type="action"
|
||||
name="%(crm.crm_phonecall_category_phone_incoming0)d"
|
||||
icon="fa-phone"
|
||||
context="{'search_default_partner_id': active_id, 'default_duration': 1.0}">
|
||||
<field string="Calls" name="phonecall_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action"
|
||||
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}"
|
||||
name="%(crm_claim_category_claim0)d" icon="fa-comments" groups="base.group_sale_salesman">
|
||||
<field string="Claims" name="claim_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -35,14 +35,17 @@
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_form_view_leads" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action" name="%(convert_lead2projectissue_wizard_action)d" icon="fa-bug"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(convert_lead2projectissue_wizard_action)d" icon="fa-bug"
|
||||
help="Convert to Issue">
|
||||
<div>Convert To<br/>Issue</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Convert To</span>
|
||||
<span class="o_stat_text">Issue</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
||||
@@ -65,19 +65,19 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,done"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" groups="base.group_user">
|
||||
<div class="oe_button_box" name="button_box" groups="base.group_user">
|
||||
<button name="%(event.act_event_registration_from_event)d"
|
||||
type="action"
|
||||
class="oe_stat_button oe_inline oe_event_attendee_button"
|
||||
class="oe_stat_button oe_event_attendee_button"
|
||||
icon="fa-github"
|
||||
help="Register with this event">
|
||||
<field name="seats_reserved" widget="statinfo" string="Attendees"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<group name="main_field_group">
|
||||
<group>
|
||||
<field name="address_id" context="{'show_address': 1}" options='{"always_reload": True}'/>
|
||||
@@ -165,7 +165,7 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('delete')">
|
||||
<t t-if="widget.deletable">
|
||||
<li><a type="delete">Delete</a></li>
|
||||
</t>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
|
||||
+14
-14
@@ -190,20 +190,7 @@
|
||||
<field name="state_id" widget="statusbar" clickable="True" />
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label for="model_id" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="model_id" class="oe_inline" on_change="on_change_model(model_id)"/>
|
||||
</h1>
|
||||
<label for="license_plate" class="oe_edit_only"/>
|
||||
<h2>
|
||||
<field name="license_plate" class="oe_inline"/>
|
||||
</h2>
|
||||
<label for="tag_ids" class="oe_edit_only"/>
|
||||
<field name="tag_ids" widget="many2many_tags" />
|
||||
</div>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="return_action_to_open"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
@@ -245,6 +232,19 @@
|
||||
<field name="odometer_count" widget="statinfo" string="Odometer"/>
|
||||
</button>
|
||||
</div>
|
||||
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label for="model_id" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="model_id" class="oe_inline" on_change="on_change_model(model_id)"/>
|
||||
</h1>
|
||||
<label for="license_plate" class="oe_edit_only"/>
|
||||
<h2>
|
||||
<field name="license_plate" class="oe_inline"/>
|
||||
</h2>
|
||||
<label for="tag_ids" class="oe_edit_only"/>
|
||||
<field name="tag_ids" widget="many2many_tags" />
|
||||
</div>
|
||||
<group col="2" string="General Properties">
|
||||
<group >
|
||||
<field name="driver_id" />
|
||||
|
||||
@@ -42,8 +42,7 @@
|
||||
<button string="Grant this Badge" type="action" name="%(action_grant_wizard)d" class="oe_highlight" attrs="{'invisible': [('remaining_sending','=',0)]}" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
</div>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<field name="image" widget='image' class="oe_left oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
|
||||
@@ -40,6 +40,19 @@
|
||||
<field name="state" widget="statusbar" clickable="True"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<!-- action buttons -->
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button type="action"
|
||||
name="%(goals_from_challenge_act)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-gift"
|
||||
attrs="{'invisible': [('state','=','draft')]}">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Related</span>
|
||||
<span class="o_stat_text">Goals</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
@@ -53,16 +66,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- action buttons -->
|
||||
<div class="oe_right oe_button_box">
|
||||
<button type="action"
|
||||
name="%(goals_from_challenge_act)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-gift"
|
||||
attrs="{'invisible': [('state','=','draft')]}">
|
||||
<div>Related<br/>Goals</div>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="period" attrs="{'readonly':[('state','!=','draft')]}"/>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-if="widget.view.is_action_enabled('edit')" class="o_kanban_card_manage_settings row">
|
||||
<div t-if="widget.editable" class="o_kanban_card_manage_settings row">
|
||||
<div class="col-xs-8">
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</div>
|
||||
|
||||
+41
-43
@@ -23,6 +23,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Employee">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
@@ -36,11 +37,8 @@
|
||||
<label for="work_phone" class="oe_edit_only"/>
|
||||
<field name="work_phone"/>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<!-- Put here related buttons -->
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Public Information">
|
||||
<page name="public" string="Public Information">
|
||||
<group>
|
||||
<group string="Contact Information">
|
||||
<field name="address_id" on_change="onchange_address_id(address_id)"
|
||||
@@ -141,14 +139,14 @@
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<!-- HR Kanban View -->
|
||||
|
||||
<!-- HR Kanban View -->
|
||||
<record model="ir.ui.view" id="hr_kanban_view_employees">
|
||||
<field name="name">HR - Employess Kanban</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="priority">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<kanban class="o_hr_employee_kanban">
|
||||
<field name="last_login"/>
|
||||
<field name="message_is_follower"/>
|
||||
<field name="message_follower_ids"/>
|
||||
@@ -157,40 +155,40 @@
|
||||
<field name="message_unread"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="row oe_employee_details">
|
||||
<div class="col-md-4">
|
||||
<a type="open"><img t-att-src="kanban_image('hr.employee', 'image_medium', record.id.value)" class="img-responsive oe_employee_image"/></a>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<h4>
|
||||
<a type="open"><field name="name"/><t t-if="record.login.raw_value"> (<field name="login"/>)</t></a>
|
||||
</h4>
|
||||
<ul>
|
||||
<li id="last_login">
|
||||
<span t-if="record.last_login.raw_value && record.last_login.raw_value.is().today()" class="oe_kanban_button" style="font-size: 100%%">
|
||||
<t t-esc="moment(record.last_login.raw_value).format('LT')"/>
|
||||
</span>
|
||||
</li>
|
||||
<li t-if="record.job_id.raw_value"><field name="job_id"/></li>
|
||||
<li t-if="record.work_location.raw_value"><field name="work_location"/></li>
|
||||
<li t-if="record.work_phone.raw_value"><i class="fa fa-phone"></i> <field name="work_phone"/></li>
|
||||
<li t-if="record.mobile_phone.raw_value"><i class="fa fa-mobile"></i> <field name="mobile_phone"/></li>
|
||||
<li t-if="record.work_email.raw_value"><i class="fa fa-envelope"></i><a t-attf-href="mailto:#{record.work_email.value}"> <field name="work_email"/></a></li>
|
||||
</ul>
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<t t-raw="record.message_summary.raw_value"/>
|
||||
<span title='Messages'><i class='fa fa-comments'/><t t-esc="record.message_ids.raw_value.length"/></span>
|
||||
<span title='Followers'><i class='fa fa-users'/><t t-esc="record.message_follower_ids.raw_value.length"/></span>
|
||||
</div>
|
||||
<div class="oe_followers" groups="base.group_user">
|
||||
<button t-if="record.message_is_follower.raw_value" name="action_unfollow" type="object" class="oe_follower oe_following">
|
||||
<span class="oe_unfollow">Unfollow</span>
|
||||
<span class="oe_following">Following</span>
|
||||
</button>
|
||||
<button t-if="! record.message_is_follower.raw_value" name="action_follow" type="object" class="oe_follower oe_notfollow">Follow</button>
|
||||
</div>
|
||||
<div class="o_kanban_two_column oe_kanban_global_click oe_employee_details">
|
||||
<div class="o_kanban_image">
|
||||
<img t-att-src="kanban_image('hr.employee', 'image_medium', record.id.value)"/>
|
||||
<div class="o_employee_summary_icons">
|
||||
<t t-raw="record.message_summary.raw_value"/>
|
||||
<span title='Messages'><i class='fa fa-comments'/><t t-esc="record.message_ids.raw_value.length"/></span>
|
||||
<span title='Followers'><i class='fa fa-users'/><t t-esc="record.message_follower_ids.raw_value.length"/></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_kanban_details oe_employee_details_content">
|
||||
<strong>
|
||||
<field name="name"/><t t-if="record.login.raw_value"> (<field name="login"/>)</t>
|
||||
</strong>
|
||||
<ul>
|
||||
<li id="last_login">
|
||||
<span t-if="record.last_login.raw_value && record.last_login.raw_value.is().today()" class="oe_kanban_button" style="font-size: 100%%">
|
||||
<t t-esc="moment(record.last_login.raw_value).format('LT')"/>
|
||||
</span>
|
||||
</li>
|
||||
<li t-if="record.job_id.raw_value"><field name="job_id"/></li>
|
||||
<li t-if="record.work_location.raw_value"><field name="work_location"/></li>
|
||||
<li t-if="record.work_email.raw_value"><i class="fa fa-envelope"></i> <field name="work_email"/></li>
|
||||
<li t-if="record.work_phone.raw_value"><i class="fa fa-phone"></i> <field name="work_phone"/></li>
|
||||
<li t-if="record.mobile_phone.raw_value"><i class="fa fa-mobile"></i> <field name="mobile_phone"/></li>
|
||||
</ul>
|
||||
<div class="oe_followers o_kanban_button">
|
||||
<button t-if="record.message_is_follower.raw_value" name="action_unfollow" type="object" class="o_follow_btn o_following btn btn-primary">
|
||||
<span class="o_unfollow">Unfollow</span>
|
||||
<span class="o_following">Following</span>
|
||||
</button>
|
||||
<button t-if="!record.message_is_follower.raw_value" name="action_follow" type="object" class="o_follow_btn o_not_following btn btn-primary">Follow</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
@@ -352,14 +350,14 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="recruit,open"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right" name="button_box"/>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name" class="oe_inline"/></h1>
|
||||
<h1><field name="name"/></h1>
|
||||
</div>
|
||||
<div class="oe_right" name="buttons"/>
|
||||
<group name="employee_data">
|
||||
<field name="department_id" groups="hr.group_multi_departments" class="oe_inline"/>
|
||||
<field name="no_of_recruitment" class="oe_inline" />
|
||||
<field name="department_id" groups="hr.group_multi_departments"/>
|
||||
<field name="no_of_recruitment"/>
|
||||
</group>
|
||||
<div attrs="{'invisible': [('state', '!=', 'recruit')]}">
|
||||
<label for="description"/>
|
||||
@@ -520,4 +518,4 @@
|
||||
groups="group_multi_departments"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -1,8 +0,0 @@
|
||||
odoo.define('hr.hr', function(require) {
|
||||
"use strict";
|
||||
|
||||
var common = require('web_kanban.common');
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
.oe_kanban_view.o_kanban_dashboard.o_hr_kanban {
|
||||
.oe_kanban_record {
|
||||
max-width: 500px;
|
||||
min-width: 400px;
|
||||
min-height: 200px;
|
||||
}
|
||||
.o_kanban_view {
|
||||
.o_kanban_record.oe_employee_details {
|
||||
.oe_employee_details_content {
|
||||
padding-left: 16px;
|
||||
|
||||
> h4 {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
<link rel="stylesheet" href="/hr/static/src/css/hr.css"/>
|
||||
<link rel="stylesheet" href="/hr/static/src/less/hr_dashboard.less"/>
|
||||
<script type="text/javascript" src="/hr/static/src/js/suggestions.js"></script>
|
||||
<script type="text/javascript" src="/hr/static/src/js/hr.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(act_hr_employee_2_hr_contract)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
@@ -27,7 +27,7 @@
|
||||
groups="base.group_hr_manager">
|
||||
<field name="contracts_count" widget="statinfo" string="Contracts"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
<xpath expr="//field[@name='coach_id']" position="after">
|
||||
<field name="manager"/>
|
||||
</xpath>
|
||||
|
||||
@@ -92,8 +92,8 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg" />
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('edit')"><li><a type="edit">Edit...</a></li></t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')"><li><a type="delete">Delete</a></li></t>
|
||||
<t t-if="widget.editable"><li><a type="edit">Edit...</a></li></t>
|
||||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -192,13 +192,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Equipments">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only" string="Name"/>
|
||||
<h1><field name="name" string="Name"/></h1>
|
||||
<label for="serial_no" class="oe_edit_only"/>
|
||||
<field name="serial_no"/>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(hr_equipment_request_action_from_equipment)d"
|
||||
type="action"
|
||||
class="oe_stat_button"
|
||||
@@ -206,6 +200,12 @@
|
||||
<field string="Maintenance" name="maintenance_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only" string="Name"/>
|
||||
<h1><field name="name" string="Name"/></h1>
|
||||
<label for="serial_no" class="oe_edit_only"/>
|
||||
<field name="serial_no"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="category_id" groups="base.group_equipment_manager" on_change="1" options="{"no_open": True}"/>
|
||||
@@ -265,8 +265,8 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg" />
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('edit')"><li><a type="edit">Edit...</a></li></t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')"><li><a type="delete">Delete</a></li></t>
|
||||
<t t-if="widget.editable"><li><a type="edit">Edit...</a></li></t>
|
||||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -392,13 +392,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Equipment Categories">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only" string="Category Name"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(hr_equipment_action_from_category_form)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-laptop"
|
||||
@@ -412,6 +406,12 @@
|
||||
<field string="Maintenance" name="maintenance_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only" string="Category Name"/>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group col="4">
|
||||
<field name="user_id"/>
|
||||
|
||||
@@ -147,14 +147,14 @@
|
||||
<field name="evaluation_date"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(act_hr_employee_2_hr__evaluation_interview)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-sitemap"
|
||||
type="action">
|
||||
<field name="appraisal_count" widget="statinfo" string="Appraisals"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="waiting_answer,done"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button string="Send Reminder Email" name="%(mail.action_email_compose_message_wizard)d" type="action"
|
||||
states="waiting_answer"
|
||||
context="{'default_body': 'Hello,\n\nKindly post your response for the survey interview.\n\nThanks',
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
odoo.define('hr_gamification.hr_gamification', function(require) {
|
||||
"use strict";
|
||||
|
||||
var common = require('web_kanban.common');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
|
||||
common.KanbanRecord.include({
|
||||
KanbanRecord.include({
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'gamification.badge.user') {
|
||||
if (this.model === 'gamification.badge.user') {
|
||||
var action = {
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'gamification.badge',
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
<field name="model">gamification.badge</field>
|
||||
<field name="inherit_id" ref="gamification.badge_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@class='oe_right oe_button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button string="Granted Employees" type="object" name="get_granted_employees" attrs="{'invisible': [('stat_count','=',0)]}" />
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -589,7 +589,7 @@
|
||||
</div>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(act_hr_employee_holiday_request_approved)d"
|
||||
icon="fa-calendar"
|
||||
class="oe_stat_button"
|
||||
@@ -604,7 +604,7 @@
|
||||
groups="base.group_hr_user">
|
||||
<field name="leaves_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(act_payslip_lines)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-money"
|
||||
@@ -391,7 +391,7 @@
|
||||
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(act_hr_employee_payslip_list)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-money"
|
||||
@@ -399,7 +399,7 @@
|
||||
groups="base.group_hr_user">
|
||||
<field name="payslip_count" widget="statinfo" string="Payslips"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-if="widget.view.is_action_enabled('edit')" class="o_kanban_card_manage_settings row">
|
||||
<div t-if="widget.editable" class="o_kanban_card_manage_settings row">
|
||||
<div class="col-xs-8">
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</div>
|
||||
|
||||
@@ -62,10 +62,12 @@
|
||||
<field name="stage_id" widget="statusbar" clickable="True" options="{'fold_field': 'fold'}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_makeMeeting" class="oe_stat_button" icon="fa-calendar" type="object"
|
||||
help="Schedule interview with this applicant">
|
||||
<div>Meetings</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Meetings</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_start_survey"
|
||||
class="oe_stat_button"
|
||||
@@ -74,7 +76,10 @@
|
||||
help="Answer related job question"
|
||||
context="{'survey_id': survey}"
|
||||
attrs="{'invisible':[('survey','=',False)]}">
|
||||
<div>Start<br/>Interview</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Start</span>
|
||||
<span class="o_stat_text">Interview</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_print_survey"
|
||||
class="oe_stat_button"
|
||||
@@ -82,7 +87,10 @@
|
||||
type="object"
|
||||
help="Print interview report"
|
||||
attrs="{'invisible':[('survey','=',False)]}">
|
||||
<div>Print<br/>Interview</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Print</span>
|
||||
<span class="o_stat_text">Interview</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_get_attachment_tree_view"
|
||||
class="oe_stat_button"
|
||||
@@ -268,7 +276,7 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('delete')"><li><a type="delete">Delete</a></li></t>
|
||||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
|
||||
<li><a name="action_makeMeeting" type="object">Schedule Interview</a></li>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
@@ -375,14 +383,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<group name="employee_data" position="inside">
|
||||
<label for="survey_id" groups="base.group_user"/>
|
||||
<div groups="base.group_user">
|
||||
<field name="survey_id" class="oe_inline"/>
|
||||
<button string="Print Interview" name="action_print_survey" type="object" attrs="{'invisible':[('survey_id','=',False)]}" class="oe_inline oe_link"/>
|
||||
</div>
|
||||
<label for="address_id"/>
|
||||
<div>
|
||||
<field name="address_id" context="{'show_address': 1}" domain= "[('is_company', '=', True )]"/>
|
||||
<div groups="base.group_user" class="o_row">
|
||||
<field name="survey_id"/>
|
||||
<button string="Print Interview" name="action_print_survey" type="object" attrs="{'invisible':[('survey_id','=',False)]}" class="oe_link"/>
|
||||
</div>
|
||||
<field name="address_id" context="{'show_address': 1}" domain= "[('is_company', '=', True )]"/>
|
||||
</group>
|
||||
<group name="employee_data" position="after">
|
||||
<notebook>
|
||||
@@ -392,46 +397,45 @@
|
||||
</notebook>
|
||||
</group>
|
||||
<xpath expr="//field[@name='department_id']" position="after">
|
||||
<label for="alias_name" string="Specific Email Address" attrs="{'invisible': [('alias_domain', '=', False)]}" help ="Define a specific contact address for this job position. If you keep it empty, the default email address will be used which is in human resources settings"/>
|
||||
<div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}">
|
||||
<field name="alias_id" class="oe_read_only oe_inline"
|
||||
string="Email Alias" required="0"/>
|
||||
<div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
|
||||
<field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
|
||||
</div>
|
||||
<label for="alias_name" string="Specific Email Address" attrs="{'invisible': [('alias_domain', '=', False)]}" help="Define a specific contact address for this job position. If you keep it empty, the default email address will be used which is in human resources settings"/>
|
||||
<div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}">
|
||||
<field name="alias_id" class="oe_read_only" string="Email Alias" required="0"/>
|
||||
<div class="oe_edit_only" name="edit_alias">
|
||||
<field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='department_id']" position="after">
|
||||
<field name="user_id" class="oe_inline"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<div class="oe_button_box" >
|
||||
<button class="oe_stat_button"
|
||||
icon="fa-file-o"
|
||||
name="%(action_hr_job_applications)d"
|
||||
context="{'default_user_id': user_id}"
|
||||
type="action">
|
||||
<field name="application_count" widget="statinfo" string="Applications"/>
|
||||
</button>
|
||||
<button class="oe_stat_button"
|
||||
icon="fa-users"
|
||||
name="%(action_hr_job_no_employee)d"
|
||||
type="action">
|
||||
<field name="no_of_employee" widget="statinfo" string="Employees"/>
|
||||
</button>
|
||||
<button class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
name="action_get_attachment_tree_view"
|
||||
type="object">
|
||||
<field name="documents_count" widget="statinfo" string="Documents"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" type="action"
|
||||
name="%(action_hr_job_sources)d" icon="fa-share"
|
||||
context="{'default_job_id': active_id}">
|
||||
<div>Trackers</div>
|
||||
</button>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='department_id']" position="after">
|
||||
<field name="user_id"/>
|
||||
</xpath>
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button"
|
||||
icon="fa-file-o"
|
||||
name="%(action_hr_job_applications)d"
|
||||
context="{'default_user_id': user_id}"
|
||||
type="action">
|
||||
<field name="application_count" widget="statinfo" string="Applications"/>
|
||||
</button>
|
||||
<button class="oe_stat_button"
|
||||
icon="fa-users"
|
||||
name="%(action_hr_job_no_employee)d"
|
||||
type="action">
|
||||
<field name="no_of_employee" widget="statinfo" string="Employees"/>
|
||||
</button>
|
||||
<button class="oe_stat_button"
|
||||
icon="fa-book"
|
||||
name="action_get_attachment_tree_view"
|
||||
type="object">
|
||||
<field name="documents_count" widget="statinfo" string="Documents"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" type="action"
|
||||
name="%(action_hr_job_sources)d" icon="fa-share"
|
||||
context="{'default_job_id': active_id}">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Trackers</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -502,6 +506,7 @@
|
||||
<menuitem
|
||||
name="Recruitment"
|
||||
id="menu_hr_recruitment_root"
|
||||
web_icon="hr_recruitment,static/description/icon.png"
|
||||
sequence="80"/>
|
||||
|
||||
<menuitem id="menu_hr_recruitment_configuration" name="Configuration" parent="menu_hr_recruitment_root"
|
||||
@@ -695,4 +700,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -1,11 +1,11 @@
|
||||
odoo.define('hr_recruitment.hr_recruitment', function(require) {
|
||||
"use strict";
|
||||
|
||||
var common = require('web_kanban.common');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
|
||||
common.KanbanRecord.include({
|
||||
KanbanRecord.include({
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'hr.job') {
|
||||
if (this.model === 'hr.job') {
|
||||
this.$('.oe_applications a').first().click();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
@@ -118,10 +118,10 @@
|
||||
<field name="invoice_on_timesheets"/>
|
||||
<label for="invoice_on_timesheets"/>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="buttons"]' position='inside'>
|
||||
<button class="oe_inline oe_stat_button" type="action" name="%(act_analytic_cost_revenue)d"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(act_analytic_cost_revenue)d"
|
||||
icon="fa-usd" string="Cost/Revenue" widget="statinfo"/>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -87,12 +87,15 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="new,confirm,done"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button type="action"
|
||||
name="%(act_hr_timesheet_sheet_sheet_2_hr_analytic_timesheet)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-clock-o">
|
||||
<div><strong><field name="total_timesheet" widget="float_time"/></strong><br/>Timesheet</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value"><field name="total_timesheet" widget="float_time"/></span>
|
||||
<span class="o_stat_text">Timesheet</span>
|
||||
</div>
|
||||
</button>
|
||||
<button type="action" groups="base.group_hr_attendance"
|
||||
class="oe_stat_button" icon="fa-users"
|
||||
@@ -378,7 +381,7 @@
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" ref="hr_timesheet.hr_timesheet_employee_extd_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(act_hr_employee_2_hr_timesheet)d"
|
||||
type="action"
|
||||
class="oe_stat_button"
|
||||
@@ -386,7 +389,7 @@
|
||||
groups="base.group_hr_manager">
|
||||
<field name="timesheet_count" widget="statinfo" string="Timesheets"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -71,6 +71,14 @@
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="action" attrs="{'invisible':[('nbr_session','=', 0)]}" name="%(im_chat_session_action_from_channel)d" icon="fa-comments">
|
||||
<field string="Sessions" name="nbr_session" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_view_rating" attrs="{'invisible':[('rating_percentage_satisfaction','=', -1)]}" class="oe_stat_button" type="object" icon="fa-smile-o">
|
||||
<field string="% Happy" name="rating_percentage_satisfaction" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<field name="image" widget='image' class="oe_avatar oe_left" options='{"preview_image": "image_medium"}'/>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
@@ -83,14 +91,6 @@
|
||||
<field name="are_you_inside" invisible="1"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button class="oe_inline oe_stat_button" type="action" attrs="{'invisible':[('nbr_session','=', 0)]}" name="%(im_chat_session_action_from_channel)d" icon="fa-comments">
|
||||
<field string="Sessions" name="nbr_session" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_view_rating" attrs="{'invisible':[('rating_percentage_satisfaction','=', -1)]}" class="oe_stat_button" type="object" icon="fa-smile-o">
|
||||
<field string="% Happy" name="rating_percentage_satisfaction" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group string="Operators">
|
||||
<field name="user_ids" widget="many2many_kanban" nolabel="1" colspan="2">
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Alias">
|
||||
<sheet>
|
||||
<h2><field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline"/></h2>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="open_document" string="Open Document"
|
||||
type="object" class="oe_link"
|
||||
attrs="{'invisible': ['|', ('alias_model_id', '=', False), ('alias_force_thread_id', '=', 0)]}"/>
|
||||
@@ -18,6 +17,7 @@
|
||||
type="object" class="oe_link"
|
||||
attrs="{'invisible': ['|', ('alias_parent_model_id', '=', False), ('alias_parent_thread_id', '=', 0)]}"/>
|
||||
</div>
|
||||
<h2><field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline"/></h2>
|
||||
<group>
|
||||
<field name="alias_model_id"/>
|
||||
<field name="alias_force_thread_id"/>
|
||||
|
||||
@@ -7,6 +7,29 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Templates">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<field name="ref_ir_act_window" invisible="1"/>
|
||||
<button class="oe_stat_button" name="create_action" type="object"
|
||||
attrs="{'invisible':[('ref_ir_act_window','!=',False)]}" icon="fa-plus"
|
||||
help="Display an option on related documents to open a composition wizard with this template">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Add</span>
|
||||
<span class="o_stat_text">Context Action</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="unlink_action" type="object"
|
||||
class="oe_stat_button" icon="fa-minus"
|
||||
attrs="{'invisible':[('ref_ir_act_window','=',False)]}"
|
||||
help="Remove the contextual action to use this template on related documents" widget="statinfo">
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Remove</span>
|
||||
<span class="o_stat_text">Context Action</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="%(wizard_email_template_preview)d" icon="fa-search-plus" string="Preview"
|
||||
type="action" target="new"
|
||||
context="{'template_id':active_id}"/>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/><h1><field name="name" required="1"/></h1>
|
||||
<group>
|
||||
@@ -14,23 +37,6 @@
|
||||
<field name="model" invisible="1"/>
|
||||
</group>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<field name="ref_ir_act_window" invisible="1"/>
|
||||
<button class="oe_inline oe_stat_button" name="create_action" type="object"
|
||||
attrs="{'invisible':[('ref_ir_act_window','!=',False)]}" icon="fa-plus"
|
||||
help="Display an option on related documents to open a composition wizard with this template">
|
||||
<div>Add<br/>Context Action</div>
|
||||
</button>
|
||||
<button name="unlink_action" type="object"
|
||||
class="oe_stat_button" icon="fa-minus"
|
||||
attrs="{'invisible':[('ref_ir_act_window','=',False)]}"
|
||||
help="Remove the contextual action to use this template on related documents" widget="statinfo">
|
||||
<div>Remove<br/>Context Action</div>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" name="%(wizard_email_template_preview)d" icon="fa-search-plus" string="Preview"
|
||||
type="action" target="new"
|
||||
context="{'template_id':active_id}"/>
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Content">
|
||||
<label for="subject"/>
|
||||
|
||||
@@ -61,13 +61,16 @@
|
||||
<field name="state" readonly="1" widget="statusbar" statusbar_visible="draft,running,done"/>
|
||||
</header>
|
||||
<sheet string="Campaign">
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button type="action"
|
||||
name="%(act_marketing_campaing_stat)d"
|
||||
class="oe_stat_button"
|
||||
icon="fa-keyboard-o"
|
||||
help="Marketing Campaign Statistics">
|
||||
<div>Campaign<br/>Statistics</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Campaign</span>
|
||||
<span class="o_stat_text">Statistics</span>
|
||||
</div>
|
||||
</button>
|
||||
<button type="action"
|
||||
name="%(act_marketing_campaing_segment_opened)d"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
odoo.define('mass_mailing.mass_mailing', function (require) {
|
||||
|
||||
var core = require('web.core');
|
||||
var common = require('web_kanban.common');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
var KanbanView = require('web_kanban.KanbanView');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
common.KanbanRecord.include({
|
||||
KanbanRecord.include({
|
||||
on_card_clicked: function (event) {
|
||||
if (this.view.dataset.model === 'mail.mass_mailing.campaign') {
|
||||
if (this.model === 'mail.mass_mailing.campaign') {
|
||||
this.$('.oe_mailings').click();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Templates">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(mail.wizard_email_template_preview)d" string="Preview"
|
||||
type="action" target="new"
|
||||
context="{'template_id':active_id}"/>
|
||||
<br />
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" required="True"/>
|
||||
@@ -19,14 +25,6 @@
|
||||
<field name="model" invisible="True"/>
|
||||
<field name="use_default_to" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<button name="%(mail.wizard_email_template_preview)d" string="Preview"
|
||||
type="action" target="new"
|
||||
context="{'template_id':active_id}"/>
|
||||
<br />
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Body">
|
||||
@@ -50,11 +48,11 @@
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click oe_kanban_email_template">
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu" t-if="widget.view.is_action_enabled('edit') or widget.view.is_action_enabled('delete')">
|
||||
<t t-if="widget.view.is_action_enabled('edit')">
|
||||
<ul class="oe_dropdown_menu" t-if="widget.editable or widget.deletable">
|
||||
<t t-if="widget.editable">
|
||||
<li><a type="edit">Edit</a></li>
|
||||
</t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')">
|
||||
<t t-if="widget.deletable">
|
||||
<li><a type="delete">Delete</a></li>
|
||||
</t>
|
||||
</ul>
|
||||
|
||||
@@ -245,9 +245,9 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contact List">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(mass_mailing.action_view_mass_mailing_contacts_from_list)d"
|
||||
type="action" icon="fa-user" class="oe_stat_button pull-right">
|
||||
type="action" icon="fa-user" class="oe_stat_button">
|
||||
<field name="contact_nbr" string="Recipients" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
@@ -392,7 +392,7 @@
|
||||
</strong></p>
|
||||
</div>
|
||||
<sheet>
|
||||
<div class="oe_button_box pull-right" attrs="{'invisible': [('state', 'in', ('draft','test'))]}">
|
||||
<div class="oe_button_box" name="button_box" attrs="{'invisible': [('state', 'in', ('draft','test'))]}">
|
||||
<button name="%(action_view_mail_mail_statistics_mailing)d" type="action"
|
||||
icon="fa-envelope-o" class="oe_stat_button"
|
||||
attrs="{'invisible': [('sent', '=', 0)]}" >
|
||||
@@ -499,7 +499,7 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('delete')">
|
||||
<t t-if="widget.deletable">
|
||||
<li><a type="delete">Delete</a></li>
|
||||
</t>
|
||||
</ul>
|
||||
@@ -705,43 +705,39 @@
|
||||
<span><field name="stage_id" widget="statusbar" clickable="True"/></span>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="total" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box"
|
||||
attrs="{'invisible': [('total', '=', 0)]}">
|
||||
<button name="%(action_view_mass_mailings_from_campaign)d"
|
||||
type="action" class="oe_stat_button" icon="fa-envelope-o">
|
||||
<field name="total_mailings" widget="statinfo" string="Mailings"/>
|
||||
</button>
|
||||
<button name="%(action_view_mail_mail_statistics_mailing)d" type="action"
|
||||
icon="fa-envelope-o" class="oe_stat_button"
|
||||
attrs="{'invisible': [('sent', '=', 0)]}" >
|
||||
<field name="sent" string="Emails Sent" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="%(action_view_mass_mailing_contacts)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="received_ratio" widget="percentpie" string="Received"/>
|
||||
</button>
|
||||
<button name="%(action_view_mass_mailing_contacts)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="opened_ratio" widget="percentpie" string="Opened"/>
|
||||
</button>
|
||||
<button name="%(action_view_mass_mailing_contacts)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="replied_ratio" widget="percentpie" string="Replied"/>
|
||||
</button>
|
||||
<button name="%(dropdb snipp)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="clicks_ratio" widget="percentpie" string="Clicks"/>
|
||||
</button>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" string="Campaign Name" on_change="on_change_campaign_name(name)"/>
|
||||
<field name="user_id"/>
|
||||
<field name="tag_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="total" invisible="1"/>
|
||||
<div class="oe_right oe_button_box" name="buttons"
|
||||
attrs="{'invisible': [('total', '=', 0)]}">
|
||||
<button name="%(action_view_mass_mailings_from_campaign)d"
|
||||
type="action" class="oe_inline oe_stat_button" icon="fa-envelope-o">
|
||||
<field name="total_mailings" widget="statinfo" string="Mailings"/>
|
||||
</button>
|
||||
<button name="%(action_view_mail_mail_statistics_mailing)d" type="action"
|
||||
icon="fa-envelope-o" class="oe_stat_button"
|
||||
attrs="{'invisible': [('sent', '=', 0)]}" >
|
||||
<field name="sent" string="Emails Sent" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="%(action_view_mass_mailing_contacts)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="received_ratio" widget="percentpie" string="Received"/>
|
||||
</button>
|
||||
<button name="%(action_view_mass_mailing_contacts)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="opened_ratio" widget="percentpie" string="Opened"/>
|
||||
</button>
|
||||
<button name="%(action_view_mass_mailing_contacts)d"
|
||||
type="action" class="oe_stat_button oe_inline">
|
||||
<field name="replied_ratio" widget="percentpie" string="Replied"/>
|
||||
</button>
|
||||
<button name="%(dropdb snipp)d"
|
||||
type="action" class="oe_stat_button">
|
||||
<field name="clicks_ratio" widget="percentpie" string="Clicks"/>
|
||||
</button>
|
||||
</div>
|
||||
</group>
|
||||
<field name="name" string="Campaign Name" on_change="on_change_campaign_name(name)"/>
|
||||
<field name="user_id"/>
|
||||
<field name="tag_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Tracking">
|
||||
@@ -787,10 +783,10 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('edit')">
|
||||
<t t-if="widget.editable">
|
||||
<li><a type="edit">Settings</a></li>
|
||||
</t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')">
|
||||
<t t-if="widget.deletable">
|
||||
<li><a type="delete">Delete</a></li>
|
||||
</t>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
|
||||
@@ -1105,12 +1105,12 @@
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('mrp.group_mrp_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="buttons" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="%(template_open_bom)d" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="%(template_open_bom)d" type="action"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-flask">
|
||||
<field string="Bill of Materials" name="bom_count" widget="statinfo" />
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" name="action_view_mos" type="object"
|
||||
<button class="oe_stat_button" name="action_view_mos" type="object"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-list-alt">
|
||||
<field string="Manufacturing" name="mo_count" widget="statinfo" />
|
||||
</button>
|
||||
@@ -1124,12 +1124,12 @@
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('mrp.group_mrp_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<div name="buttons" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="action_view_bom" type="object"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="action_view_bom" type="object"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-flask">
|
||||
<field string="Bill of Materials" name="bom_count" widget="statinfo" />
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" name="%(act_product_mrp_production)d" type="action"
|
||||
<button class="oe_stat_button" name="%(act_product_mrp_production)d" type="action"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-list-alt">
|
||||
<field string="Manufacturing" name="mo_count" widget="statinfo" />
|
||||
</button>
|
||||
|
||||
+24
-22
@@ -54,32 +54,32 @@
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
|
||||
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_global_click_edit oe_semantic_html_override oe_kanban_card">
|
||||
<div class="oe_dropdown_kanban oe_dropdown_toggle">
|
||||
<!-- dropdown menu -->
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<li><a type="delete">Delete</a></li>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
<div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click_edit oe_semantic_html_override oe_kanban_card">
|
||||
|
||||
<div class="o_dropdown_kanban dropdown">
|
||||
<a class="dropdown-toggle btn" data-toggle="dropdown" href="#" >
|
||||
<span class="fa fa-bars fa-lg"/>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
|
||||
<li><a type="delete">Delete</a></li>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div style="display: inline" class="oe_dropdown_kanban">
|
||||
<span class="oe_dropdown_kanban">
|
||||
<a name="onclick_note_is_done" type="object" t-if="record.open.raw_value"><i class="fa fa-check"/></a>
|
||||
<a name="onclick_note_not_done" type="object" t-if="!record.open.raw_value"><i class="fa fa-check"/></a>
|
||||
</div>
|
||||
</span>
|
||||
<!-- kanban note -->
|
||||
<div t-attf-class="oe_kanban_content #{record.open.raw_value ? '' : 'note_text_line_through'}">
|
||||
<span t-attf-class="oe_kanban_content #{record.open.raw_value ? '' : 'note_text_line_through'}">
|
||||
<!-- title -->
|
||||
<field name="name"/>
|
||||
</div>
|
||||
<div class="oe_clear"></div>
|
||||
</span>
|
||||
<div class="clearfix"></div>
|
||||
<field name="tag_ids"/>
|
||||
<div class="oe_right">
|
||||
<t t-foreach="record.message_follower_ids.raw_value" t-as="follower">
|
||||
<img t-att-src="kanban_image('res.partner', 'image_small', follower)" width="24" height="24" class="oe_kanban_avatar" t-att-data-member_id="follower"/>
|
||||
<img t-att-src="kanban_image('res.partner', 'image_small', follower)" width="24" height="24" class="oe_kanban_avatar pull-right" t-att-data-member_id="follower"/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="oe_clear"></div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -106,12 +106,14 @@
|
||||
<field name="name">note.note.form</field>
|
||||
<field name="model">note.note</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Note" class="oe_form_nomargin">
|
||||
<form string="Note" class="oe_form_nomargin o_note_form_view">
|
||||
<header>
|
||||
<field name="tag_ids" widget="many2many_tags" class="oe_inline" placeholder="Tags"/>
|
||||
<field name="tag_ids" widget="many2many_tags" placeholder="Tags"/>
|
||||
<field name="stage_id" domain="[('user_id','=',uid)]" widget="statusbar" clickable="1"/>
|
||||
</header>
|
||||
<field name="memo" widget="html" class="oe_memo" editor_height="450px" />
|
||||
<sheet>
|
||||
<field name="memo" widget="html" class="oe_memo" editor_height="450px" />
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
<field name="message_ids" widget="mail_thread"/>
|
||||
@@ -182,9 +184,9 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Notes" id="menu_note_notes" sequence="3" action="note.action_note_note"/>
|
||||
<menuitem name="Notes" id="menu_note_notes" sequence="3" action="note.action_note_note" web_icon="note,static/description/icon.png"/>
|
||||
<menuitem name="Configuration" id="menu_note_configuration" sequence="100" parent="menu_note_notes" groups="base.group_configuration"/>
|
||||
<menuitem name="Stages" id="menu_notes_stage" parent="menu_note_configuration" action="note.action_note_stage" sequence="21" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -806,14 +806,20 @@
|
||||
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="%(action_pos_box_in)d"
|
||||
type="action" states="opened,closing_control" icon="fa-level-down">
|
||||
<div>Put<br/>Money In</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Put</span>
|
||||
<span class="o_stat_text">Money In</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="%(action_pos_box_out)d"
|
||||
type="action" states="opened,closing_control" icon="fa-level-up">
|
||||
<div>Take<br/>Money Out</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_text">Take</span>
|
||||
<span class="o_stat_text">Money Out</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<h1 class="oe_title">
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
<field name="state" readonly="1" widget="statusbar" statusbar_visible="draft,confirmed,running,done" />
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<button name="do_view_procurements" class="oe_stat_button" icon="fa-bars" string="Group's Procurements" type="object"/>
|
||||
</div>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="do_view_procurements" class="oe_stat_button" icon="fa-bars" string="Group's Procurements" type="object"/>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="product_id" on_change="onchange_product_id(product_id)"/>
|
||||
@@ -98,7 +98,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Procurement group">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="%(do_view_procurements)d" string="Procurements" type="action"/>
|
||||
</div>
|
||||
<group>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<field string="Product Variant" name="product_variant_ids" filter_domain="['|', ('product_variant_ids.name','ilike',self), ('product_variant_ids.attribute_value_ids.attribute_id.name','ilike',self)]"/>
|
||||
<field name="company_id"/>
|
||||
<field name="pricelist_id" widget="selection" context="{'pricelist': self}" filter_domain="[]" groups="product.group_sale_pricelist"/> <!-- Keep widget=selection on this field to pass numeric `self` value, which is not the case for regular m2o widgets! -->
|
||||
<group expand='0' string='Group by...'>
|
||||
<group expand='0' name="group_by" string='Group by...'>
|
||||
<filter string='Category' domain="[]" context="{'group_by' : 'categ_id'}"/>
|
||||
<filter string='Default Unit of Measure' icon="terp-mrp" domain="[]" context="{'group_by' : 'uom_id'}"/>
|
||||
<filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}"/>
|
||||
@@ -53,18 +53,15 @@
|
||||
<field name='product_variant_count' invisible='1'/>
|
||||
<sheet>
|
||||
<field name="id" invisible="True"/>
|
||||
<div class="oe_right oe_button_box" style="width: 300px;" name="buttons">
|
||||
</div>
|
||||
<div class="oe_left" style="width: 500px;">
|
||||
<field name="image_medium" widget="image" class="oe_avatar oe_left"/>
|
||||
<div class="oe_title" style="width: 390px;">
|
||||
<label class="oe_edit_only" for="name" string="Product Name"/>
|
||||
<h1><field name="name" class="oe_inline"/></h1>
|
||||
<div name="options" groups="base.group_user">
|
||||
<div>
|
||||
<field name="sale_ok"/>
|
||||
<label for="sale_ok"/>
|
||||
</div>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<field name="image_medium" widget="image" class="oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label class="oe_edit_only" for="name" string="Product Name"/>
|
||||
<h1><field name="name"/></h1>
|
||||
<div name="options" groups="base.group_user">
|
||||
<div>
|
||||
<field name="sale_ok"/>
|
||||
<label for="sale_ok"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -161,7 +158,7 @@
|
||||
<field name="name" position="after">
|
||||
<field name="product_tmpl_id" string="Product Template"/>
|
||||
</field>
|
||||
<xpath expr="//group[@string='Group by...']" position="inside">
|
||||
<xpath expr="//group[@name='group_by']" position="inside">
|
||||
<filter string='Product Template' name="template_id" domain="[]" context="{'group_by' : 'product_tmpl_id'}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
@@ -255,14 +252,14 @@
|
||||
<field name="barcode" attrs="{'invisible': [('product_variant_count', '>', 1)]}"/>
|
||||
<field name="default_code" attrs="{'invisible': [('product_variant_count', '>', 1)]}"/>
|
||||
</field>
|
||||
<xpath expr="//page[@string='Sales']" position="after">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" string="Variant Prices" name="%(variants_template_action)d" type="action" icon="fa-strikethrough"/>
|
||||
<button class="oe_stat_button" name="%(product.product_variant_action)d" type="action" icon="fa-sitemap">
|
||||
<field string="List of Variants" name="product_variant_count" widget="statinfo" />
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr="//page[@name='sales']" position="after">
|
||||
<page name="variants" string="Variants">
|
||||
<div class="oe_right">
|
||||
<button class="oe_inline oe_stat_button" string="Variant Prices" name="%(variants_template_action)d" type="action" icon="fa-strikethrough"/>
|
||||
<button class="oe_inline oe_stat_button" name="%(product.product_variant_action)d" type="action" icon="fa-sitemap">
|
||||
<field string="List of Variants" name="product_variant_count" widget="statinfo" />
|
||||
</button>
|
||||
</div>
|
||||
<p class="oe_grey">
|
||||
<strong>Warning</strong>: adding or deleting attributes
|
||||
will delete and recreate existing variants and lead
|
||||
@@ -291,8 +288,8 @@
|
||||
<field name="product_variant_ids"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_vignette oe_semantic_html_override">
|
||||
<a type="open"><img t-att-src="kanban_image('product.template', 'image_small', record.id.value)" class="oe_kanban_image"/></a>
|
||||
<div class="o_kanban_two_column">
|
||||
<a type="open"><img t-att-src="kanban_image('product.template', 'image_small', record.id.value)" class="o_kanban_image"/></a>
|
||||
<div class="oe_kanban_details">
|
||||
<h4>
|
||||
<a type="open">
|
||||
@@ -867,4 +864,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -556,6 +556,12 @@ class task(osv.osv):
|
||||
res[task.id] = False
|
||||
return res
|
||||
|
||||
def _compute_displayed_image(self, cr, uid, ids, prop, arg, context=None):
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
res[line.id] = line.attachment_ids and line.attachment_ids.filtered(lambda x: x.file_type_icon == 'webimage')[0] or None
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'active': fields.function(_is_template, store=True, string='Not a Template Task', type='boolean', help="This field is computed automatically and have the same behavior than the boolean 'active' field: if the task is linked to a template or unactivated project, it will be hidden unless specifically asked."),
|
||||
'name': fields.char('Task Summary', track_visibility='onchange', size=128, required=True, select=True),
|
||||
@@ -592,7 +598,9 @@ class task(osv.osv):
|
||||
'id': fields.integer('ID', readonly=True),
|
||||
'color': fields.integer('Color Index'),
|
||||
'user_email': fields.related('user_id', 'email', type='char', string='User Email', readonly=True),
|
||||
}
|
||||
'attachment_ids': fields.one2many('ir.attachment', 'res_id', domain=lambda self: [('res_model', '=', self._name)], auto_join=True, string='Attachments'),
|
||||
'displayed_image_id': fields.function(_compute_displayed_image, relation='ir.attachment', type="many2one", string='Attachment'),
|
||||
}
|
||||
_defaults = {
|
||||
'stage_id': _get_default_stage_id,
|
||||
'project_id': lambda self, cr, uid, ctx=None: ctx.get('default_project_id') if ctx is not None else False,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<span><t t-esc="record.name.value"/></span>
|
||||
</div>
|
||||
<div t-if="record.alias_id.raw_value">
|
||||
<span><i class="fa fa-envelope-o"></i> <t t-esc="record.alias_id.value"/></span>
|
||||
<span><i class="fa fa-envelope"></i> <t t-esc="record.alias_id.value"/></span>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="o_kanban_card_manage_pane o_invisible">
|
||||
@@ -41,16 +41,14 @@
|
||||
<div>
|
||||
<a name="%(action_view_task_history_cumulative_filter)d" type="action">Cumulative Flow</a>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="widget.view.is_action_enabled('edit')" class="o_project_kanban_colorpicker">
|
||||
<div class="col-xs-12">
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
<div t-if="widget.editable" class="o_project_kanban_colorpicker">
|
||||
<ul class="oe_kanban_colorpicker" data-field="color"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_project_kanban_manage">
|
||||
<div class="text-left">
|
||||
<a class="o_kanban_manage_toggle_button">More <i class="fa fa-caret-down"/></a>
|
||||
<a class="o_kanban_manage_toggle_button" href="#">More <i class="fa fa-caret-down"/></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
id="base.menu_main_pm"
|
||||
groups="group_project_manager,group_project_user"
|
||||
icon="fa-calendar"
|
||||
web_icon="project,static/description/icon.png"
|
||||
sequence="50"/>
|
||||
|
||||
<menuitem name="Search"
|
||||
@@ -88,6 +89,15 @@
|
||||
</header>
|
||||
<sheet string="Project">
|
||||
<field name="analytic_account_id" invisible="1" required="0"/>
|
||||
<div class="oe_button_box" name="button_box" groups="base.group_user">
|
||||
<button class="oe_stat_button" type="action" attrs="{'invisible':[('use_tasks','=', False)]}"
|
||||
name="%(act_project_project_2_project_task_all)d" icon="fa-tasks">
|
||||
<field string="Tasks" name="task_count" widget="statinfo" options="{'label_field': 'label_tasks'}"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="attachment_tree_view" type="object" icon="fa-files-o">
|
||||
<field string="Documents" name="doc_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only" string="Project Name"/>
|
||||
<h1>
|
||||
@@ -102,15 +112,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="buttons" groups="base.group_user">
|
||||
<button class="oe_inline oe_stat_button" type="action" attrs="{'invisible':[('use_tasks','=', False)]}"
|
||||
name="%(act_project_project_2_project_task_all)d" icon="fa-tasks">
|
||||
<field string="Tasks" name="task_count" widget="statinfo" options="{'label_field': 'label_tasks'}"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" name="attachment_tree_view" type="object" icon="fa-files-o">
|
||||
<field string="Documents" name="doc_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<notebook>
|
||||
<page string="Emails" attrs="{'invisible': [('alias_domain', '=', False)]}">
|
||||
<group name="group_alias">
|
||||
@@ -254,7 +255,6 @@
|
||||
</record>
|
||||
|
||||
<!-- Task -->
|
||||
|
||||
<record id="view_task_form2" model="ir.ui.view">
|
||||
<field name="name">project.task.form</field>
|
||||
<field name="model">project.task</field>
|
||||
@@ -266,17 +266,15 @@
|
||||
options="{'fold_field': 'fold'}"/>
|
||||
</header>
|
||||
<sheet string="Task">
|
||||
<div class="row">
|
||||
<h1 class="col-xs-11">
|
||||
<field class="oe_inline oe_left" name="priority" widget="priority"/>
|
||||
<field name="name" placeholder="Task summary..." class="oe_inline"/>
|
||||
</h1>
|
||||
<div class="col-xs-1 text-right">
|
||||
<field name="kanban_state" class="oe_inline" widget="kanban_state_selection"
|
||||
<div class="oe_title">
|
||||
<h1 class="o_row">
|
||||
<field name="priority" widget="priority"/>
|
||||
<field name="name" placeholder="Task summary..."/>
|
||||
<field name="kanban_state" widget="kanban_state_selection"
|
||||
options='{
|
||||
"states_legend_field": "stage_id",
|
||||
"states_legend": {"normal": "legend_normal", "blocked": "legend_blocked", "done": "legend_done"}}'/>
|
||||
</div>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
@@ -357,29 +355,35 @@
|
||||
<field name="date_deadline"/>
|
||||
<field name="message_summary"/>
|
||||
<field name="tag_ids"/>
|
||||
<field name="displayed_image_id"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_user">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('edit')"><li><a type="edit">Edit Task</a></li></t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')"><li><a type="delete">Delete</a></li></t>
|
||||
|
||||
<div class="o_dropdown_kanban dropdown" groups="base.group_user">
|
||||
<a class="dropdown-toggle btn" data-toggle="dropdown" href="#" >
|
||||
<span class="fa fa-bars fa-lg"/>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
|
||||
<t t-if="widget.editable"><li><a type="edit">Edit Task</a></li></t>
|
||||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="oe_kanban_content">
|
||||
<div><b><field name="name"/></b></div>
|
||||
<div>
|
||||
<field name="tag_ids"/>
|
||||
</div>
|
||||
<div>
|
||||
<strong><field name="name"/></strong>
|
||||
</div>
|
||||
<div class="text-muted">
|
||||
<field name="project_id" invisible="context.get('default_project_id', False)"/><br/>
|
||||
<t t-if="record.date_deadline.raw_value and record.date_deadline.raw_value lt (new Date())" t-set="red">oe_kanban_text_red</t>
|
||||
<span t-attf-class="#{red || ''}"><i><field name="date_deadline"/></i></span>
|
||||
</div>
|
||||
<div class="oe_kanban_footer_left" style="margin-top:5px;">
|
||||
<field name="tag_ids"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<field name="priority" widget="priority"/>
|
||||
<t t-raw="record.message_summary.raw_value"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
@@ -387,10 +391,12 @@
|
||||
<div class="pull-left" groups="base.group_user">
|
||||
<field name="kanban_state" widget="kanban_state_selection"
|
||||
options='{"states_legend": {"normal": "legend_normal", "blocked": "legend_blocked", "done": "legend_done"}}'/>
|
||||
<field name="priority" widget="priority"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="record.displayed_image_id.value">
|
||||
<field name="displayed_image_id" widget="attachment_image"/>
|
||||
</div>
|
||||
<div class="oe_clear"></div>
|
||||
</div>
|
||||
</t>
|
||||
@@ -571,7 +577,7 @@
|
||||
<p class="text-muted" colspan="2">
|
||||
You can also give a tooltip about the use of the stars available in the kanban and form views.
|
||||
</p>
|
||||
<label for="legend_priority" string=" " class="fa fa-star fa-lg oe_star_on oe_project_kanban_legend"/>
|
||||
<label for="legend_priority" string=" " class="fa fa-star fa-lg o_star_on oe_project_kanban_legend"/>
|
||||
<field name="legend_priority" nolabel="1"/>
|
||||
|
||||
<p class="text-muted" colspan="2">
|
||||
@@ -685,4 +691,4 @@
|
||||
<menuitem action="project_tags_action" id="menu_project_tags_act" parent="base.menu_definitions" groups="base.group_no_one"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -10,17 +10,15 @@
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="groups_id" eval="[(4, ref('project.group_project_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action" name="%(action_view_task)d"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(action_view_task)d"
|
||||
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}"
|
||||
icon="fa-tasks">
|
||||
<field string="Tasks" name="task_count" widget="statinfo"/>
|
||||
</button>
|
||||
|
||||
|
||||
</xpath>
|
||||
</button>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -1,14 +1,14 @@
|
||||
odoo.define('project.update_kanban', function (require) {
|
||||
|
||||
var kanban_common = require('web_kanban.common');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
var KanbanView = require('web_kanban.KanbanView');
|
||||
var data = require('web.data');
|
||||
var session = require('web.session');
|
||||
|
||||
|
||||
kanban_common.KanbanRecord.include({
|
||||
KanbanRecord.include({
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'project.project') {
|
||||
if (this.model === 'project.project') {
|
||||
this.$('.o_project_kanban_boxes a').first().click();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
@@ -1,45 +1,37 @@
|
||||
.oe_kanban_view.o_kanban_dashboard.o_project_kanban {
|
||||
|
||||
@odoo-brand-optional: #21b799;
|
||||
.o_kanban_view.o_kanban_dashboard.o_project_kanban {
|
||||
|
||||
.o_kanban_flexbox {
|
||||
display: flex;
|
||||
.o-flex-display();
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.oe_kanban_record {
|
||||
.o_kanban_record {
|
||||
min-width: 300px;
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
/*
|
||||
.oe_kanban_record:hover .o_project_kanban_manage {
|
||||
visibility: visible;
|
||||
}
|
||||
*/
|
||||
|
||||
.o_project_kanban_main {
|
||||
margin-bottom: 40px; // give space for manage section at the bottom
|
||||
width: 75%;
|
||||
// give space for manage section at the bottom
|
||||
margin-bottom: 40px;
|
||||
width: 70%;
|
||||
|
||||
.o_primary {
|
||||
font-size: larger;
|
||||
.o_kanban_card_content {
|
||||
font-size: 12px;
|
||||
.o_primary {
|
||||
font-size: larger;
|
||||
}
|
||||
}
|
||||
|
||||
.o_project_kanban_manage {
|
||||
visibility: visible;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
margin-left: 10px;
|
||||
margin-left: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.o_project_kanban_colorpicker {
|
||||
padding: 8px;
|
||||
}
|
||||
.o_kanban_card_manage_pane {
|
||||
border-color: lightgrey;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
|
||||
.o_kanban_card_manage_title {
|
||||
margin: 0;
|
||||
@@ -48,12 +40,16 @@
|
||||
}
|
||||
|
||||
.o_project_kanban_boxes {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-content: stretch;
|
||||
.o-flex-display();
|
||||
.o-flex-flow(column, nowrap);
|
||||
.o-justify-content(flex-end);
|
||||
.o-align-content(stretch);
|
||||
|
||||
width: 25%;
|
||||
width: 30%;
|
||||
|
||||
> a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.o_value {
|
||||
font-size: x-large;
|
||||
@@ -67,11 +63,11 @@
|
||||
.o_project_kanban_box {
|
||||
text-align: center;
|
||||
padding: 15px 0 15px 0;
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.o-flex(1, 1, auto);
|
||||
.o-flex-display();
|
||||
.o-align-items(center);
|
||||
.o-flex-flow(column, nowrap);
|
||||
.o-justify-content(center);
|
||||
}
|
||||
.o_project_kanban_box:nth-child(even) {
|
||||
background-color: grey;
|
||||
@@ -80,4 +76,4 @@
|
||||
background-color: @odoo-brand-optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@
|
||||
<div name="project">
|
||||
<field name="project_id" on_change="on_change_project(project_id)" class="oe_inline" context="{'default_use_issues':1}"/>
|
||||
<field name="can_escalate" invisible="1"/>
|
||||
<button name="case_escalate" string="Escalate" type="object" class="oe_link" attrs="{'invisible':[('can_escalate','=',False)]}" groups="base.group_user"/>
|
||||
<button name="case_escalate" string="Escalate" type="object" class="btn-default" attrs="{'invisible':[('can_escalate','=',False)]}" groups="base.group_user"/>
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
@@ -168,8 +168,8 @@
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban" groups="base.group_user">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<t t-if="widget.view.is_action_enabled('edit')"><li><a type="edit">Edit Issue</a></li></t>
|
||||
<t t-if="widget.view.is_action_enabled('delete')"><li><a type="delete">Delete</a></li></t>
|
||||
<t t-if="widget.editable"><li><a type="edit">Edit Issue</a></li></t>
|
||||
<t t-if="widget.deletable"><li><a type="delete">Delete</a></li></t>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -278,12 +278,12 @@
|
||||
<field name="label_issues" class="oe_inline oe_input_align" attrs="{'invisible': [('use_issues', '=', False)]}"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr='//div[@name="buttons"]' position='inside'>
|
||||
<button class="oe_inline oe_stat_button" type="action" attrs="{'invisible':[('use_issues','=', False)]}"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" attrs="{'invisible':[('use_issues','=', False)]}"
|
||||
name="%(act_project_project_2_project_issue_all)d" icon="fa-bug">
|
||||
<field string="Issues" name="issue_count" widget="statinfo" options="{'label_field': 'label_issues'}"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
<xpath expr='//page[@name="project_stages"]' position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('use_tasks', '=', False),('use_issues','=',False)]}</attribute>
|
||||
</xpath>
|
||||
@@ -331,18 +331,16 @@
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="groups_id" eval="[(4, ref('project.group_project_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action" name="%(action_view_issues)d"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(action_view_issues)d"
|
||||
context="{'search_default_partner_id': active_id, 'default_partner_id': active_id}"
|
||||
attrs="{'invisible': [('customer', '=', False)]}"
|
||||
icon="fa-bug">
|
||||
<field string="Issues" name="issue_count" widget="statinfo"/>
|
||||
</button>
|
||||
|
||||
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -40,10 +40,10 @@
|
||||
<field name="effective_hours" widget="float_time"
|
||||
groups="project.group_time_work_estimation_tasks"/>
|
||||
</field>
|
||||
<xpath expr='//div[@name="buttons"]' position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="open_timesheets" type="object" attrs="{'invisible':[('invoice_on_timesheets','=',False)]}"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="open_timesheets" type="object" attrs="{'invisible':[('invoice_on_timesheets','=',False)]}"
|
||||
icon="fa-calendar" string="Timesheets"/>
|
||||
</xpath>
|
||||
</div>
|
||||
<xpath expr='//field[@name="partner_id"]' position='after'>
|
||||
<field name="pricelist_id" invisible="1"/>
|
||||
</xpath>
|
||||
|
||||
@@ -77,12 +77,12 @@
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="groups_id" eval="[(4, ref('purchase.group_purchase_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="%(purchase.act_res_partner_2_purchase_order)d" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="%(purchase.act_res_partner_2_purchase_order)d" type="action"
|
||||
attrs="{'invisible': [('supplier', '=', False)]}" icon="fa-shopping-cart">
|
||||
<field string="Purchases" name="purchase_order_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -93,12 +93,12 @@
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="%(purchase.act_res_partner_2_supplier_invoices)d" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="%(purchase.act_res_partner_2_supplier_invoices)d" type="action"
|
||||
attrs="{'invisible': [('supplier', '=', False)]}" icon="fa-pencil-square-o" help="Supplier Bills">
|
||||
<field string="Supplier Inv." name="supplier_invoice_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
@@ -694,12 +694,12 @@
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('purchase.group_purchase_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="action_view_purchases" type="object"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="action_view_purchases" type="object"
|
||||
icon="fa-shopping-cart">
|
||||
<field string="Purchases" name="purchase_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -709,12 +709,12 @@
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('purchase.group_purchase_user'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="action_view_purchases" type="object"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="action_view_purchases" type="object"
|
||||
icon="fa-shopping-cart">
|
||||
<field string="Purchases" name="purchase_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<field name="inherit_id" ref="purchase.purchase_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[contains(@class, 'oe_title')]" position="before">
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button type="object"
|
||||
name="view_picking"
|
||||
class="oe_stat_button"
|
||||
|
||||
@@ -39,11 +39,14 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,in_progress,open,done" statusbar_colors='{"in_progress":"blue"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="open_product_line" type="object" string="Product Lines" class="oe_stat_button" icon="fa-list"
|
||||
attrs="{'invisible': ['|', ('state', 'not in', ('open','done')), ('exclusive', '=', 'exclusive')]}" groups="purchase.group_advance_bidding"/>
|
||||
<button name="open_rfq" type="object" string="RFQs/Bids" class="oe_stat_button" icon="fa-list-alt"
|
||||
attrs="{'invisible': [('state', '=', 'draft')]}"/>
|
||||
<button name="%(action_purchase_requisition_partner)d" type="action"
|
||||
string="Request a Quotation" icon="gtk-execute"
|
||||
attrs="{'invisible': ['|', ('line_ids','=',[]),('state', 'in', ('draft' ,'open','done'))]}"/>
|
||||
</div>
|
||||
<div class="pull-left">
|
||||
<label for="name" class="oe_edit_only oe_inline"/>
|
||||
@@ -89,11 +92,6 @@
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
<div class="oe_right oe_button_box" style="margin-top: 10px">
|
||||
<button name="%(action_purchase_requisition_partner)d" type="action"
|
||||
string="Request a Quotation" icon="gtk-execute"
|
||||
attrs="{'invisible': ['|', ('line_ids','=',[]),('state', 'in', ('draft' ,'open','done'))]}"/>
|
||||
</div>
|
||||
<separator string="Requests for Quotation"/>
|
||||
<field name="purchase_ids" options="{'reload_on_button': true}">
|
||||
<tree string="Purchase Order">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
odoo.define('rating.kanban', function(require) {
|
||||
"use strict";
|
||||
|
||||
var common = require('web_kanban.common');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
|
||||
common.KanbanRecord.include({
|
||||
KanbanRecord.include({
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'rating.rating') {
|
||||
if (this.model === 'rating.rating') {
|
||||
this.$('a').first().click();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="action_view_task_rating"
|
||||
attrs="{'invisible': ['|', '|', ('is_visible_happy_customer', '=', False), ('use_tasks','=', False), ('percentage_satisfaction_task', '=', -1)]}"
|
||||
class="oe_stat_button oe_percent"
|
||||
@@ -16,7 +16,7 @@
|
||||
icon="fa-smile-o">
|
||||
<field string="On tasks" name="percentage_satisfaction_task" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
<xpath expr="//field[@name='privacy_visibility']" position="after">
|
||||
<field name="is_visible_happy_customer"/>
|
||||
</xpath>
|
||||
@@ -38,4 +38,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
@@ -8,7 +8,7 @@
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="action_view_issue_rating"
|
||||
attrs="{'invisible': ['|', '|', ('use_issues','=', False), ('is_visible_happy_customer','=', False), ('percentage_satisfaction_issue', '=', -1)]}"
|
||||
class="oe_stat_button oe_percent"
|
||||
@@ -16,7 +16,7 @@
|
||||
icon="fa-smile-o">
|
||||
<field string="On issues" name="percentage_satisfaction_issue" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
<field name="sale_order_count"/>
|
||||
</field>
|
||||
<xpath expr="//div[@class='oe_kanban_partner_links']" position="inside">
|
||||
<a name="%(sale.act_res_partner_2_sale_order)d" type="action" t-if="record.sale_order_count.value>0">
|
||||
<t t-esc="record.sale_order_count.value"/> Sales
|
||||
</a>
|
||||
<span t-if="record.sale_order_count.value>0" class="badge"><i class="fa fa-fw fa-strikethrough"/><t t-esc="record.sale_order_count.value"/></span>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -48,16 +46,15 @@
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_sale_salesman'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action" name="%(sale.act_res_partner_2_sale_order)d"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action" name="%(sale.act_res_partner_2_sale_order)d"
|
||||
attrs="{'invisible': [('customer', '=', False)]}"
|
||||
icon="fa-strikethrough">
|
||||
<field string="Sales" name="sale_order_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
+14
-14
@@ -143,14 +143,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,sent,progress,done" statusbar_colors='{"invoice_except":"red","waiting_date":"blue"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<label string="Quotation " attrs="{'invisible': [('state', 'not in', ('draft', 'sent'))]}"/>
|
||||
<label string="Sales Order " attrs="{'invisible': [('state', 'in', ('draft', 'sent'))]}"/>
|
||||
<field name="name" class="oe_inline" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_view_invoice"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
@@ -159,6 +152,13 @@
|
||||
<field name="invoice_count" widget="statinfo" string="Invoices"/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<label string="Quotation " attrs="{'invisible': [('state', 'not in', ('draft', 'sent'))]}"/>
|
||||
<label string="Sales Order " attrs="{'invisible': [('state', 'in', ('draft', 'sent'))]}"/>
|
||||
<field name="name" class="oe_inline" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id, context)" domain="[('customer','=',True)]" context="{'search_default_customer':1, 'show_address': 1}" options='{"always_reload": True}'/>
|
||||
@@ -591,12 +591,12 @@
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_sale_salesman'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="action_view_sales"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="action_view_sales"
|
||||
type="object" icon="fa-strikethrough">
|
||||
<field string="Sales" name="sales_count" widget="statinfo" />
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -606,12 +606,12 @@
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="groups_id" eval="[(4, ref('base.group_sale_salesman'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" name="action_view_sales"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="action_view_sales"
|
||||
type="object" icon="fa-strikethrough">
|
||||
<field string="Sales" name="sales_count" widget="statinfo" />
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -29,21 +29,21 @@
|
||||
<button attrs="{'invisible': [('probability', '>', 0)]}" string="New Quotation" name="%(sale_action_quotations_new)d" type="action"
|
||||
context="{'search_default_partner_id': partner_id, 'default_partner_id': partner_id}"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<button class="oe_inline oe_stat_button" type="action"
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" type="action"
|
||||
name="%(sale_action_quotations)d" icon="stat_button_icon fa fa-usd"
|
||||
context="{'search_default_partner_id': partner_id, 'default_partner_id': partner_id}">
|
||||
<field name="sale_number" widget="statinfo" string="Quotes"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" type="action" attrs="{'invisible': [('sale_amount_total', '=', 0)]}"
|
||||
<button class="oe_stat_button" type="action" attrs="{'invisible': [('sale_amount_total', '=', 0)]}"
|
||||
name="%(sale_action_quotations)d" icon="stat_button_icon fa fa-usd"
|
||||
context="{'search_default_partner_id': partner_id, 'default_partner_id': partner_id}">
|
||||
<div>
|
||||
<strong><field name="sale_amount_total" class="oe_inline" widget="monetary" options="{'currency_field': 'company_currency'}"/></strong>
|
||||
<div><field name="sale_number" class="oe_inline"/> Orders</div>
|
||||
<div class="o_form_field o_stat_info">
|
||||
<span class="o_stat_value"><field name="sale_amount_total" widget="monetary" options="{'currency_field': 'company_currency'}"/></span>
|
||||
<span class="o_stat_text"> Orders</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
</div>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-if="widget.view.is_action_enabled('edit')" class="o_kanban_card_manage_settings row">
|
||||
<div t-if="widget.editable" class="o_kanban_card_manage_settings row">
|
||||
<div class="col-xs-8">
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ odoo.define('sales_team.update_kanban', function (require) {
|
||||
"use strict";
|
||||
|
||||
var KanbanView = require('web_kanban.KanbanView');
|
||||
var kanban_common = require('web_kanban.common');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
var data = require('web.data');
|
||||
var session = require('web.session');
|
||||
|
||||
@@ -40,9 +40,9 @@ KanbanView.include({
|
||||
},
|
||||
});
|
||||
|
||||
kanban_common.KanbanRecord.include({
|
||||
KanbanRecord.include({
|
||||
on_card_clicked: function() {
|
||||
if (this.view.dataset.model === 'crm.team') {
|
||||
if (this.model === 'crm.team') {
|
||||
this.$('.oe_kanban_crm_salesteams_list a').first().click();
|
||||
} else {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
@@ -222,18 +222,18 @@
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button"
|
||||
name="%(product_open_quants)d"
|
||||
icon="fa-building-o"
|
||||
type="action" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_locations">
|
||||
<field name="qty_available2" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" string="Moves" name= "%(act_product_stock_move_open)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_inline oe_stat_button" name="%(product_open_orderpoint)d" type="action"
|
||||
<button class="oe_stat_button" string="Moves" name= "%(act_product_stock_move_open)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_stat_button" name="%(product_open_orderpoint)d" type="action"
|
||||
attrs="{'invisible':[('type', '=', 'service')]}" icon="fa-refresh" string="Reordering Rules"/>
|
||||
<button class="oe_inline oe_stat_button" name="action_view_routes" string="Routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" />
|
||||
</xpath>
|
||||
<button class="oe_stat_button" name="action_view_routes" string="Routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" />
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -242,18 +242,18 @@
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='buttons']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button"
|
||||
name="action_open_quants"
|
||||
icon="fa-building-o"
|
||||
type="object" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_locations">
|
||||
<field name="qty_available2" widget="statinfo"/>
|
||||
</button>
|
||||
<button class="oe_inline oe_stat_button" string="Moves" name= "action_view_stock_moves" type="object" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_inline oe_stat_button" name="action_view_orderpoints" type="object"
|
||||
<button class="oe_stat_button" string="Moves" name= "action_view_stock_moves" type="object" attrs="{'invisible':[('type', '=', 'service')]}" groups="stock.group_stock_user" icon="fa-arrows-v"/>
|
||||
<button class="oe_stat_button" name="action_view_orderpoints" type="object"
|
||||
attrs="{'invisible':[('type', 'in', ('service','consu'))]}" icon="fa-refresh" string="Reordering Rules"/>
|
||||
<button class="oe_inline oe_stat_button" name="action_view_routes" string="Routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" />
|
||||
</xpath>
|
||||
<button class="oe_stat_button" name="action_view_routes" string="Routes" type="object" icon="fa-cogs" attrs="{'invisible':[('type', '=', 'service')]}" />
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-if="widget.view.is_action_enabled('edit')" class="o_kanban_card_manage_settings row">
|
||||
<div t-if="widget.editable" class="o_kanban_card_manage_settings row">
|
||||
<div class="col-xs-8">
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</div>
|
||||
|
||||
+15
-17
@@ -195,7 +195,7 @@
|
||||
<field name="model">stock.production.lot</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Serial Number">
|
||||
<div class="oe_button_box oe_right">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_traceability" icon="fa-arrow-up" class="oe_stat_button" string="Traceability" type="object" attrs="{'invisible': [('quant_ids','=',[])]}"/>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
@@ -316,7 +316,7 @@
|
||||
<field name="model">stock.location</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Stock Location">
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button string="Current Stock"
|
||||
class="oe_stat_button"
|
||||
icon="fa-building-o" name="%(location_open_quants)d" type="action"
|
||||
@@ -532,7 +532,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Warehouse">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="view_all_routes_for_wh"
|
||||
string="Routes"
|
||||
icon="fa-refresh"
|
||||
@@ -703,7 +703,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,partially_available,assigned,done" statusbar_colors='{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
</div>
|
||||
<h1>
|
||||
<field name="name" class="oe_inline" attrs="{'invisible': [('name','=','/')]}" readonly="1"/>
|
||||
@@ -1564,7 +1564,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Reordering Rules">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_view_proc_to_process" type="object" string="Procurement Orders to Process"/>
|
||||
</div>
|
||||
<group>
|
||||
@@ -1631,9 +1631,9 @@
|
||||
<field name="route_ids" widget="many2many_tags"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="do_view_pickings" class="oe_stat_button" icon="fa-bars" string="Group's Pickings" type="object"/>
|
||||
</xpath>
|
||||
</div>
|
||||
<xpath expr="//field[@name='rule_id']" position="replace">
|
||||
<field name="rule_id" domain="['|', ('location_id', '=', False), ('location_id', '=', location_id)]"/>
|
||||
<field name="partner_dest_id"/>
|
||||
@@ -1759,8 +1759,8 @@
|
||||
<field eval="10" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Quants" create="false" edit="false">
|
||||
<div class="oe_right oe_button_box">
|
||||
<button name="action_view_quant_history" type="object" string="Quant History"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_view_quant_history" type="object" string="Quant History"/>
|
||||
</div>
|
||||
<group>
|
||||
<field name="product_id"/>
|
||||
@@ -1861,11 +1861,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Package">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button class="oe_inline" name="unpack" string="Unpack" type="object"/>
|
||||
<button class="oe_inline oe_stat_button" name="%(action_picking_tree_all)d"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="unpack" string="Unpack" type="object"/>
|
||||
<button class="oe_stat_button" name="%(action_picking_tree_all)d"
|
||||
string="Package Transfers" type="action"
|
||||
widget="statinfo" icon="fa-dropbox"/>
|
||||
<button name="get_content_package" type="object" string="View Contained Packages content" icon="gtk-execute" attrs="{'invisible': [('children_ids','=',[])]}"/>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" string="Package Reference" class="oe_edit_only"/>
|
||||
@@ -1895,9 +1896,6 @@
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
<div class="oe_right oe_button_box" style="margin-top: 10px">
|
||||
<button name="get_content_package" type="object" string="View Contained Packages content" icon="gtk-execute" attrs="{'invisible': [('children_ids','=',[])]}"/>
|
||||
</div>
|
||||
<separator string="Contained Packages"/>
|
||||
<field name="children_ids">
|
||||
<tree string="Contained Packages">
|
||||
@@ -2050,9 +2048,9 @@
|
||||
<field name="model">procurement.group</field>
|
||||
<field name="inherit_id" ref="procurement.procurement_group_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(do_view_pickings)d" string="Pickings" type="action"/>
|
||||
</xpath>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<field name="state" widget="statusbar" statusbar_visible="in_progress,done"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="print_picking" string="Print all pickings" type="object"/>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box" name="button_box">
|
||||
</div>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="survey_id"/>
|
||||
@@ -184,11 +183,11 @@
|
||||
<field name="public_url" />
|
||||
<templates>
|
||||
<div t-name="kanban-box" t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click">
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban" t-if="widget.view.is_action_enabled('edit')">
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban" t-if="widget.editable">
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu">
|
||||
<li><a type="edit">Edit Survey</a></li>
|
||||
<li t-if="widget.view.is_action_enabled('delete')"><a type="delete">Delete</a></li>
|
||||
<li t-if="widget.deletable"><a type="delete">Delete</a></li>
|
||||
<li><ul class="oe_kanban_colorpicker" data-field="color"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -186,6 +186,11 @@ return {
|
||||
list_widget_registry: new Registry(),
|
||||
search_widgets_registry: new Registry(),
|
||||
search_filters_registry: new Registry(),
|
||||
|
||||
// necessary to make the kanban view compatible between
|
||||
// community and enterprise edition
|
||||
one2many_view_registry: new Registry(),
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ var Priority = FieldChar.extend({
|
||||
},
|
||||
render_value: function() {
|
||||
this.priorities = this.prepare_priority();
|
||||
this.$el.html(QWeb.render("Priority", {'widget': this}));
|
||||
this.$el.html(QWeb.render("FormPriority", {'widget': this}));
|
||||
if (!this.get('readonly')){
|
||||
this.$el.find('li').on('click', this.set_priority.bind(this));
|
||||
}
|
||||
@@ -1584,6 +1584,7 @@ var StatInfo = common.AbstractField.extend({
|
||||
}
|
||||
}
|
||||
this.$el.html(QWeb.render("StatInfo", options));
|
||||
this.$el.addClass('o_stat_info');
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
odoo.define('web.Pager', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var direction = {
|
||||
previous: -1,
|
||||
next: 1,
|
||||
};
|
||||
|
||||
var Pager = Widget.extend({
|
||||
template: "Pager",
|
||||
|
||||
events: {
|
||||
'click .o-pager-previous': 'previous',
|
||||
'click .o-pager-next': 'next',
|
||||
},
|
||||
|
||||
// pager goes from 1 to size (included).
|
||||
// current value is current_min (if limit === 1)
|
||||
// or the interval [current_min, current_min + limit[ if limit > 1
|
||||
init: function (parent, size, current_min, limit, options) {
|
||||
this.state = {
|
||||
size: size,
|
||||
current_min: current_min,
|
||||
limit: limit,
|
||||
};
|
||||
Object.defineProperty(this.state, 'current_max', {
|
||||
get: function() {
|
||||
return Math.min(this.current_min + this.limit - 1, this.size);
|
||||
}
|
||||
});
|
||||
this.options = options || {};
|
||||
this._super(parent);
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this.$content = this.$('.o-pager-value');
|
||||
this._render();
|
||||
return this._super();
|
||||
},
|
||||
|
||||
set_state: function (options) {
|
||||
_.extend(this.state, options);
|
||||
this._render();
|
||||
},
|
||||
|
||||
previous: function(e) {
|
||||
this._change_selection(direction.previous);
|
||||
},
|
||||
|
||||
next: function() {
|
||||
this._change_selection(direction.next);
|
||||
},
|
||||
|
||||
disable: function() {
|
||||
this.$('button').prop("disabled", true);
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
this.$('button').prop("disabled", false);
|
||||
},
|
||||
|
||||
_render: function () {
|
||||
var state;
|
||||
var size = this.state.size;
|
||||
var current_min = this.state.current_min;
|
||||
var current_max = this.state.current_max;
|
||||
var single_page = 1 === current_min && current_max === size;
|
||||
|
||||
if (size === 0 || (single_page && this.options.single_page_hidden)) {
|
||||
this.$el.hide();
|
||||
} else {
|
||||
this.$el.show();
|
||||
|
||||
if (single_page) {
|
||||
this.disable();
|
||||
} else {
|
||||
this.enable();
|
||||
}
|
||||
|
||||
if (this.state.limit === 1) {
|
||||
state = "" + current_min + " / " + size;
|
||||
} else {
|
||||
state = "" + current_min + "-" + current_max + " / " + size;
|
||||
}
|
||||
this.$content.html(state);
|
||||
}
|
||||
},
|
||||
|
||||
_change_selection: function (direction) {
|
||||
var size = this.state.size;
|
||||
var current_min = this.state.current_min;
|
||||
var limit = this.state.limit;
|
||||
current_min = (current_min + limit*direction);
|
||||
if (current_min > size) {
|
||||
current_min = 1;
|
||||
} else if ((current_min < 1) && (limit === 1)) {
|
||||
current_min = size;
|
||||
} else if ((current_min < 1) && (limit > 1)) {
|
||||
current_min = size - ((size % limit) || limit) + 1;
|
||||
}
|
||||
this.state.current_min = current_min;
|
||||
this.trigger('pager_changed', _.clone(this.state));
|
||||
this._render();
|
||||
},
|
||||
});
|
||||
|
||||
return Pager;
|
||||
|
||||
});
|
||||
@@ -0,0 +1,195 @@
|
||||
// ------------------------------------------------------------------
|
||||
// Odoo
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// This file is necessary to make the community edition of the Odoo web
|
||||
// client compatible with the enterprise edition.
|
||||
|
||||
// The problem is that we have two web clients in parallel, and every
|
||||
// addons should behave properly with both.
|
||||
|
||||
@odoo-brand-optional-disabled: #6ED0BC; // Specifically used for status bar status arrows
|
||||
@odoo-brand-primary: #337ab7;
|
||||
@odoo-brand-optional: @odoo-brand-primary;
|
||||
@odoo-brand-secondary: #8f8f8f;
|
||||
@odoo-form-group-cols: 12;
|
||||
@odoo-horizontal-padding: 16px;
|
||||
@odoo-list-grey: #e2e2e0; // FIXME: listview thead background color
|
||||
@odoo-main-color-muted: #a8a8a8;
|
||||
@odoo-main-text-color: #666666;
|
||||
@odoo-webclient-background-color: @odoo-brand-secondary;
|
||||
@odoo-view-background-color: red;
|
||||
@odoo-shadow-color: #303030;
|
||||
@brand-primary: @odoo-brand-primary;
|
||||
|
||||
.oe-view-manager {
|
||||
background-color: #f0eeee !important;
|
||||
}
|
||||
|
||||
.o_kanban_view {
|
||||
background-color: #f0eeee;
|
||||
.o_kanban_header {
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.o_kanban_config i, .o_kanban_quick_add i {
|
||||
color: #555 !important;
|
||||
&:hover {
|
||||
background-color: darken(#f0eeee, 10%) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.o_column_folded {
|
||||
background-color: #f0eeee !important;
|
||||
border: none !important;
|
||||
span.o_column_title, span.o_column_unfold {
|
||||
// color: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.o_column_quick_create {
|
||||
background-color: #f0eeee !important;
|
||||
.o_kanban_add_column, .o_kanban_title {
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.oe_list {
|
||||
background-color: white !important;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
.btn-default;
|
||||
}
|
||||
|
||||
.openerp .oe_avatar {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.openerp .oe_button_box {
|
||||
float: right;
|
||||
}
|
||||
|
||||
@grid-gutter-width: 0;
|
||||
|
||||
.oe-control-panel .row {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.oe_form_field_one2many {
|
||||
.oe-view-manager {
|
||||
background-color: white;
|
||||
|
||||
.o_kanban_view {
|
||||
background-color: white;
|
||||
|
||||
.o_kanban_record {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons containing only an icon
|
||||
.o_icon_button {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
// Stars
|
||||
.o_priority {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
> a {
|
||||
display: inline-block;
|
||||
}
|
||||
.o_star_on, .o_star_off {
|
||||
color: @odoo-main-color-muted !important;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
.o_star_on {
|
||||
color: gold !important;
|
||||
}
|
||||
}
|
||||
|
||||
.o_text_overflow {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top; // To update display context changed by overflow:hidden
|
||||
}
|
||||
|
||||
.oe-o2m-control-panel {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.oe_formview {
|
||||
.oe_button_box {
|
||||
.oe_stat_button {
|
||||
|
||||
.stat_button_icon {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// padding: @odoo-statbutton-vpadding @odoo-statbutton-spacing @odoo-statbutton-vpadding 0px;
|
||||
text-align: left;
|
||||
|
||||
.o_button_icon {
|
||||
// margin-left: @odoo-statbutton-spacing; // To create the button padding left (firefox bug)
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
&:before {
|
||||
font-size: x-large;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
// .o_form_field_percent_pie {
|
||||
// margin-left: @odoo-statbutton-spacing; // To create the button padding left (firefox bug)
|
||||
// }
|
||||
|
||||
.o_stat_info { // contains the value and text
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
max-width: 70%;
|
||||
// padding-right: @odoo-statbutton-spacing;
|
||||
line-height: 1.2;
|
||||
|
||||
.o_stat_value {
|
||||
.o_text_overflow;
|
||||
font-weight: 700;
|
||||
color: @odoo-brand-primary;
|
||||
}
|
||||
.o_stat_text {
|
||||
.o_text_overflow;
|
||||
font-size: small;
|
||||
|
||||
.o_stat_value {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Some buttons only display text and directly use the WidgetButton template instead of StatInfo
|
||||
> span {
|
||||
.o_stat_info; // layout
|
||||
font-size: small;
|
||||
white-space: normal; // text on several lines if needed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
// ------------------------------------------------------------------
|
||||
// Margin
|
||||
// ------------------------------------------------------------------
|
||||
.utils-margin-loop(@index) when (@index < 256) {
|
||||
.o-mt@{index} {margin-top: @index px;}
|
||||
.o-mb@{index} {margin-bottom: @index px;}
|
||||
.o-mr@{index} {margin-right: @index px;}
|
||||
.o-ml@{index} {margin-left: @index px;}
|
||||
|
||||
.utils-margin-loop(@index * 2);
|
||||
}
|
||||
.utils-margin-loop(2);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Padding
|
||||
// ------------------------------------------------------------------
|
||||
.o-webclient-padding(@top: 0px, @right: @odoo-horizontal-padding, @bottom: 0px, @left: @odoo-horizontal-padding) {
|
||||
padding-top: @top;
|
||||
padding-right: @right;
|
||||
padding-bottom: @bottom;
|
||||
padding-left: @left;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Caret
|
||||
// ------------------------------------------------------------------
|
||||
.utils-caret-boilerplate() {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.o-caret-down(@caret-width: @caret-width-base) {
|
||||
.utils-caret-boilerplate;
|
||||
border-bottom: 0;
|
||||
border-left: @caret-width solid transparent;
|
||||
border-right: @caret-width solid transparent;
|
||||
border-top: @caret-width solid;
|
||||
-moz-transform: scale(0.9999); // Smooth the caret on firefox
|
||||
}
|
||||
.o-caret-up(@caret-width: @caret-width-base) {
|
||||
.utils-caret-boilerplate;
|
||||
border-bottom: @caret-width solid;
|
||||
border-left: @caret-width solid transparent;
|
||||
border-right: @caret-width solid transparent;
|
||||
border-top: 0;
|
||||
-moz-transform: scale(0.9999); // Smooth the caret on firefox
|
||||
}
|
||||
.o-caret-left(@caret-width: @caret-width-base) {
|
||||
.utils-caret-boilerplate;
|
||||
border-bottom: @caret-width solid transparent;
|
||||
border-left: 0;
|
||||
border-right: @caret-width solid;
|
||||
border-top: @caret-width solid transparent;
|
||||
-moz-transform: scale(0.9999); // Smooth the caret on firefox
|
||||
}
|
||||
.o-caret-right(@caret-width: @caret-width-base) {
|
||||
.utils-caret-boilerplate;
|
||||
border-bottom: @caret-width solid transparent;
|
||||
border-left: @caret-width solid;
|
||||
border-right: 0;
|
||||
border-top: @caret-width solid transparent;
|
||||
-moz-transform: scale(0.9999); // Smooth the caret on firefox
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Vendor prefixes
|
||||
// ------------------------------------------------------------------
|
||||
// Flex
|
||||
.o-flex-display() {
|
||||
display: -ms-flexbox;
|
||||
display: -moz-box;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
|
||||
display: flex;
|
||||
}
|
||||
.o-inline-flex-display() {
|
||||
display: -ms-inline-flexbox;
|
||||
display: -moz-inline-box;
|
||||
display: -webkit-inline-box;
|
||||
display: -webkit-inline-flex;
|
||||
|
||||
display: inline-flex;
|
||||
}
|
||||
.o-flex-flow(@direction, @wrap) {
|
||||
-ms-flex-flow: @direction @wrap;
|
||||
-moz-flex-flow: @direction @wrap;
|
||||
-webkit-flex-flow: @direction @wrap;
|
||||
|
||||
flex-flow: @direction @wrap;
|
||||
}
|
||||
.o-flex(@grow, @schrink, @basis) {
|
||||
-ms-flex: @grow @schrink @basis;
|
||||
-moz-flex: @grow @schrink @basis;
|
||||
-webkit-box-flex: @grow;
|
||||
-webkit-flex: @grow @schrink @basis;
|
||||
|
||||
flex: @grow @schrink @basis;
|
||||
}
|
||||
.o-justify-content(@justify) {
|
||||
-moz-justify-content: @justify;
|
||||
-webkit-justify-content: @justify;
|
||||
|
||||
justify-content: @justify;
|
||||
}
|
||||
.o-align-content(@align) {
|
||||
-webkit-align-content: @align;
|
||||
|
||||
align-content: @align;
|
||||
}
|
||||
.o-align-items(@align) {
|
||||
-webkit-align-items: @align;
|
||||
|
||||
align-items: @align;
|
||||
}
|
||||
.o-align-self(@align) {
|
||||
-webkit-align-self: @align;
|
||||
|
||||
align-self: @align;
|
||||
}
|
||||
|
||||
// Background-size
|
||||
// https://css-tricks.com/perfect-full-page-background-image/
|
||||
.o-background-size(@size) {
|
||||
-webkit-background-size: @size;
|
||||
-moz-background-size: @size;
|
||||
-o-background-size: @size;
|
||||
background-size: @size;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Dropdowns
|
||||
// ------------------------------------------------------------------
|
||||
.o-selected-li() {
|
||||
li {
|
||||
position: relative;
|
||||
> a {
|
||||
padding: 3px 25px;
|
||||
color: @odoo-main-text-color;
|
||||
&:hover {
|
||||
color: darken(@odoo-main-text-color, 10%);
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
> a {
|
||||
color: darken(@odoo-main-text-color, 10%);
|
||||
font-weight: bold;
|
||||
&:before {
|
||||
font-family: FontAwesome;
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
content: "\f00c";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Select Appearance
|
||||
// ------------------------------------------------------------------
|
||||
.o-appearance(@value) {
|
||||
-webkit-appearance: @value;
|
||||
-moz-appearance: @value;
|
||||
appearance: @value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Transform
|
||||
// ------------------------------------------------------------------
|
||||
.o-transform-origin(@x: 50%, @y: 50%, @z: 0) {
|
||||
-ms-transform-origin: @x @y @z;
|
||||
-webkit-transform-origin: @x @y @z;
|
||||
-moz-transform-origin: @x @y @z;
|
||||
transform-origin: @x @y @z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Position absolute
|
||||
// ------------------------------------------------------------------
|
||||
.o-position-absolute(@top: auto, @right: auto, @bottom: auto, @left: auto) {
|
||||
position: absolute;
|
||||
top: @top;
|
||||
left: @left;
|
||||
bottom: @bottom;
|
||||
right: @right;
|
||||
}
|
||||
@@ -1104,7 +1104,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="Priority">
|
||||
<t t-name="FormPriority">
|
||||
<ul style="list-style: none; padding-left: 2px; display: inline-block;">
|
||||
<t t-foreach="widget.priorities" t-as="rec" >
|
||||
<li t-att-data-value="rec.click_value" style="display: inline-block;">
|
||||
@@ -1116,6 +1116,14 @@
|
||||
</t>
|
||||
</ul>
|
||||
</t>
|
||||
<t t-name="Priority">
|
||||
<div class="o_priority">
|
||||
<t t-foreach="widget.priorities" t-as="rec" >
|
||||
<a t-if="!widget.get('readonly')" href="#" t-att-data-value="rec.click_value" t-att-title="rec.name" t-att-class="widget.get('value') gte rec.value and 'fa fa-star o_star_on' or 'fa fa-star o_star_off'"/>
|
||||
<span t-if="widget.get('readonly')" t-att-data-value="rec.click_value" t-att-title="rec.name" t-att-class="widget.get('value') gte rec.value and 'fa fa-star o_star_on' or 'fa fa-star o_star_off'"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="FieldEmail">
|
||||
<span class="oe_form_field oe_form_field_email" t-att-style="widget.node.attrs.style">
|
||||
<a t-if="widget.get('effective_readonly')" href="#" class="oe_form_uri" target="_blank"/>
|
||||
@@ -1938,14 +1946,25 @@
|
||||
<a href="javascript:void(0)"><t t-esc="text"/></a>
|
||||
</t>
|
||||
<t t-name="StatInfo">
|
||||
<strong><t t-esc="value"/></strong><br/><t t-esc="text"/>
|
||||
<span class="o_stat_value"><t t-esc="value"/></span>
|
||||
<span class="o_stat_text"><t t-esc="text"/></span>
|
||||
</t>
|
||||
|
||||
<button t-name="toggle_button" type="button"
|
||||
t-att-title="widget.string"
|
||||
style="box-shadow: none; white-space:nowrap;">
|
||||
<img t-attf-src="#{prefix}/web/static/src/img/icons/#{widget.icon}.png"
|
||||
t-att-alt="widget.string"/>
|
||||
</button>
|
||||
|
||||
<div t-name="Pager">
|
||||
<span class="o-pager-value"></span>
|
||||
<span class="btn-group btn-group-sm">
|
||||
<button type="button" class="fa fa-chevron-left btn btn-icon o-pager-previous" accesskey="O"/>
|
||||
<button type="button" class="fa fa-chevron-right btn btn-icon o-pager-next" accesskey="P"/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button t-name="FieldToggleBoolean" type="button"
|
||||
t-att-title="widget.string" class="oe_toggle_button">
|
||||
<img t-attf-src="#{_s}/web/static/src/img/icons/#{widget.icon}" t-att-alt="widget.string"/>
|
||||
|
||||
@@ -73,6 +73,8 @@
|
||||
<script type="text/javascript" src="/web/static/lib/select2/select2.js"></script>
|
||||
|
||||
<link rel="stylesheet" href='/website/static/src/less/import_bootstrap.less'/>
|
||||
<link rel="stylesheet" href="/web/static/src/less/enterprise_compatibility.less"/>
|
||||
<link rel="stylesheet" href="/web/static/src/less/utils.less"/>
|
||||
<script src="/web/static/lib/bootstrap/js/affix.js"></script>
|
||||
<script src="/web/static/lib/bootstrap/js/alert.js"></script>
|
||||
<script src="/web/static/lib/bootstrap/js/button.js"></script>
|
||||
@@ -138,6 +140,7 @@
|
||||
<script type="text/javascript" src="/web/static/src/js/widgets/notification.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/widgets/sidebar.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/widgets/progress_bar.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/widgets/pager.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/widgets/systray_menu.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/widgets/user_menu.js"></script>
|
||||
<script type="text/javascript" src="/web/static/src/js/framework/dialog.js"></script>
|
||||
|
||||
@@ -577,11 +577,11 @@
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.openerp .oe_popup_form .oe_kanban_buttons .oe_highlight {
|
||||
.openerp .o_popup_form .oe_kanban_buttons .oe_highlight {
|
||||
color: #404040;
|
||||
background: none;
|
||||
}
|
||||
.openerp .oe_popup_form .oe_kanban_buttons button.oe_highlight {
|
||||
.openerp .o_popup_form .oe_kanban_buttons button.oe_highlight {
|
||||
background-color: #efefef;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#d8d8d8));
|
||||
background-image: -webkit-linear-gradient(top, #efefef, #d8d8d8);
|
||||
@@ -593,7 +593,7 @@
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
|
||||
}
|
||||
.openerp .oe_popup_form .oe_kanban_buttons button.oe_highlight:active {
|
||||
.openerp .o_popup_form .oe_kanban_buttons button.oe_highlight:active {
|
||||
background-color: #e3e3e3;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e3e3e3), to(#f6f6f6));
|
||||
background-image: -webkit-linear-gradient(top, #e3e3e3, #f6f6f6);
|
||||
@@ -605,7 +605,7 @@
|
||||
-webkit-box-shadow: none;
|
||||
-box-shadow: none;
|
||||
}
|
||||
.openerp .oe_popup_form .oe_kanban_buttons button.oe_highlight:hover {
|
||||
.openerp .o_popup_form .oe_kanban_buttons button.oe_highlight:hover {
|
||||
background-color: #f6f6f6;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#e3e3e3));
|
||||
background-image: -webkit-linear-gradient(top, #f6f6f6, #e3e3e3);
|
||||
|
||||
@@ -514,7 +514,7 @@
|
||||
padding: 0px
|
||||
background: #ffffff
|
||||
.openerp
|
||||
.oe_popup_form
|
||||
.o_popup_form
|
||||
.oe_kanban_buttons
|
||||
.oe_highlight
|
||||
color: #404040
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
odoo.define('web_kanban.compatibility', function (require) {
|
||||
"use strict";
|
||||
|
||||
var common = require('web_kanban.common');
|
||||
var kanban_widgets = require('web_kanban.widgets');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
var KanbanColumn = require('web_kanban.Column');
|
||||
var KanbanView = require('web_kanban.KanbanView');
|
||||
|
||||
return;
|
||||
openerp = window.openerp || {};
|
||||
openerp.web_kanban = openerp.web_kanban || {};
|
||||
openerp.web_kanban.AbstractField = common.AbstractField;
|
||||
openerp.web_kanban.KanbanGroup = common.KanbanGroup;
|
||||
openerp.web_kanban.KanbanRecord = common.KanbanRecord;
|
||||
openerp.web_kanban.AbstractField = kanban_widgets.AbstractField;
|
||||
openerp.web_kanban.KanbanGroup = KanbanColumn;
|
||||
openerp.web_kanban.KanbanRecord = KanbanRecord;
|
||||
openerp.web_kanban.KanbanView = KanbanView;
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
odoo.define('web_kanban.Column', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var form_common = require('web.form_common');
|
||||
var Widget = require('web.Widget');
|
||||
var quick_create = require('web_kanban.quick_create');
|
||||
var KanbanRecord = require('web_kanban.Record');
|
||||
|
||||
var _t = core._t;
|
||||
var QWeb = core.qweb;
|
||||
var RecordQuickCreate = quick_create.RecordQuickCreate;
|
||||
|
||||
var KanbanColumn = Widget.extend({
|
||||
template: "KanbanView.Group",
|
||||
|
||||
events: {
|
||||
'click .o_kanban_toggle_fold': function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.folded = true;
|
||||
this.update_column();
|
||||
},
|
||||
'click .o_column_edit': 'edit_column',
|
||||
'click .o_column_delete': 'delete_column',
|
||||
'click .o_kanban_quick_add': 'add_quick_create',
|
||||
'click .o_kanban_load_more': 'load_more',
|
||||
},
|
||||
|
||||
custom_events: {
|
||||
'kanban_record_delete': 'delete_record',
|
||||
'cancel_quick_create': 'cancel_quick_create',
|
||||
'quick_create_add_record': 'quick_create_add_record',
|
||||
},
|
||||
|
||||
init: function(parent, group_data, options, record_options) {
|
||||
this._super(parent);
|
||||
this.data_records = group_data.records;
|
||||
this.dataset = group_data.dataset;
|
||||
this.records = [];
|
||||
this.title = group_data.title;
|
||||
this.id = group_data.id;
|
||||
this.folded = group_data.attributes.folded;
|
||||
this.fields = options.fields;
|
||||
this.values = group_data.values;
|
||||
|
||||
this.quick_create = options.quick_create;
|
||||
this.grouped_by_m2o = options.grouped_by_m2o;
|
||||
this.editable = options.editable;
|
||||
this.deletable = options.deletable;
|
||||
this.records_editable = options.records_editable;
|
||||
this.records_deletable = options.records_deletable;
|
||||
this.relation = options.relation;
|
||||
this.offset = 0;
|
||||
this.remaining = this.dataset.size() - this.data_records.length;
|
||||
|
||||
this.record_options = _.extend(_.clone(record_options), {
|
||||
group_info: this.values,
|
||||
});
|
||||
},
|
||||
|
||||
start: function() {
|
||||
var self = this;
|
||||
this.$header = this.$('.o_kanban_header');
|
||||
|
||||
for (var i = 0; i < this.data_records.length; i++) {
|
||||
this.add_record(this.data_records[i], {no_update: true});
|
||||
}
|
||||
this.$header.tooltip();
|
||||
|
||||
this.update_column();
|
||||
this.$el.sortable({
|
||||
connectWith: '.o_kanban_group',
|
||||
revert: 150,
|
||||
delay: 100,
|
||||
items: '> .o_kanban_record',
|
||||
helper: 'clone',
|
||||
cursor: 'move',
|
||||
over: function () {
|
||||
self.folded = false;
|
||||
self.update_column();
|
||||
},
|
||||
update: function (event, ui) {
|
||||
var record = ui.item.data('record');
|
||||
var index = self.records.indexOf(record);
|
||||
var test2 = $.contains(self.$el[0], record.$el[0]);
|
||||
if (index >= 0 && test2) {
|
||||
// resequencing records
|
||||
record.$el.removeAttr('style'); // jqueryui sortable add display:block inline
|
||||
self.trigger_up('kanban_column_resequence');
|
||||
} else if (index >= 0 && !test2) {
|
||||
// removing record from this column
|
||||
self.records.splice(self.records.indexOf(record), 1);
|
||||
self.dataset.remove_ids([record.id]);
|
||||
} else {
|
||||
// adding record to this column
|
||||
self.records.push(record);
|
||||
record.setParent(self);
|
||||
self.trigger_up('kanban_column_add_record', {record: record});
|
||||
}
|
||||
self.update_column();
|
||||
}
|
||||
});
|
||||
this.$el.click(function (event) {
|
||||
if (self.$el.hasClass('o_column_folded')) {
|
||||
event.preventDefault();
|
||||
self.folded = false;
|
||||
self.update_column();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
is_empty: function () {
|
||||
return !this.records.length;
|
||||
},
|
||||
|
||||
add_record: function (data, options) {
|
||||
var record = new KanbanRecord(this, data, this.record_options);
|
||||
this.records.push(record);
|
||||
this.dataset.ids = _.uniq(this.dataset.ids.concat(record.id));
|
||||
if (options.position === 'before') {
|
||||
record.insertAfter(this.quick_create_widget ? this.quick_create_widget.$el : this.$header);
|
||||
} else {
|
||||
var $load_more = this.$('.o_kanban_load_more');
|
||||
if ($load_more.length) {
|
||||
record.insertBefore($load_more);
|
||||
} else {
|
||||
record.appendTo(this.$el);
|
||||
}
|
||||
}
|
||||
if (!options.no_update) {
|
||||
this.update_column();
|
||||
}
|
||||
},
|
||||
|
||||
get_ids: function () {
|
||||
var ids = [];
|
||||
this.$('.o_kanban_record').each(function (index, r) {
|
||||
ids.push($(r).data('record').id);
|
||||
});
|
||||
return ids;
|
||||
},
|
||||
|
||||
update_column: function () {
|
||||
var title = this.folded ? this.title + ' (' + this.records.length + ')' : this.title;
|
||||
this.$header.find('.o_column_title').text(title);
|
||||
this.$header.find('.o-kanban-count').text(this.records.length);
|
||||
|
||||
this.$el.toggleClass('o_column_folded', this.folded);
|
||||
var tooltip;
|
||||
if (this.remaining) {
|
||||
tooltip = this.records.length + '/' + this.dataset.size() + _t(' records');
|
||||
} else {
|
||||
tooltip = this.records.length + _t(' records');
|
||||
}
|
||||
this.$header.tooltip().attr('data-original-title', tooltip);
|
||||
if (!this.remaining) {
|
||||
this.$('.o_kanban_load_more').remove();
|
||||
} else {
|
||||
this.$('.o_kanban_load_more').html(QWeb.render('KanbanView.LoadMore', {widget:this}))
|
||||
}
|
||||
},
|
||||
|
||||
delete_column: function (event) {
|
||||
event.preventDefault();
|
||||
var buttons = [
|
||||
{
|
||||
text: _t("Ok"),
|
||||
classes: 'btn-primary',
|
||||
close: true,
|
||||
click: this.trigger_up.bind(this, 'kanban_column_delete')
|
||||
},
|
||||
{text: _t("Cancel"), close: true}
|
||||
];
|
||||
new Dialog(this, {
|
||||
size: 'medium',
|
||||
buttons: buttons,
|
||||
$content: $('<div>', {
|
||||
text: _t("Are you sure that you want to remove this column ?")
|
||||
}),
|
||||
}).open();
|
||||
},
|
||||
|
||||
edit_column: function (event) {
|
||||
event.preventDefault();
|
||||
var dialog = new form_common.FormViewDialog(this, {
|
||||
res_model: this.relation,
|
||||
res_id: this.id,
|
||||
title: _t("Edit Column"),
|
||||
}).open();
|
||||
|
||||
dialog.on('record_saved', this, function () {
|
||||
this.trigger_up('kanban_reload');
|
||||
});
|
||||
},
|
||||
|
||||
delete_record: function (event) {
|
||||
event.stopped = false;
|
||||
var self = this;
|
||||
event.data.after = function cleanup () {
|
||||
var index = self.records.indexOf(event.data.record);
|
||||
self.records.splice(index, 1);
|
||||
self.update_column();
|
||||
};
|
||||
},
|
||||
|
||||
add_quick_create: function () {
|
||||
if (this.quick_create_widget) {
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
var width = this.records.length ? this.records[0].$el.innerWidth() : this.$el.width() - 8;
|
||||
this.quick_create_widget = new RecordQuickCreate(this, width);
|
||||
this.quick_create_widget.insertAfter(this.$header);
|
||||
this.quick_create_widget.$el.focusout(function () {
|
||||
setTimeout(function() {
|
||||
var hasFocus = !! (self.quick_create_widget.$(':focus').length > 0);
|
||||
if (! hasFocus && self.quick_create_widget) {
|
||||
self.cancel_quick_create();
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
cancel_quick_create: function () {
|
||||
this.quick_create_widget.destroy();
|
||||
this.quick_create_widget = undefined;
|
||||
},
|
||||
|
||||
quick_create_add_record: function (event) {
|
||||
this.trigger_up('column_add_record', event.data);
|
||||
},
|
||||
|
||||
load_more: function (event) {
|
||||
event.preventDefault();
|
||||
this.trigger_up('kanban_load_more');
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
return KanbanColumn;
|
||||
|
||||
});
|
||||
@@ -1,928 +0,0 @@
|
||||
odoo.define('web_kanban.common', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var data = require('web.data');
|
||||
var form_common = require('web.form_common');
|
||||
var formats = require('web.formats');
|
||||
var framework = require('web.framework');
|
||||
var ProgressBar = require('web.ProgressBar');
|
||||
var pyeval = require('web.pyeval');
|
||||
var Registry = require('web.Registry');
|
||||
var session = require('web.session');
|
||||
var time = require('web.time');
|
||||
var utils = require('web.utils');
|
||||
var web_client = require('web.web_client');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
/**
|
||||
* Interface to be implemented by kanban fields.
|
||||
*
|
||||
*/
|
||||
var FieldInterface = {
|
||||
/**
|
||||
Constructor.
|
||||
- parent: The widget's parent.
|
||||
- field: A dictionary giving details about the field, including the current field's value in the
|
||||
raw_value field.
|
||||
- $node: The field <field> tag as it appears in the view, encapsulated in a jQuery object.
|
||||
*/
|
||||
init: function(parent, field, $node) {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class for classes implementing FieldInterface.
|
||||
*
|
||||
* Properties:
|
||||
* - value: useful property to hold the value of the field. By default, the constructor
|
||||
* sets value property.
|
||||
*
|
||||
*/
|
||||
var AbstractField = Widget.extend(FieldInterface, {
|
||||
/**
|
||||
Constructor that saves the field and $node parameters and sets the "value" property.
|
||||
*/
|
||||
init: function(parent, field, $node) {
|
||||
this._super(parent);
|
||||
this.field = field;
|
||||
this.$node = $node;
|
||||
this.options = pyeval.py_eval(this.$node.attr("options") || '{}');
|
||||
this.set("value", field.raw_value);
|
||||
},
|
||||
});
|
||||
|
||||
var Priority = AbstractField.extend({
|
||||
init: function(parent, field, $node) {
|
||||
this._super.apply(this, arguments);
|
||||
this.name = $node.attr('name');
|
||||
this.parent = parent;
|
||||
},
|
||||
prepare_priority: function() {
|
||||
var self = this;
|
||||
var selection = this.field.selection || [];
|
||||
var init_value = selection && selection[0][0] || 0;
|
||||
var data = _.map(selection.slice(1), function(element, index) {
|
||||
var value = {
|
||||
'value': element[0],
|
||||
'name': element[1],
|
||||
'click_value': element[0],
|
||||
};
|
||||
if (index === 0 && self.get('value') == element[0]) {
|
||||
value.click_value = init_value;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
return data;
|
||||
},
|
||||
renderElement: function() {
|
||||
this.record_id = this.parent.id;
|
||||
this.priorities = this.prepare_priority();
|
||||
var readonly = this.field && this.field.readonly;
|
||||
if (readonly){
|
||||
this.set('readonly', true);
|
||||
}
|
||||
this.$el = $(QWeb.render("Priority", {'widget': this}));
|
||||
if (!readonly){
|
||||
this.$el.find('li').click(this.do_action.bind(this));
|
||||
}
|
||||
},
|
||||
do_action: function(e) {
|
||||
var self = this;
|
||||
var li = $(e.target).closest( "li" );
|
||||
if (li.length) {
|
||||
var value = {};
|
||||
value[self.name] = String(li.data('value'));
|
||||
return self.parent.view.dataset._model.call('write', [[self.record_id], value, self.parent.view.dataset.get_context()]).done(self.reload_record.bind(self.parent));
|
||||
}
|
||||
},
|
||||
reload_record: function() {
|
||||
this.do_reload();
|
||||
},
|
||||
});
|
||||
|
||||
var KanbanSelection = AbstractField.extend({
|
||||
init: function(parent, field, $node) {
|
||||
this._super.apply(this, arguments);
|
||||
this.name = $node.attr('name');
|
||||
this.parent = parent;
|
||||
},
|
||||
prepare_dropdown_selection: function() {
|
||||
var self = this;
|
||||
var data = [];
|
||||
_.map(this.field.selection || [], function(res) {
|
||||
var value = {
|
||||
'name': res[0],
|
||||
'tooltip': res[1],
|
||||
'state_name': res[1],
|
||||
};
|
||||
var leg_opt = self.options && self.options.states_legend || null;
|
||||
if (leg_opt && leg_opt[res[0]] && self.parent.group.values && self.parent.group.values[leg_opt[res[0]]]) {
|
||||
value['state_name'] = self.parent.group.values[leg_opt[res[0]]];
|
||||
value['tooltip'] = self.parent.group.values[leg_opt[res[0]]];
|
||||
}
|
||||
if (res[0] == 'normal') { value['state_class'] = 'oe_kanban_status'; }
|
||||
else if (res[0] == 'done') { value['state_class'] = 'oe_kanban_status oe_kanban_status_green'; }
|
||||
else { value['state_class'] = 'oe_kanban_status oe_kanban_status_red'; }
|
||||
data.push(value);
|
||||
});
|
||||
return data;
|
||||
},
|
||||
renderElement: function() {
|
||||
var self = this;
|
||||
this.record_id = self.parent.id;
|
||||
this.states = self.prepare_dropdown_selection();
|
||||
this.$el = $(QWeb.render("KanbanSelection", {'widget': self}));
|
||||
this.$el.find('li').click(self.do_action.bind(self));
|
||||
},
|
||||
do_action: function(e) {
|
||||
var self = this;
|
||||
var li = $(e.target).closest( "li" );
|
||||
if (li.length) {
|
||||
var value = {};
|
||||
value[self.name] = String(li.data('value'));
|
||||
return self.parent.view.dataset._model.call('write', [[self.record_id], value, self.parent.view.dataset.get_context()]).done(self.reload_record.bind(self.parent));
|
||||
}
|
||||
},
|
||||
reload_record: function() {
|
||||
this.do_reload();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Quick creation view.
|
||||
*
|
||||
* Triggers a single event "added" with a single parameter "name", which is the
|
||||
* name entered by the user
|
||||
*
|
||||
* @class
|
||||
* @type {*}
|
||||
*/
|
||||
var QuickCreate = Widget.extend({
|
||||
template: 'KanbanView.quick_create',
|
||||
|
||||
/**
|
||||
* close_btn: If true, the widget will display a "Close" button able to trigger
|
||||
* a "close" event.
|
||||
*/
|
||||
init: function(parent, dataset, context, buttons) {
|
||||
this._super(parent);
|
||||
this._dataset = dataset;
|
||||
this._buttons = buttons || false;
|
||||
this._context = context || {};
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
self.$input = this.$el.find('input');
|
||||
self.$input.keyup(function(event){
|
||||
if(event.keyCode == 13){
|
||||
self.quick_add();
|
||||
}
|
||||
});
|
||||
$(".oe_kanban_quick_create").focusout(function (e) {
|
||||
var val = self.$el.find('input').val();
|
||||
if (/^\s*$/.test(val)) { self.trigger('close'); }
|
||||
e.stopImmediatePropagation();
|
||||
});
|
||||
$(".oe_kanban_quick_create_add", this.$el).click(function () {
|
||||
self.quick_add();
|
||||
self.focus();
|
||||
});
|
||||
$(".oe_kanban_quick_create_close", this.$el).click(function (ev) {
|
||||
ev.preventDefault();
|
||||
self.trigger('close');
|
||||
});
|
||||
self.$input.keyup(function(e) {
|
||||
if (e.keyCode == 27 && self._buttons) {
|
||||
self.trigger('close');
|
||||
}
|
||||
});
|
||||
},
|
||||
focus: function() {
|
||||
this.$el.find('input').focus();
|
||||
},
|
||||
/**
|
||||
* Handles user event from nested quick creation view
|
||||
*/
|
||||
quick_add: function () {
|
||||
var self = this;
|
||||
var val = this.$input.val();
|
||||
if (/^\s*$/.test(val)) { this.$el.remove(); return; }
|
||||
this._dataset.call(
|
||||
'name_create', [val, new data.CompoundContext(
|
||||
this._dataset.get_context(), this._context)])
|
||||
.then(function(record) {
|
||||
self.$input.val("");
|
||||
self.trigger('added', record[0]);
|
||||
}, function(error, event) {
|
||||
event.preventDefault();
|
||||
return self.slow_create();
|
||||
});
|
||||
},
|
||||
slow_create: function() {
|
||||
var self = this;
|
||||
var popup = new form_common.SelectCreatePopup(this);
|
||||
popup.select_element(
|
||||
self._dataset.model,
|
||||
{
|
||||
title: _t("Create: ") + (this.string || this.name),
|
||||
initial_view: "form",
|
||||
disable_multiple_selection: true
|
||||
},
|
||||
[],
|
||||
{"default_name": self.$input.val()}
|
||||
);
|
||||
popup.on("elements_selected", self, function(element_ids) {
|
||||
self.$input.val("");
|
||||
self.trigger('added', element_ids[0]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var KanbanRecord = Widget.extend({
|
||||
template: 'KanbanView.record',
|
||||
|
||||
events: {
|
||||
'click .o_kanban_manage_toggle_button': 'toggle_manage_pane',
|
||||
},
|
||||
|
||||
init: function (parent, record) {
|
||||
this._super(parent);
|
||||
this.group = parent;
|
||||
this.view = parent.view;
|
||||
this.id = null;
|
||||
this.set_record(record);
|
||||
if (!this.view.state.records[this.id]) {
|
||||
this.view.state.records[this.id] = {
|
||||
folded: false
|
||||
};
|
||||
}
|
||||
this.state = this.view.state.records[this.id];
|
||||
this.fields = {};
|
||||
},
|
||||
set_record: function(record) {
|
||||
var self = this;
|
||||
this.id = record.id;
|
||||
this.values = {};
|
||||
_.each(record, function(v, k) {
|
||||
self.values[k] = {
|
||||
value: v
|
||||
};
|
||||
});
|
||||
this.record = this.transform_record(record);
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this._super();
|
||||
this.init_content();
|
||||
},
|
||||
init_content: function() {
|
||||
var self = this;
|
||||
self.sub_widgets = [];
|
||||
this.$("[data-field_id]").each(function() {
|
||||
self.add_widget($(this));
|
||||
});
|
||||
this.$el.data('widget', this);
|
||||
this.bind_events();
|
||||
},
|
||||
transform_record: function(record) {
|
||||
var self = this,
|
||||
new_record = {};
|
||||
_.each(record, function(value, name) {
|
||||
var r = _.clone(self.view.fields_view.fields[name] || {});
|
||||
if ((r.type === 'date' || r.type === 'datetime') && value) {
|
||||
r.raw_value = time.auto_str_to_date(value);
|
||||
} else {
|
||||
r.raw_value = value;
|
||||
}
|
||||
r.value = formats.format_value(value, r);
|
||||
new_record[name] = r;
|
||||
});
|
||||
return new_record;
|
||||
},
|
||||
renderElement: function() {
|
||||
this.qweb_context = {
|
||||
record: this.record,
|
||||
widget: this,
|
||||
read_only_mode: this.view.options.read_only_mode,
|
||||
};
|
||||
for (var p in this) {
|
||||
if (_.str.startsWith(p, 'kanban_')) {
|
||||
this.qweb_context[p] = _.bind(this[p], this);
|
||||
}
|
||||
}
|
||||
var $el = QWeb.render(this.template, {
|
||||
'widget': this,
|
||||
'content': this.view.qweb.render('kanban-box', this.qweb_context)
|
||||
});
|
||||
this.replaceElement($el);
|
||||
this.replace_fields();
|
||||
},
|
||||
replace_fields: function() {
|
||||
var self = this;
|
||||
this.$("field").each(function() {
|
||||
var $field = $(this);
|
||||
var $nfield = $("<span></span");
|
||||
var id = _.uniqueId("kanbanfield");
|
||||
self.fields[id] = $field;
|
||||
$nfield.attr("data-field_id", id);
|
||||
$field.replaceWith($nfield);
|
||||
});
|
||||
},
|
||||
add_widget: function($node) {
|
||||
var $orig = this.fields[$node.data("field_id")];
|
||||
var field = this.record[$orig.attr("name")];
|
||||
var type = field.type;
|
||||
type = $orig.attr("widget") ? $orig.attr("widget") : type;
|
||||
var obj = fields_registry.get(type);
|
||||
var widget = new obj(this, field, $orig);
|
||||
this.sub_widgets.push(widget);
|
||||
widget.replace($node);
|
||||
},
|
||||
bind_events: function() {
|
||||
var self = this;
|
||||
this.setup_color_picker();
|
||||
this.$el.find('[title]').each(function(){
|
||||
$(this).tooltip({
|
||||
delay: { show: 500, hide: 0},
|
||||
title: function() {
|
||||
var template = $(this).attr('tooltip');
|
||||
if (!self.view.qweb.has_template(template)) {
|
||||
return false;
|
||||
}
|
||||
return self.view.qweb.render(template, self.qweb_context);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// If no draghandle is found, make the whole card as draghandle (provided one can edit)
|
||||
if (!this.$el.find('.oe_kanban_draghandle').length) {
|
||||
this.$el.children(':first')
|
||||
.toggleClass('oe_kanban_draghandle', this.view.is_action_enabled('edit'));
|
||||
}
|
||||
|
||||
this.$el.find('.oe_kanban_action').click(function(ev) {
|
||||
ev.preventDefault();
|
||||
var $action = $(this),
|
||||
type = $action.data('type') || 'button',
|
||||
method = 'do_action_' + (type === 'action' ? 'object' : type);
|
||||
if ((type === 'edit' || type === 'delete') && ! self.view.is_action_enabled(type)) {
|
||||
self.view.open_record(self.id, true);
|
||||
} else if (_.str.startsWith(type, 'switch_')) {
|
||||
self.view.do_switch_view(type.substr(7));
|
||||
} else if (typeof self[method] === 'function') {
|
||||
self[method]($action);
|
||||
} else {
|
||||
self.do_warn("Kanban: no action for type : " + type);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.$el.find('.oe_kanban_global_click,.oe_kanban_global_click_edit').length) {
|
||||
this.$el.on('click', function(ev) {
|
||||
if (!ev.isTrigger && !$._data(ev.target, 'events')) {
|
||||
var trigger = true;
|
||||
var elem = ev.target;
|
||||
var ischild = true;
|
||||
var children = [];
|
||||
while (elem) {
|
||||
var events = $._data(elem, 'events');
|
||||
if (elem == ev.currentTarget) {
|
||||
ischild = false;
|
||||
}
|
||||
if (ischild) {
|
||||
children.push(elem);
|
||||
if (events && events.click) {
|
||||
// do not trigger global click if one child has a click event registered
|
||||
trigger = false;
|
||||
}
|
||||
}
|
||||
if (trigger && events && events.click) {
|
||||
_.each(events.click, function(click_event) {
|
||||
if (click_event.selector) {
|
||||
// For each parent of original target, check if a
|
||||
// delegated click is bound to any previously found children
|
||||
_.each(children, function(child) {
|
||||
if ($(child).is(click_event.selector)) {
|
||||
trigger = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
elem = elem.parentElement;
|
||||
}
|
||||
if (trigger) {
|
||||
self.on_card_clicked(ev);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
/* actions when user click on the block with a specific class
|
||||
* open on normal view : oe_kanban_global_click
|
||||
* open on form/edit view : oe_kanban_global_click_edit
|
||||
*/
|
||||
on_card_clicked: function(ev) {
|
||||
if (this.$el.find('.oe_kanban_global_click').size() > 0 && this.$el.find('.oe_kanban_global_click').data('routing')) {
|
||||
framework.redirect(this.$el.find('.oe_kanban_global_click').data('routing') + "/" + this.id);
|
||||
}
|
||||
else if (this.$el.find('.oe_kanban_global_click_edit').size()>0)
|
||||
this.do_action_edit();
|
||||
else
|
||||
this.do_action_open();
|
||||
},
|
||||
setup_color_picker: function() {
|
||||
var self = this;
|
||||
var $el = this.$el.find('ul.oe_kanban_colorpicker');
|
||||
if ($el.length) {
|
||||
$el.html(QWeb.render('KanbanColorPicker', {
|
||||
widget: this
|
||||
}));
|
||||
$el.on('click', 'a', function(ev) {
|
||||
ev.preventDefault();
|
||||
var color_field = $(this).parents('.oe_kanban_colorpicker').first().data('field') || 'color';
|
||||
var data = {};
|
||||
data[color_field] = $(this).data('color');
|
||||
self.view.dataset.write(self.id, data, {}).done(function() {
|
||||
self.record[color_field] = $(this).data('color');
|
||||
self.do_reload();
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
toggle_manage_pane: function(){
|
||||
this.$('.o_kanban_card_content').toggleClass('o_visible o_invisible');
|
||||
this.$('.o_kanban_card_manage_pane').toggleClass('o_visible o_invisible');
|
||||
this.$('.o_kanban_manage_button_section').toggleClass(this.kanban_color((this.values['color'] && this.values['color'].value) || 0));
|
||||
},
|
||||
|
||||
do_action_delete: function($action) {
|
||||
var self = this;
|
||||
function do_it() {
|
||||
return $.when(self.view.dataset.unlink([self.id])).done(function() {
|
||||
self.group.remove_record(self.id);
|
||||
self.destroy();
|
||||
});
|
||||
}
|
||||
if (this.view.options.confirm_on_delete) {
|
||||
if (confirm(_t("Are you sure you want to delete this record ?"))) {
|
||||
return do_it();
|
||||
}
|
||||
} else
|
||||
return do_it();
|
||||
},
|
||||
do_action_edit: function($action) {
|
||||
this.view.open_record(this.id, true);
|
||||
},
|
||||
do_action_open: function($action) {
|
||||
this.view.open_record(this.id);
|
||||
},
|
||||
do_action_object: function ($action) {
|
||||
var button_attrs = $action.data();
|
||||
var node_context = button_attrs.context || {};
|
||||
var context = new data.CompoundContext(node_context);
|
||||
context.set_eval_context({
|
||||
active_id: this.id,
|
||||
active_ids: [this.id],
|
||||
active_model: this.view.dataset.model
|
||||
});
|
||||
var action_data = _.extend({}, button_attrs, {context: context});
|
||||
this.view.do_execute_action(action_data, this.view.dataset, this.id, this.do_reload);
|
||||
},
|
||||
do_action_url: function($action) {
|
||||
return framework.redirect($action.attr("href"));
|
||||
},
|
||||
do_reload: function() {
|
||||
var self = this;
|
||||
this.view.dataset.read_ids([this.id], this.view.fields_keys.concat(['__last_update'])).done(function(records) {
|
||||
_.each(self.sub_widgets, function(el) {
|
||||
el.destroy();
|
||||
});
|
||||
self.sub_widgets = [];
|
||||
if (records.length) {
|
||||
self.set_record(records[0]);
|
||||
self.renderElement();
|
||||
self.init_content();
|
||||
self.group.compute_cards_auto_height();
|
||||
self.view.postprocess_m2m_tags();
|
||||
} else {
|
||||
self.destroy();
|
||||
}
|
||||
});
|
||||
},
|
||||
kanban_getcolor: function(variable) {
|
||||
var index = 0;
|
||||
switch (typeof(variable)) {
|
||||
case 'string':
|
||||
for (var i=0, ii=variable.length; i<ii; i++) {
|
||||
index += variable.charCodeAt(i);
|
||||
}
|
||||
break;
|
||||
case 'number':
|
||||
index = Math.round(variable);
|
||||
break;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
var color = (index % this.view.number_of_color_schemes);
|
||||
return color;
|
||||
},
|
||||
kanban_color: function(variable) {
|
||||
var color = this.kanban_getcolor(variable);
|
||||
return color === '' ? '' : 'oe_kanban_color_' + color;
|
||||
},
|
||||
kanban_image: function(model, field, id, cache, options) {
|
||||
options = options || {};
|
||||
var url;
|
||||
if (this.record[field] && this.record[field].value && !utils.is_bin_size(this.record[field].value)) {
|
||||
url = 'data:image/png;base64,' + this.record[field].value;
|
||||
} else if (this.record[field] && ! this.record[field].value) {
|
||||
url = "/web/static/src/img/placeholder.png";
|
||||
} else {
|
||||
id = JSON.stringify(id);
|
||||
if (options.preview_image)
|
||||
field = options.preview_image;
|
||||
url = session.url('/web/binary/image', {model: model, field: field, id: id});
|
||||
if (cache !== undefined) {
|
||||
// Set the cache duration in seconds.
|
||||
url += '&cache=' + parseInt(cache, 10);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
},
|
||||
kanban_text_ellipsis: function(s, size) {
|
||||
size = size || 160;
|
||||
if (!s) {
|
||||
return '';
|
||||
} else if (s.length <= size) {
|
||||
return s;
|
||||
} else {
|
||||
return s.substr(0, size) + '...';
|
||||
}
|
||||
},
|
||||
kanban_compute_domain: function(domain) {
|
||||
return data.compute_domain(domain, this.values);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var KanbanGroup = Widget.extend({
|
||||
template: 'KanbanView.group_header',
|
||||
init: function (parent, records, group, dataset) {
|
||||
var self = this;
|
||||
this._super(parent);
|
||||
this.$has_been_started = $.Deferred();
|
||||
this.view = parent;
|
||||
this.group = group;
|
||||
this.dataset = dataset;
|
||||
this.dataset_offset = 0;
|
||||
this.value = this.title = this.values = null;
|
||||
if (this.group) {
|
||||
this.values = group.values;
|
||||
this.value = group.get('value');
|
||||
this.title = group.get('value');
|
||||
if (this.value instanceof Array) {
|
||||
this.title = this.value[1];
|
||||
this.value = this.value[0];
|
||||
}
|
||||
var field = this.view.group_by_field;
|
||||
if (!_.isEmpty(field)) {
|
||||
try {
|
||||
this.title = formats.format_value(group.get('value'), field, false);
|
||||
} catch(e) {}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.title === false) {
|
||||
this.title = _t('Undefined');
|
||||
this.undefined_title = true;
|
||||
}
|
||||
var key = this.view.group_by + '-' + this.value;
|
||||
if (!this.view.state.groups[key]) {
|
||||
this.view.state.groups[key] = {
|
||||
folded: group ? group.get('folded') : false
|
||||
};
|
||||
}
|
||||
this.state = this.view.state.groups[key];
|
||||
this.$records = null;
|
||||
|
||||
this.records = [];
|
||||
this.$has_been_started.done(function() {
|
||||
self.do_add_records(records);
|
||||
});
|
||||
},
|
||||
start: function() {
|
||||
var self = this,
|
||||
def = this._super();
|
||||
if (! self.view.group_by) {
|
||||
self.$el.addClass("oe_kanban_no_group");
|
||||
var QuickCreateClass = self.view.get_quick_create_class();
|
||||
self.quick = (new QuickCreateClass(this, self.dataset, {}, false))
|
||||
.on('added', self, self.proxy('quick_created'));
|
||||
self.quick.replace($(".oe_kanban_no_group_qc_placeholder"));
|
||||
}
|
||||
this.$records = $(QWeb.render('KanbanView.group_records_container', { widget : this}));
|
||||
this.$records.insertBefore(this.view.$el.find('.oe_kanban_groups_records td:last'));
|
||||
|
||||
this.$el.on('click', '.oe_kanban_group_dropdown li a', function(ev) {
|
||||
var fn = 'do_action_' + $(ev.target).data().action;
|
||||
if (typeof(self[fn]) === 'function') {
|
||||
self[fn]($(ev.target));
|
||||
}
|
||||
});
|
||||
|
||||
this.$el.find('.oe_kanban_add').click(function () {
|
||||
if (self.view.quick) {
|
||||
self.view.quick.trigger('close');
|
||||
}
|
||||
if (self.quick) {
|
||||
return false;
|
||||
}
|
||||
self.view.$el.find('.oe_view_nocontent').hide();
|
||||
var ctx = {};
|
||||
ctx['default_' + self.view.group_by] = self.value;
|
||||
self.quick = new (self.view.get_quick_create_class())(this, self.dataset, ctx, true)
|
||||
.on('added', self, self.proxy('quick_created'))
|
||||
.on('close', self, function() {
|
||||
self.view.$el.find('.oe_view_nocontent').show();
|
||||
this.quick.destroy();
|
||||
delete self.view.quick;
|
||||
delete this.quick;
|
||||
});
|
||||
self.quick.appendTo($(".oe_kanban_group_list_header", self.$records));
|
||||
self.quick.focus();
|
||||
self.view.quick = self.quick;
|
||||
});
|
||||
// Add bounce effect on image '+' of kanban header when click on empty space of kanban grouped column.
|
||||
this.$records.on('click', '.oe_kanban_show_more', this.do_show_more);
|
||||
if (this.state.folded) {
|
||||
this.do_toggle_fold();
|
||||
}
|
||||
this.$el.data('widget', this);
|
||||
this.$records.data('widget', this);
|
||||
this.$has_been_started.resolve();
|
||||
var add_btn = this.$el.find('.oe_kanban_add');
|
||||
add_btn.tooltip({delay: { show: 500, hide:1000 }});
|
||||
this.$records.find(".oe_kanban_column_cards").click(function (ev) {
|
||||
if (ev.target == ev.currentTarget) {
|
||||
if (!self.state.folded) {
|
||||
add_btn.openerpBounce();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.is_started = true;
|
||||
this.fetch_tooltip();
|
||||
return def;
|
||||
},
|
||||
/*
|
||||
* Form the tooltip, based on optional group_by_tooltip on the grouping field.
|
||||
* This function goes through the arch of the view, finding the declaration
|
||||
* of the field used to group. If group_by_tooltip is defined, use the previously
|
||||
* computed values of the group to form the tooltip. */
|
||||
fetch_tooltip: function() {
|
||||
var self = this;
|
||||
if (! this.group)
|
||||
return;
|
||||
var options = null;
|
||||
var recurse = function(node) {
|
||||
if (node.tag === "field" && node.attrs.name == self.view.group_by) {
|
||||
options = pyeval.py_eval(node.attrs.options || '{}');
|
||||
return;
|
||||
}
|
||||
_.each(node.children, function(child) {
|
||||
recurse(child);
|
||||
});
|
||||
};
|
||||
recurse(this.view.fields_view.arch);
|
||||
if (options && options.group_by_tooltip) {
|
||||
this.tooltip = _.compact(
|
||||
_.union(
|
||||
[this.title],
|
||||
_.map(
|
||||
options.group_by_tooltip,
|
||||
function (key, value, list) { return self.values && self.values[value] && (key + "\n" + self.values[value]) || ''; }))
|
||||
).join('\n\n');
|
||||
this.$(".oe_kanban_group_title_text").attr("title", this.tooltip || this.title || "");
|
||||
}
|
||||
},
|
||||
compute_cards_auto_height: function() {
|
||||
// oe_kanban_no_auto_height is an empty class used to disable this feature
|
||||
if (!this.view.group_by) {
|
||||
var min_height = 0;
|
||||
var els = [];
|
||||
_.each(this.records, function(r) {
|
||||
var $e = r.$el.children(':first:not(.oe_kanban_no_auto_height)').css('min-height', 0);
|
||||
if ($e.length) {
|
||||
els.push($e[0]);
|
||||
min_height = Math.max(min_height, $e.outerHeight());
|
||||
}
|
||||
});
|
||||
$(els).css('min-height', min_height);
|
||||
}
|
||||
},
|
||||
destroy: function() {
|
||||
this._super();
|
||||
if (this.$records) {
|
||||
this.$records.remove();
|
||||
}
|
||||
},
|
||||
do_show_more: function(evt) {
|
||||
var self = this;
|
||||
var ids = self.view.dataset.ids.slice(0);
|
||||
return this.dataset.read_slice(this.view.fields_keys.concat(['__last_update']), {
|
||||
'limit': self.view.limit,
|
||||
'offset': self.dataset_offset += self.view.limit
|
||||
}).then(function(records) {
|
||||
self.view.dataset.ids = ids.concat(_.difference(self.dataset.ids, ids));
|
||||
self.do_add_records(records);
|
||||
self.compute_cards_auto_height();
|
||||
self.view.postprocess_m2m_tags();
|
||||
return records;
|
||||
});
|
||||
},
|
||||
do_add_records: function(records, prepend) {
|
||||
var self = this;
|
||||
var $list_header = this.$records.find('.oe_kanban_group_list_header');
|
||||
var $show_more = this.$records.find('.oe_kanban_show_more');
|
||||
var $cards = this.$records.find('.oe_kanban_column_cards');
|
||||
|
||||
_.each(records, function(record) {
|
||||
var rec = new KanbanRecord(self, record);
|
||||
if (!prepend) {
|
||||
rec.appendTo($cards);
|
||||
self.records.push(rec);
|
||||
} else {
|
||||
rec.prependTo($cards);
|
||||
self.records.unshift(rec);
|
||||
}
|
||||
});
|
||||
if ($show_more.length) {
|
||||
var size = this.dataset.size();
|
||||
$show_more.toggle(this.records.length < size).find('.oe_kanban_remaining').text(size - this.records.length);
|
||||
}
|
||||
},
|
||||
remove_record: function(id, remove_from_dataset) {
|
||||
for (var i = 0; i < this.records.length; i++) {
|
||||
if (this.records[i]['id'] === id) {
|
||||
this.records.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
},
|
||||
do_toggle_fold: function(compute_width) {
|
||||
this.$el.add(this.$records).toggleClass('oe_kanban_group_folded');
|
||||
this.state.folded = this.$el.is('.oe_kanban_group_folded');
|
||||
this.$("ul.oe_kanban_group_dropdown li a[data-action=toggle_fold]").text((this.state.folded) ? _t("Unfold") : _t("Fold"));
|
||||
},
|
||||
do_action_toggle_fold: function() {
|
||||
this.do_toggle_fold();
|
||||
},
|
||||
do_action_edit: function() {
|
||||
var self = this;
|
||||
self.do_action({
|
||||
res_id: this.value,
|
||||
name: _t("Edit column"),
|
||||
res_model: self.view.group_by_field.relation,
|
||||
views: [[false, 'form']],
|
||||
type: 'ir.actions.act_window',
|
||||
target: "new",
|
||||
flags: {
|
||||
action_buttons: true,
|
||||
headless: true,
|
||||
}
|
||||
});
|
||||
// to do : remove this horrible hack
|
||||
var am = web_client.action_manager;
|
||||
var form = am.dialog_widget.views.form.controller;
|
||||
form.on("on_button_cancel", am.dialog, function() { return am.dialog.$dialog_box.modal('hide'); });
|
||||
form.on('record_saved', self, function() {
|
||||
am.dialog.$dialog_box.modal('hide');
|
||||
self.view.do_reload();
|
||||
});
|
||||
},
|
||||
do_action_delete: function() {
|
||||
var self = this;
|
||||
if (confirm(_t("Are you sure to remove this column ?"))) {
|
||||
(new data.DataSet(self, self.view.group_by_field.relation)).unlink([self.value]).done(function(r) {
|
||||
self.view.do_reload();
|
||||
});
|
||||
}
|
||||
},
|
||||
do_save_sequences: function() {
|
||||
var self = this;
|
||||
if (_.indexOf(this.view.fields_keys, 'sequence') > -1) {
|
||||
var new_sequence = _.pluck(this.records, 'id');
|
||||
self.view.dataset.resequence(new_sequence);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Handles a newly created record
|
||||
*
|
||||
* @param {id} id of the newly created record
|
||||
*/
|
||||
quick_created: function (record) {
|
||||
var id = record, self = this;
|
||||
self.view.remove_no_result();
|
||||
self.trigger("add_record");
|
||||
this.dataset.read_ids([id], this.view.fields_keys)
|
||||
.done(function (records) {
|
||||
self.view.dataset.ids.push(id);
|
||||
self.do_add_records(records, true);
|
||||
});
|
||||
},
|
||||
highlight: function(show){
|
||||
if(show){
|
||||
this.$el.addClass('oe_kanban_column_higlight');
|
||||
this.$records.addClass('oe_kanban_column_higlight');
|
||||
}else{
|
||||
this.$el.removeClass('oe_kanban_column_higlight');
|
||||
this.$records.removeClass('oe_kanban_column_higlight');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Kanban widgets: ProgressBar
|
||||
* options
|
||||
* - editable: boolean if current_value is editable
|
||||
* - current_value: get the current_value from the field that must be present in the view
|
||||
* - max_value: get the max_value from the field that must be present in the view
|
||||
* - title: title of the gauge, displayed on top of the gauge
|
||||
* - on_change: action to call when cliking and setting a value
|
||||
*/
|
||||
var KanbanProgressBar = AbstractField.extend({
|
||||
events: {
|
||||
'click': function() {
|
||||
if(!this.readonly && this.progressbar.readonly) {
|
||||
this.toggle_progressbar();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
init: function (parent, field, node) {
|
||||
this._super(parent, field, node);
|
||||
|
||||
var record = this.getParent().record;
|
||||
this.progressbar = new ProgressBar(this, {
|
||||
readonly: true,
|
||||
value: record[this.options.current_value].raw_value,
|
||||
max_value: record[this.options.max_value].raw_value,
|
||||
title: this.options.title,
|
||||
edit_max_value: this.options.edit_max_value,
|
||||
});
|
||||
|
||||
this.readonly = !this.options.editable;
|
||||
this.on_change = this.options.on_change;
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var self = this;
|
||||
|
||||
var def = this.progressbar.appendTo('<div>').done(function() {
|
||||
self.progressbar.$el.addClass(self.$el.attr('class'));
|
||||
self.replaceElement(self.progressbar.$el);
|
||||
});
|
||||
|
||||
return $.when(this._super(), def).then(function() {
|
||||
if(!self.readonly) {
|
||||
var parent = self.getParent();
|
||||
self.progressbar.on('change:value change:max_value', self, function(e) {
|
||||
var value = this.progressbar.get(this.progressbar.edit_max_value ? 'max_value' : 'value') || 0;
|
||||
if(!isNaN(value)) {
|
||||
parent.view.dataset.call(this.on_change, [parent.id, value]).then(function() {
|
||||
self.toggle_progressbar();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
toggle_progressbar: function() {
|
||||
this.progressbar.readonly = !this.progressbar.readonly;
|
||||
var $div = $('<div/>').insertAfter(this.$el);
|
||||
this.progressbar.replace($div);
|
||||
this.setElement(this.progressbar.$el);
|
||||
},
|
||||
});
|
||||
|
||||
var fields_registry = new Registry();
|
||||
|
||||
fields_registry
|
||||
.add('priority', Priority)
|
||||
.add('kanban_state_selection', KanbanSelection)
|
||||
.add("progress", KanbanProgressBar);
|
||||
|
||||
|
||||
return {
|
||||
AbstractField: AbstractField,
|
||||
registry: fields_registry,
|
||||
QuickCreate: QuickCreate,
|
||||
KanbanRecord: KanbanRecord,
|
||||
KanbanGroup: KanbanGroup,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,127 @@
|
||||
odoo.define('web_kanban.quick_create', function (require) {
|
||||
"use strict";
|
||||
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var RecordQuickCreate = Widget.extend({
|
||||
template: "KanbanView.QuickCreate",
|
||||
|
||||
events: {
|
||||
'click .o_kanban_cancel': 'cancel',
|
||||
'click .o_kanban_add': 'add_record',
|
||||
'keypress input': function (event) {
|
||||
if (event.keyCode === 13) {
|
||||
this.add_record();
|
||||
}
|
||||
},
|
||||
'keydown': function (event) {
|
||||
if (event.keyCode === 27) {
|
||||
this.trigger_up('cancel_quick_create');
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
init: function (parent, width) {
|
||||
this._super(parent);
|
||||
this.width = width;
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this.$el.css({width: this.width});
|
||||
this.$input = this.$('input');
|
||||
this.$input.focus();
|
||||
},
|
||||
|
||||
cancel: function () {
|
||||
this.trigger_up('cancel_quick_create');
|
||||
},
|
||||
|
||||
add_record: function () {
|
||||
var value = this.$input.val();
|
||||
this.$input.val('');
|
||||
if (/^\s*$/.test(value)) { return; }
|
||||
this.trigger_up('quick_create_add_record', {value: value});
|
||||
this.$input.focus();
|
||||
},
|
||||
});
|
||||
|
||||
var ColumnQuickCreate = Widget.extend({
|
||||
template: 'KanbanView.ColumnQuickCreate',
|
||||
|
||||
events: {
|
||||
'click .o_kanban_add': function (event) {
|
||||
console.log('click okanbanadd');
|
||||
event.stopPropagation();
|
||||
this.add_column();
|
||||
},
|
||||
'click .o_kanban_quick_create': function (event) {
|
||||
console.log('click quickcreate');
|
||||
event.stopPropagation();
|
||||
},
|
||||
'keypress input': function (event) {
|
||||
if (event.keyCode === 13) {
|
||||
this.add_column();
|
||||
}
|
||||
},
|
||||
'click .o_kanban_cancel': function (event) {
|
||||
this.folded = true;
|
||||
this.update();
|
||||
},
|
||||
'keydown': function (event) {
|
||||
if (event.keyCode === 27) {
|
||||
this.folded = true;
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
init: function (parent) {
|
||||
this._super(parent);
|
||||
this.folded = true;
|
||||
},
|
||||
|
||||
start: function () {
|
||||
this.$header = this.$('.o_column_header');
|
||||
this.$quick_create = this.$('.o_kanban_quick_create');
|
||||
this.$input = this.$('input');
|
||||
this.$el.click(this.proxy('toggle'));
|
||||
var self = this;
|
||||
this.$el.focusout(function () {
|
||||
setTimeout(function() {
|
||||
var hasFocus = !! (self.$(':focus').length > 0);
|
||||
if (! hasFocus) {
|
||||
self.folded = true;
|
||||
self.update();
|
||||
}
|
||||
}, 10);
|
||||
});
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
this.folded = !this.folded;
|
||||
this.update();
|
||||
if (!this.folded) {
|
||||
this.$input.focus();
|
||||
}
|
||||
},
|
||||
|
||||
update: function () {
|
||||
this.$header.toggle(this.folded);
|
||||
this.$quick_create.toggle(!this.folded);
|
||||
},
|
||||
|
||||
add_column: function () {
|
||||
var name = this.$input.val();
|
||||
this.$input.val('');
|
||||
if (/^\s*$/.test(name)) { return; }
|
||||
this.trigger_up('quick_create_add_column', {value: name});
|
||||
this.$input.focus();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
RecordQuickCreate: RecordQuickCreate,
|
||||
ColumnQuickCreate: ColumnQuickCreate,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -0,0 +1,275 @@
|
||||
odoo.define('web_kanban.Record', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var data = require('web.data');
|
||||
var formats = require('web.formats');
|
||||
var framework = require('web.framework');
|
||||
var session = require('web.session');
|
||||
var time = require('web.time');
|
||||
var utils = require('web.utils');
|
||||
var Widget = require('web.Widget');
|
||||
var kanban_widgets = require('web_kanban.widgets');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var fields_registry = kanban_widgets.registry;
|
||||
|
||||
var KanbanRecord = Widget.extend({
|
||||
template: 'KanbanView.record',
|
||||
|
||||
events: {
|
||||
'click .oe_kanban_action': 'on_kanban_action_clicked',
|
||||
'click .o_kanban_manage_toggle_button': 'toggle_manage_pane',
|
||||
},
|
||||
|
||||
custom_events: {
|
||||
'kanban_update_record': 'update_record',
|
||||
},
|
||||
|
||||
init: function (parent, record, options) {
|
||||
this._super(parent);
|
||||
|
||||
this.fields = options.fields;
|
||||
this.editable = options.editable;
|
||||
this.deletable = options.deletable;
|
||||
this.draggable = options.draggable;
|
||||
this.read_only_mode = options.read_only_mode;
|
||||
this.model = options.model;
|
||||
this.group_info = options.group_info;
|
||||
this.qweb = options.qweb;
|
||||
this.sub_widgets = [];
|
||||
|
||||
this.init_content(record);
|
||||
},
|
||||
|
||||
init_content: function (record) {
|
||||
var self = this;
|
||||
this.id = record.id;
|
||||
this.values = {};
|
||||
_.each(record, function(v, k) {
|
||||
self.values[k] = {
|
||||
value: v
|
||||
};
|
||||
});
|
||||
this.record = this.transform_record(record);
|
||||
var qweb_context = {
|
||||
record: this.record,
|
||||
widget: this,
|
||||
read_only_mode: this.read_only_mode,
|
||||
};
|
||||
for (var p in this) {
|
||||
if (_.str.startsWith(p, 'kanban_')) {
|
||||
qweb_context[p] = _.bind(this[p], this);
|
||||
}
|
||||
}
|
||||
this.content = this.qweb.render('kanban-box', qweb_context);
|
||||
},
|
||||
|
||||
add_widgets: function () {
|
||||
var self = this;
|
||||
this.$("field").each(function() {
|
||||
var $field = $(this);
|
||||
var field = self.record[$field.attr("name")];
|
||||
var type = $field.attr("widget") || field.type;
|
||||
var Widget = fields_registry.get(type);
|
||||
var widget = new Widget(self, field, $field);
|
||||
widget.replace($field);
|
||||
self.sub_widgets.push(widget);
|
||||
});
|
||||
},
|
||||
|
||||
start: function() {
|
||||
this.add_widgets();
|
||||
},
|
||||
|
||||
renderElement: function () {
|
||||
this._super();
|
||||
this.setup_color_picker();
|
||||
this.$el.addClass('o_kanban_record');
|
||||
this.$el.data('record', this);
|
||||
if (this.$el.hasClass('oe_kanban_global_click') || this.$el.hasClass('oe_kanban_global_click_edit')) {
|
||||
this.$el.on('click', this.proxy('on_global_click'));
|
||||
}
|
||||
},
|
||||
transform_record: function(record) {
|
||||
var self = this;
|
||||
var new_record = {};
|
||||
_.each(record, function(value, name) {
|
||||
var r = _.clone(self.fields[name] || {});
|
||||
if ((r.type === 'date' || r.type === 'datetime') && value) {
|
||||
r.raw_value = time.auto_str_to_date(value);
|
||||
} else {
|
||||
r.raw_value = value;
|
||||
}
|
||||
r.value = formats.format_value(value, r);
|
||||
new_record[name] = r;
|
||||
});
|
||||
return new_record;
|
||||
},
|
||||
|
||||
update: function (record) {
|
||||
_.invoke(this.sub_widgets, 'destroy');
|
||||
this.sub_widgets = [];
|
||||
this.init_content(record);
|
||||
this.renderElement();
|
||||
this.add_widgets();
|
||||
},
|
||||
|
||||
kanban_image: function(model, field, id, cache, options) {
|
||||
options = options || {};
|
||||
var url;
|
||||
if (this.record[field] && this.record[field].value && !utils.is_bin_size(this.record[field].value)) {
|
||||
url = 'data:image/png;base64,' + this.record[field].value;
|
||||
} else if (this.record[field] && ! this.record[field].value) {
|
||||
url = "/web/static/src/img/placeholder.png";
|
||||
} else {
|
||||
id = JSON.stringify(id);
|
||||
if (options.preview_image)
|
||||
field = options.preview_image;
|
||||
url = session.url('/web/binary/image', {model: model, field: field, id: id});
|
||||
if (cache !== undefined) {
|
||||
// Set the cache duration in seconds.
|
||||
url += '&cache=' + parseInt(cache, 10);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
},
|
||||
|
||||
kanban_getcolor: function(variable) {
|
||||
if (typeof(variable) === 'number') {
|
||||
return Math.round(variable) % 10;
|
||||
}
|
||||
if (typeof(variable) === 'string') {
|
||||
var index = 0;
|
||||
for (var i=0; i<variable.length; i++) {
|
||||
index += variable.charCodeAt(i);
|
||||
}
|
||||
return index % 10;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
kanban_color: function(variable) {
|
||||
var color = this.kanban_getcolor(variable);
|
||||
return 'oe_kanban_color_' + color;
|
||||
},
|
||||
|
||||
on_global_click: function (ev) {
|
||||
if ($(ev.target).parents('.o_dropdown_kanban').length) {
|
||||
return;
|
||||
}
|
||||
if (!ev.isTrigger) {
|
||||
var trigger = true;
|
||||
var elem = ev.target;
|
||||
var ischild = true;
|
||||
var children = [];
|
||||
while (elem) {
|
||||
var events = $._data(elem, 'events');
|
||||
if (elem == ev.currentTarget) {
|
||||
ischild = false;
|
||||
}
|
||||
if (ischild) {
|
||||
children.push(elem);
|
||||
if (events && events.click) {
|
||||
// do not trigger global click if one child has a click event registered
|
||||
trigger = false;
|
||||
}
|
||||
}
|
||||
if (trigger && events && events.click) {
|
||||
_.each(events.click, function(click_event) {
|
||||
if (click_event.selector) {
|
||||
// For each parent of original target, check if a
|
||||
// delegated click is bound to any previously found children
|
||||
_.each(children, function(child) {
|
||||
if ($(child).is(click_event.selector)) {
|
||||
trigger = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
elem = elem.parentElement;
|
||||
}
|
||||
if (trigger) {
|
||||
this.on_card_clicked(ev);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* actions when user click on the block with a specific class
|
||||
* open on normal view : oe_kanban_global_click
|
||||
* open on form/edit view : oe_kanban_global_click_edit
|
||||
*/
|
||||
on_card_clicked: function() {
|
||||
if (this.$el.hasClass('oe_kanban_global_click_edit') && this.$el.data('routing')) {
|
||||
framework.redirect(this.$el.data('routing') + "/" + this.id);
|
||||
} else if (this.$el.hasClass('oe_kanban_global_click_edit')) {
|
||||
this.trigger_up('kanban_record_edit', {id: this.id});
|
||||
} else {
|
||||
this.trigger_up('kanban_record_open', {id: this.id});
|
||||
}
|
||||
},
|
||||
|
||||
toggle_manage_pane: function(event){
|
||||
event.preventDefault();
|
||||
this.$('.o_kanban_card_content').toggleClass('o_visible o_invisible');
|
||||
this.$('.o_kanban_card_manage_pane').toggleClass('o_visible o_invisible');
|
||||
this.$('.o_kanban_manage_button_section').toggleClass(this.kanban_color((this.values['color'] && this.values['color'].value) || 0));
|
||||
},
|
||||
|
||||
on_kanban_action_clicked: function (ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
var $action = $(ev.currentTarget);
|
||||
var type = $action.data('type') || 'button';
|
||||
|
||||
switch (type) {
|
||||
case 'edit':
|
||||
this.trigger_up('kanban_record_edit', {id: this.id});
|
||||
break;
|
||||
case 'open':
|
||||
this.trigger_up('kanban_record_open', {id: this.id});
|
||||
break;
|
||||
case 'delete':
|
||||
this.trigger_up('kanban_record_delete', {record: this});
|
||||
break;
|
||||
case 'action':
|
||||
case 'object':
|
||||
this.trigger_up('kanban_do_action', $action.data());
|
||||
break;
|
||||
default:
|
||||
this.do_warn("Kanban: no action for type : " + type);
|
||||
}
|
||||
},
|
||||
|
||||
kanban_compute_domain: function(domain) {
|
||||
return data.compute_domain(domain, this.values);
|
||||
},
|
||||
|
||||
update_record: function (event) {
|
||||
this.trigger_up('kanban_record_update', event.data);
|
||||
},
|
||||
|
||||
setup_color_picker: function() {
|
||||
var self = this;
|
||||
var $colorpicker = this.$('ul.oe_kanban_colorpicker');
|
||||
if (!$colorpicker.length) {
|
||||
return;
|
||||
}
|
||||
$colorpicker.html(QWeb.render('KanbanColorPicker', {
|
||||
widget: this
|
||||
}));
|
||||
$colorpicker.on('click', 'a', function(ev) {
|
||||
ev.preventDefault();
|
||||
var color_field = $colorpicker.data('field') || 'color';
|
||||
var data = {};
|
||||
data[color_field] = $(this).data('color');
|
||||
self.trigger_up('kanban_record_update', data);
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
return KanbanRecord;
|
||||
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,247 @@
|
||||
odoo.define('web_kanban.widgets', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var ProgressBar = require('web.ProgressBar');
|
||||
var pyeval = require('web.pyeval');
|
||||
var Registry = require('web.Registry');
|
||||
var session = require('web.session');
|
||||
var Widget = require('web.Widget');
|
||||
|
||||
var QWeb = core.qweb;
|
||||
/**
|
||||
* Interface to be implemented by kanban fields.
|
||||
*
|
||||
*/
|
||||
var FieldInterface = {
|
||||
/**
|
||||
Constructor.
|
||||
- parent: The widget's parent.
|
||||
- field: A dictionary giving details about the field, including the current field's value in the
|
||||
raw_value field.
|
||||
- $node: The field <field> tag as it appears in the view, encapsulated in a jQuery object.
|
||||
*/
|
||||
init: function(parent, field, $node) {},
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class for classes implementing FieldInterface.
|
||||
*
|
||||
* Properties:
|
||||
* - value: useful property to hold the value of the field. By default, the constructor
|
||||
* sets value property.
|
||||
*
|
||||
*/
|
||||
var AbstractField = Widget.extend(FieldInterface, {
|
||||
/**
|
||||
Constructor that saves the field and $node parameters and sets the "value" property.
|
||||
*/
|
||||
init: function(parent, field, $node) {
|
||||
this._super(parent);
|
||||
this.field = field;
|
||||
this.$node = $node;
|
||||
this.options = pyeval.py_eval(this.$node.attr("options") || '{}');
|
||||
this.set("value", field.raw_value);
|
||||
},
|
||||
});
|
||||
|
||||
var Priority = AbstractField.extend({
|
||||
init: function(parent, field, $node) {
|
||||
this._super.apply(this, arguments);
|
||||
this.name = $node.attr('name');
|
||||
},
|
||||
prepare_priority: function() {
|
||||
var self = this;
|
||||
var selection = this.field.selection || [];
|
||||
var init_value = selection && selection[0][0] || 0;
|
||||
var data = _.map(selection.slice(1), function(element, index) {
|
||||
var value = {
|
||||
'value': element[0],
|
||||
'name': element[1],
|
||||
'click_value': element[0],
|
||||
};
|
||||
if (index === 0 && self.get('value') == element[0]) {
|
||||
value.click_value = init_value;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
return data;
|
||||
},
|
||||
renderElement: function() {
|
||||
this.priorities = this.prepare_priority();
|
||||
var readonly = this.field && this.field.readonly;
|
||||
if (readonly){
|
||||
this.set('readonly', true);
|
||||
}
|
||||
this.$el = $(QWeb.render("Priority", {'widget': this}));
|
||||
if (!readonly){
|
||||
this.$el.on('click', 'a', this.do_action.bind(this));
|
||||
}
|
||||
},
|
||||
do_action: function(event) {
|
||||
event.preventDefault();
|
||||
var $a = $(event.currentTarget);
|
||||
var data = {};
|
||||
data[this.name] = String($a.data('value'));
|
||||
this.trigger_up('kanban_update_record', data);
|
||||
},
|
||||
});
|
||||
|
||||
var KanbanSelection = AbstractField.extend({
|
||||
|
||||
init: function(parent, field, $node) {
|
||||
this._super.apply(this, arguments);
|
||||
this.name = $node.attr('name');
|
||||
this.parent = parent;
|
||||
},
|
||||
prepare_dropdown_selection: function() {
|
||||
var self = this;
|
||||
var data = [];
|
||||
_.map(this.field.selection || [], function(res) {
|
||||
var value = {
|
||||
'name': res[0],
|
||||
'tooltip': res[1],
|
||||
'state_name': res[1],
|
||||
};
|
||||
var leg_opt = self.options && self.options.states_legend || null;
|
||||
if (leg_opt) {
|
||||
var key = leg_opt[value.name];
|
||||
var legend = self.parent.group_info[key];
|
||||
if (legend) {
|
||||
value.state_name = legend;
|
||||
value.tooltip = legend;
|
||||
}
|
||||
}
|
||||
if (res[0] == 'normal') { value.state_class = 'oe_kanban_status'; }
|
||||
else if (res[0] == 'done') { value.state_class = 'oe_kanban_status oe_kanban_status_green'; }
|
||||
else { value.state_class = 'oe_kanban_status oe_kanban_status_red'; }
|
||||
data.push(value);
|
||||
});
|
||||
return data;
|
||||
},
|
||||
renderElement: function() {
|
||||
var self = this;
|
||||
this.states = this.prepare_dropdown_selection();
|
||||
|
||||
var state;
|
||||
for(var i = 0 ; i < this.states.length ; i++) {
|
||||
if(this.states[i].name === this.get('value')) {
|
||||
state = this.states[i];
|
||||
}
|
||||
}
|
||||
|
||||
this.$el = $(QWeb.render("KanbanSelection", {'widget': this}));
|
||||
this.$('a').first().find('span').removeClass().addClass(state.state_class);
|
||||
this.$('ul li').show().filter(function() {
|
||||
return ($(this).data('value') === state.name);
|
||||
}).hide();
|
||||
|
||||
this.$('a').click(function (ev) {
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
this.$('li').click(this.set_kanban_selection.bind(this));
|
||||
},
|
||||
set_kanban_selection: function(e) {
|
||||
e.preventDefault();
|
||||
var self = this;
|
||||
var $li = $(e.target).closest( "li" );
|
||||
if ($li.length) {
|
||||
var value = {};
|
||||
value[self.name] = String($li.data('value'));
|
||||
this.trigger_up('kanban_update_record', value, this);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var KanbanAttachmentImage = AbstractField.extend({
|
||||
template: 'KanbanAttachmentImage',
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Kanban widgets: ProgressBar
|
||||
* options
|
||||
* - editable: boolean if current_value is editable
|
||||
* - current_value: get the current_value from the field that must be present in the view
|
||||
* - max_value: get the max_value from the field that must be present in the view
|
||||
* - title: title of the gauge, displayed on top of the gauge
|
||||
* - on_change: action to call when cliking and setting a value
|
||||
*/
|
||||
var KanbanProgressBar = AbstractField.extend({
|
||||
events: {
|
||||
'click': function() {
|
||||
if(!this.readonly && this.progressbar.readonly) {
|
||||
this.toggle_progressbar();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
init: function (parent, field, node) {
|
||||
this._super(parent, field, node);
|
||||
|
||||
var record = this.getParent().record;
|
||||
this.progressbar = new ProgressBar(this, {
|
||||
readonly: true,
|
||||
value: record[this.options.current_value].raw_value,
|
||||
max_value: record[this.options.max_value].raw_value,
|
||||
title: this.options.title,
|
||||
edit_max_value: this.options.edit_max_value,
|
||||
});
|
||||
|
||||
this.readonly = !this.options.editable;
|
||||
this.on_change = this.options.on_change;
|
||||
},
|
||||
|
||||
start: function () {
|
||||
var self = this;
|
||||
|
||||
var def = this.progressbar.appendTo('<div>').done(function() {
|
||||
self.progressbar.$el.addClass(self.$el.attr('class'));
|
||||
self.replaceElement(self.progressbar.$el);
|
||||
});
|
||||
|
||||
return $.when(this._super(), def).then(function() {
|
||||
if(!self.readonly) {
|
||||
var parent = self.getParent();
|
||||
self.progressbar.on('change:value change:max_value', self, function(e) {
|
||||
var value = this.progressbar.get(this.progressbar.edit_max_value ? 'max_value' : 'value') || 0;
|
||||
if(!isNaN(value)) {
|
||||
var data = {
|
||||
method: this.on_change,
|
||||
params: [parent.id, value],
|
||||
callback: self.proxy('toggle_progressbar'),
|
||||
};
|
||||
self.trigger_up('kanban_call_method', data);
|
||||
|
||||
// parent.view.dataset.call(this.on_change, [parent.id, value]).then(function() {
|
||||
// self.toggle_progressbar();
|
||||
// });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
toggle_progressbar: function() {
|
||||
this.progressbar.readonly = !this.progressbar.readonly;
|
||||
var $div = $('<div/>').insertAfter(this.$el);
|
||||
this.progressbar.replace($div);
|
||||
this.setElement(this.progressbar.$el);
|
||||
},
|
||||
});
|
||||
|
||||
var fields_registry = new Registry();
|
||||
|
||||
fields_registry
|
||||
.add('priority', Priority)
|
||||
.add('kanban_state_selection', KanbanSelection)
|
||||
.add("attachment_image", KanbanAttachmentImage)
|
||||
.add('progress', KanbanProgressBar);
|
||||
|
||||
return {
|
||||
AbstractField: AbstractField,
|
||||
registry: fields_registry,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
.oe_kanban_view {
|
||||
.o_kanban_view {
|
||||
|
||||
&.o_kanban_mobile {
|
||||
.oe_kanban_record {
|
||||
.o_kanban_record {
|
||||
width: 400px;
|
||||
}
|
||||
span {
|
||||
@@ -14,8 +14,6 @@
|
||||
|
||||
&.o_kanban_dashboard {
|
||||
|
||||
@odoo-brand-optional: #21b799;
|
||||
|
||||
.o_visible {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -43,8 +41,8 @@
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
|
||||
|
||||
.oe_kanban_colorpicker {
|
||||
min-height: 21px;
|
||||
|
||||
li {
|
||||
height: 0px;
|
||||
@@ -52,45 +50,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
.oe_kanban_record {
|
||||
padding: 0;
|
||||
position: relative;
|
||||
margin: 10px;
|
||||
|
||||
// @media (max-width: @grid-float-breakpoint) {
|
||||
// margin: 10px !important;
|
||||
// }
|
||||
}
|
||||
|
||||
// if invisible, it will no take more than its original height
|
||||
// If invisible, elem will no take more than its original height
|
||||
a, span {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.o_kanban_record {
|
||||
padding: 0;
|
||||
position: relative;
|
||||
margin: 4px 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
// color: @odoo-brand-optional;
|
||||
color: @odoo-brand-optional;
|
||||
}
|
||||
|
||||
.o_kanban_card_header {
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
.o-flex-display();
|
||||
background-color: lightgrey;
|
||||
position: relative;
|
||||
|
||||
.o_kanban_card_header_title {
|
||||
-webkit-flex: 3 0 0;
|
||||
flex: 3 0 0;
|
||||
padding: 8px;
|
||||
.o-flex(3, 0, 0);
|
||||
padding: 8px 16px;
|
||||
|
||||
.o_primary {
|
||||
// color: @odoo-brand-optional;
|
||||
font-variant: small-caps;
|
||||
font-size: large;
|
||||
color: @odoo-brand-optional;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.o_secondary {
|
||||
@@ -98,12 +88,11 @@
|
||||
}
|
||||
|
||||
.o_kanban_manage_button_section {
|
||||
-webkit-flex: 1 0 0;
|
||||
flex: 1 0 0;
|
||||
.o-flex(1, 0, 0);
|
||||
padding: 16px;
|
||||
|
||||
.o_kanban_manage_toggle_button {
|
||||
text-align: center;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,6 +118,7 @@
|
||||
.o_kanban_card_manage_pane {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.o_kanban_card_manage_section {
|
||||
@@ -145,6 +135,7 @@
|
||||
}
|
||||
|
||||
.o_kanban_card_manage_settings {
|
||||
text-align: right;
|
||||
padding: 8px;
|
||||
|
||||
border-color: lightgrey;
|
||||
|
||||
@@ -0,0 +1,500 @@
|
||||
@o-kanban-record-margin: 4px;
|
||||
|
||||
.o_kanban_view {
|
||||
|
||||
.o-flex-display();
|
||||
.o-align-content(stretch);
|
||||
@media (max-width: @grid-float-breakpoint) {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.o_kanban_quick_create {
|
||||
background-color: white;
|
||||
margin: @o-kanban-record-margin;
|
||||
box-shadow: 0px 0px 1px 1px lighten(@odoo-main-text-color, 10%);
|
||||
padding: 3px;
|
||||
input {
|
||||
width: 100%;
|
||||
margin: 4px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_record {
|
||||
min-width: 150px;
|
||||
background-color: white;
|
||||
margin: 4px 4px 8px 4px;
|
||||
box-shadow: 0px 0px 1px 1px lighten(@odoo-main-text-color, 10%);
|
||||
padding: 8px;
|
||||
|
||||
&.o_record_dragged {
|
||||
background-color: @odoo-main-text-color;
|
||||
}
|
||||
|
||||
&.oe_kanban_global_click, &.oe_kanban_global_click_edit {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.o_kanban_two_column {
|
||||
.o-flex-display();
|
||||
|
||||
.oe_kanban_details {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
.o-flex(1, 1, auto);
|
||||
width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.o_kanban_two_column_tags {
|
||||
.o-flex-display();
|
||||
.o-flex-flow(row, wrap);
|
||||
|
||||
.o_kanban_tags_section {
|
||||
.o-flex(1, 1, 100%);
|
||||
}
|
||||
.o_kanban_image {
|
||||
.o-flex(1, 1, 25%);
|
||||
margin-right: 0;
|
||||
> img {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
.oe_kanban_details {
|
||||
position: relative;
|
||||
.o-flex(1, 1, 75%);
|
||||
ul {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.o_kanban_image {
|
||||
.o-flex(0, 0, auto);
|
||||
margin-right: 8px;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.o_kanban_button {
|
||||
margin-top: 15px;
|
||||
|
||||
> button, > a {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.ui-sortable-helper {
|
||||
transform: rotate(3deg);
|
||||
opacity: 0.9,
|
||||
}
|
||||
|
||||
.o_dropdown_kanban {
|
||||
float: right;
|
||||
|
||||
// Open the dropdown a the left side of the dropdown toggle
|
||||
> .dropdown-menu {
|
||||
left: auto;
|
||||
right: 0;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
> a {
|
||||
padding: 3px;
|
||||
color: @odoo-main-text-color;
|
||||
}
|
||||
&.open {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_footer {
|
||||
.o-flex-display();
|
||||
.o-justify-content(space-between);
|
||||
> * {
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
.o_dropdown_kanban {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
.o_dropdown_kanban {
|
||||
@media (max-width: @grid-float-breakpoint) {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.o_kanban_ungrouped {
|
||||
.o-flex-flow(row, wrap);
|
||||
.o-justify-content(flex-start);
|
||||
padding: @o-kanban-record-margin @odoo-horizontal-padding - @o-kanban-record-margin;
|
||||
|
||||
@media (max-width: @grid-float-breakpoint) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.o_kanban_record {
|
||||
.o-flex(1, 1, auto);
|
||||
width: 320px;
|
||||
@media (max-width: @grid-float-breakpoint) {
|
||||
margin: 0 0 1px 0;
|
||||
width: 100vw;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_ghost {
|
||||
height: 0;
|
||||
min-height: 0 !important; // to prevent view writers to override this height
|
||||
visibility: hidden;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.o_kanban_grouped {
|
||||
min-height: 100%;
|
||||
padding: 0 @odoo-horizontal-padding - @o-kanban-record-margin;
|
||||
.o_kanban_record {
|
||||
width: 300px;
|
||||
|
||||
&.o_kanban_small {
|
||||
width: 240px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_group {
|
||||
.o-flex(0, 0, auto);
|
||||
margin: 0 4px;
|
||||
|
||||
&.o_kanban_dragged {
|
||||
background-color: @odoo-main-text-color;
|
||||
.o_kanban_record {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_header + .o_kanban_record {
|
||||
margin-top: 0; // no margin top from the first card after kanban_header
|
||||
}
|
||||
|
||||
.o_kanban_header {
|
||||
color: white;
|
||||
padding: 0 4px;
|
||||
height: 50px;
|
||||
line-height: 2.2;
|
||||
cursor: move;
|
||||
.o-flex-display();
|
||||
.o_column_unfold {
|
||||
display: none;
|
||||
}
|
||||
.o_column_title {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
.o-flex(1, 1, auto);
|
||||
white-space: nowrap;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.o-kanban-icon() {
|
||||
// Share the style of `.o_kanban_quick_add` and `o_kanban_config`.
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
line-height: 1.8;
|
||||
text-align: center;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.o_kanban_quick_add i {
|
||||
.o-kanban-icon;
|
||||
&:hover {
|
||||
background-color: @odoo-brand-optional;
|
||||
}
|
||||
}
|
||||
.o_kanban_config i {
|
||||
.o-kanban-icon;
|
||||
&:hover {
|
||||
background-color: darken(@gray-light, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_number {
|
||||
color: @odoo-main-text-color;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_record {
|
||||
&.o_kanban_dragged {
|
||||
> * {
|
||||
visibility: hidden;
|
||||
}
|
||||
background-color: @odoo-main-text-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.o_column_folded {
|
||||
position: relative;
|
||||
border-right: 1px solid @odoo-main-text-color;
|
||||
margin: 0;
|
||||
|
||||
.o_column_title {
|
||||
line-height: 1.3;
|
||||
text-transform: uppercase;
|
||||
transform-origin: left bottom;
|
||||
transform: rotate(90deg);
|
||||
top: 40px;
|
||||
left: 15px;
|
||||
position: absolute;
|
||||
}
|
||||
> .o_kanban_record, .o_kanban_quick_add, .o_kanban_config, .o_kanban_load_more {
|
||||
display: none;
|
||||
}
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
background-color: darken(@gray-light, 10%);
|
||||
}
|
||||
.o_column_unfold {
|
||||
display: block;
|
||||
padding: 0 10px;
|
||||
|
||||
> i {
|
||||
font-size: 22px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
}
|
||||
background-color: @gray-light;
|
||||
}
|
||||
|
||||
.o_kanban_load_more {
|
||||
text-align: center;
|
||||
a {
|
||||
color: white;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.oe_kanban_color_0 {
|
||||
background-color: #FFFFFF;
|
||||
color: #5a5a5a;
|
||||
}
|
||||
.oe_kanban_color_1 {
|
||||
background-color: #d8d8d8;
|
||||
color: #5e5e5e;
|
||||
}
|
||||
.oe_kanban_color_2 {
|
||||
background-color: #e5d8e3;
|
||||
color: #7a3737;
|
||||
}
|
||||
.oe_kanban_color_3 {
|
||||
background-color: #ece9c2;
|
||||
color: #756832;
|
||||
}
|
||||
.oe_kanban_color_4 {
|
||||
background-color: #dee180;
|
||||
color: #5d6937;
|
||||
}
|
||||
.oe_kanban_color_5 {
|
||||
background-color: #abd4cc;
|
||||
color: #1a7759;
|
||||
}
|
||||
.oe_kanban_color_6 {
|
||||
background-color: #b8e3e8;
|
||||
color: #1a5d83;
|
||||
}
|
||||
.oe_kanban_color_7 {
|
||||
background-color: #f4ddab;
|
||||
color: #5e5e5e;
|
||||
}
|
||||
.oe_kanban_color_8 {
|
||||
background-color: #7f637d;
|
||||
color: #a5a5a5;
|
||||
}
|
||||
.oe_kanban_color_9 {
|
||||
background-color: #d8c5d5;
|
||||
color: #5e5e5e;
|
||||
}
|
||||
.oe_kanban_color_10 {
|
||||
background-color: #46C265;
|
||||
color: #639B89;
|
||||
}
|
||||
|
||||
.oe_tags {
|
||||
display: block;
|
||||
}
|
||||
.o_kanban_tags {
|
||||
|
||||
margin-left: -8px;
|
||||
|
||||
.o_tag{
|
||||
width: 50px;
|
||||
height: 9px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
.o_kanban_footer {
|
||||
width: 100%;
|
||||
}
|
||||
.oe_kanban_avatar {
|
||||
border-radius: 12px;
|
||||
border: 1px solid @odoo-main-color-muted;
|
||||
}
|
||||
|
||||
.o_progressbar {
|
||||
.o_progressbar_title {
|
||||
width: 20%;
|
||||
}
|
||||
.o_progress {
|
||||
width: 60%;
|
||||
height: 15px;
|
||||
}
|
||||
.o_progressbar_value {
|
||||
width: 20%;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_attachment_image {
|
||||
// The image should take the hole card
|
||||
margin: -8px;
|
||||
> img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.oe_kanban_colorpicker {
|
||||
li {
|
||||
float: left;
|
||||
&:first-child a {
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
a {
|
||||
width: 15px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
border: 1px solid white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_dropdown_kanban {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.oe_kanban_avatar_smallbox {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
box-shadow: 0 1px 4px @gray-light;
|
||||
// border: 1px solid
|
||||
// border-color: #e5e5e5 #dbdbdb #d2d2d2
|
||||
// @include radius(3px)
|
||||
// @include box-shadow(0 1px 2px rgba(0,0,0,0.2))
|
||||
}
|
||||
|
||||
.o_kanban_shadow {
|
||||
background-color: @odoo-main-text-color;
|
||||
miw-width: 100px;
|
||||
}
|
||||
|
||||
.o_column_quick_create {
|
||||
.o-flex(0, 0, auto);
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
position: relative;
|
||||
background-color: @odoo-main-text-color;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: darken(@gray-light, 10%);
|
||||
}
|
||||
.o_column_header {
|
||||
.o_kanban_add_column {
|
||||
padding: 0 10px;
|
||||
color: white;
|
||||
|
||||
> i {
|
||||
font-size: 22px;
|
||||
padding-top: 7px;
|
||||
}
|
||||
}
|
||||
.o_kanban_title {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
white-space: nowrap;
|
||||
color: @gray-lighter;
|
||||
text-transform: uppercase;
|
||||
transform-origin: left bottom;
|
||||
transform: rotate(90deg);
|
||||
top: 40px;
|
||||
left: 15px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
.o_kanban_quick_create {
|
||||
display: none;
|
||||
width: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
.oe_kanban_footer_left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.oe_kanban_bottom_right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.oe_kanban_bottom_left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.oe_kanban_status {
|
||||
display: inline-block;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
border-radius: 6px;
|
||||
|
||||
background-color: @odoo-brand-secondary;
|
||||
|
||||
&.oe_kanban_status_green {
|
||||
background-color: @brand-success;
|
||||
}
|
||||
&.oe_kanban_status_red {
|
||||
background-color: @brand-danger;
|
||||
}
|
||||
}
|
||||
|
||||
.o_form_field_one2many .oe_view_nocontent {
|
||||
display: none;
|
||||
}
|
||||
@@ -1,90 +1,72 @@
|
||||
<template>
|
||||
<t t-name="KanbanView">
|
||||
<div class="oe_kanban_view">
|
||||
<div class="oe_kanban_buttons"/>
|
||||
<table class="oe_kanban_groups">
|
||||
<tr class="oe_kanban_groups_headers">
|
||||
<td class="oe_kanban_dummy_cell"><div/></td>
|
||||
</tr>
|
||||
<tr class="oe_kanban_groups_records">
|
||||
<td class="oe_kanban_dummy_cell"><div/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="KanbanView.buttons">
|
||||
<t t-if="display">
|
||||
<div class="oe_kanban_buttons">
|
||||
<button type="button" class="oe_kanban_button_new btn btn-primary btn-sm">
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary btn-sm o-kanban-button-new">
|
||||
<t t-esc="widget.options.create_text || _t('Create')"/>
|
||||
</button>
|
||||
<span t-if="widget.is_action_enabled('group_create')" class="oe_alternative" style="display: none">
|
||||
<span class="oe_fade">or</span>
|
||||
<div class="oe_bounce_container">
|
||||
<a href="#" class="oe_kanban_add_column text-info">Add a new column</a>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="KanbanView.group_header">
|
||||
<td class="oe_kanban_group_header">
|
||||
<t t-if="widget.view.group_by">
|
||||
<t t-set="parent" t-value="(widget.getParent())"/>
|
||||
<div class="oe_kanban_header oe_semantic_html_override">
|
||||
<t t-if="widget.view._is_quick_create_enabled()">
|
||||
<div><i class="oe_kanban_add fa fa-plus" title="Quick create"/></div>
|
||||
</t>
|
||||
<div class="oe_dropdown_toggle oe_dropdown_kanban">
|
||||
<div class="oe_kanban_group_length">
|
||||
<span class="oe_tag">
|
||||
<t t-if="widget.group.get('length') > 99"> 99+ </t><t t-if="widget.group.get('length') <= 99"> <t t-esc="widget.group.get('length')"/> </t>
|
||||
</span>
|
||||
</div>
|
||||
<i class="fa fa-bars fa-lg"/>
|
||||
<ul class="oe_dropdown_menu oe_kanban_group_dropdown">
|
||||
<li><a data-action="toggle_fold" href="#">Fold</a></li>
|
||||
<t t-if="widget.view.grouped_by_m2o and widget.value">
|
||||
<li t-if="parent && parent.is_action_enabled('group_edit')"><a data-action="edit" href="#">Edit</a></li>
|
||||
<li t-if="parent && parent.is_action_enabled('group_delete')"><a data-action="delete" href="#">Delete</a></li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="oe_fold_column">
|
||||
<div t-attf-class="oe_kanban_group_title #{widget.undefined_title ? 'oe_kanban_group_title_undefined' : ''}">
|
||||
<div class="oe_kanban_group_title_text" t-att-title="widget.title"><t t-esc="widget.title"/></div>
|
||||
</div>
|
||||
<div class="oe_kanban_group_length oe_tag">
|
||||
<t t-if="widget.group.get('length') > 99"> 99+ </t><t t-if="widget.group.get('length') <= 99"> <t t-esc="widget.group.get('length')"/> </t>
|
||||
</div>
|
||||
</div>
|
||||
<span t-if="widget.title" class="oe_kanban_group_title_vertical">
|
||||
<t t-esc="widget.title"/>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="! widget.view.group_by && widget.view._is_quick_create_enabled()">
|
||||
<span class="oe_kanban_no_group_qc_placeholder"/>
|
||||
</t>
|
||||
</td>
|
||||
</t>
|
||||
<t t-name="KanbanView.group_records_container">
|
||||
<td class="oe_kanban_column">
|
||||
<div class="oe_kanban_group_list_header"/>
|
||||
<div class="oe_kanban_column_cards"/>
|
||||
<div class="oe_kanban_folded_column_cards"/>
|
||||
<div class="oe_kanban_show_more">
|
||||
<button class="oe_button">Show more... (<span class="oe_kanban_remaining"></span> remaining)</button>
|
||||
|
||||
<t t-name="KanbanView.Group">
|
||||
<div class="o_kanban_group" t-att-data-id="widget.id">
|
||||
<div class="o_kanban_header" t-att-title="widget.data_records.length + ' records'">
|
||||
<span class="o_column_title"><t t-esc="widget.title"/></span>
|
||||
<span class="o_column_unfold"><i class="fa fa-arrows-h"/></span>
|
||||
<span class="o_kanban_config dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#"><i class="fa fa-gear"/></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li><a class="o_kanban_toggle_fold" href="#">Fold</a></li>
|
||||
<t t-if="widget.grouped_by_m2o">
|
||||
<li t-if="widget.editable and widget.id"><a class="o_column_edit" href="#">Edit</a></li>
|
||||
<li t-if="widget.deletable and widget.id"><a class="o_column_delete" href="#">Delete</a></li>
|
||||
</t>
|
||||
</ul>
|
||||
</span>
|
||||
<t t-if="widget.quick_create">
|
||||
<span class="o_kanban_quick_add"><i class="fa fa-plus"/></span>
|
||||
</t>
|
||||
</div>
|
||||
<div t-if="widget.remaining > 0" class="o_kanban_load_more">
|
||||
<t t-call="KanbanView.LoadMore"/>
|
||||
</div>
|
||||
</td>
|
||||
</t>
|
||||
<t t-name="KanbanView.record">
|
||||
<div class="oe_fold_column oe_kanban_record">
|
||||
<t t-raw="content"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="KanbanView.LoadMore">
|
||||
<a href="#">Load more... (<t t-esc="widget.remaining"/> remaining)</a>
|
||||
</t>
|
||||
|
||||
<t t-name="KanbanView.ColumnQuickCreate">
|
||||
<div class="o_column_quick_create">
|
||||
<div class="o_column_header">
|
||||
<span class="o_kanban_add_column"><i class="fa fa-chevron-right"/></span>
|
||||
<span class="o_kanban_title">Add new Column</span>
|
||||
</div>
|
||||
<div class="o_kanban_quick_create">
|
||||
<input type="text" placeholder="Add"/>
|
||||
<button class="btn btn-primary o_kanban_add">Add</button>
|
||||
<button class="btn btn-default o_kanban_cancel">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="KanbanView.record">
|
||||
<t t-raw="widget.content"/>
|
||||
</t>
|
||||
|
||||
<t t-name="KanbanView.QuickCreate">
|
||||
<div class="o_kanban_quick_create">
|
||||
<input type="text" placeholder="Add"/>
|
||||
<button class="btn btn-primary o_kanban_add">Add</button>
|
||||
<button class="btn btn-default o_kanban_cancel">Cancel</button>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="KanbanColorPicker">
|
||||
<li t-foreach="widget.view.number_of_color_schemes" t-as="color">
|
||||
<li t-foreach="10" t-as="color">
|
||||
<a href="#" t-att-data-color="color_index" t-attf-class="oe_kanban_color_#{color}"/>
|
||||
</li>
|
||||
</t>
|
||||
@@ -98,11 +80,13 @@
|
||||
</t>
|
||||
</div>
|
||||
<t t-name="KanbanView.nocontent">
|
||||
<div class="oe_view_nocontent" style="position:absolute;">
|
||||
<div class="oe_view_nocontent_bg"></div>
|
||||
<div class="oe_view_nocontent_content">
|
||||
<t t-raw="content"/>
|
||||
</div>
|
||||
<div class="oe_view_nocontent">
|
||||
<t t-raw="content"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-name="KanbanAttachmentImage">
|
||||
<div class="o_kanban_attachment_image">
|
||||
<img t-att-src="'/web/binary/image?model=ir.attachment&field=datas&id=' + widget.field.raw_value[0]"/>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
<data>
|
||||
<template id="assets_backend" name="web_kanban assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/web_kanban/static/src/css/kanban.css"/>
|
||||
<link rel="stylesheet" href="/web_kanban/static/src/less/kanban_dashboard.less"/>
|
||||
<link rel="stylesheet" href="/web_kanban/static/src/less/kanban_view.less"/>
|
||||
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/kanban_record.js"></script>
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/kanban_quick_create.js"></script>
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/kanban_column.js"></script>
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/kanban_view.js"></script>
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/kanban_common.js"></script>
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/kanban_widgets.js"></script>
|
||||
<script type="text/javascript" src="/web_kanban/static/src/js/compatibility.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
@@ -2,10 +2,10 @@ odoo.define('web_kanban_gauge.widget', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var kanban_common = require('web_kanban.common');
|
||||
var kanban_widgets = require('web_kanban.widgets');
|
||||
|
||||
var AbstractField = kanban_common.AbstractField;
|
||||
var fields_registry = kanban_common.registry;
|
||||
var AbstractField = kanban_widgets.AbstractField;
|
||||
var fields_registry = kanban_widgets.registry;
|
||||
var _t = core._t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,4 +11,4 @@ class TestUi(openerp.tests.HttpCase):
|
||||
def test_03_js_public(self):
|
||||
self.phantom_js('/',"console.log('ok')","console")
|
||||
def test_04_js_admin(self):
|
||||
self.phantom_js('/web',"console.log('ok')","openerp.client.action_manager.inner_widget", login='admin')
|
||||
self.phantom_js('/web',"console.log('ok')","odoo.__DEBUG__.services['web.web_client'].action_manager", login='admin')
|
||||
@@ -1,7 +1,7 @@
|
||||
.oe_WidgetWebsiteButton.danger .oe_publish {
|
||||
display: none;
|
||||
.oe_stat_button .o_stat_info:not(.published) > .o_stat_text.oe_publish {
|
||||
display: none;
|
||||
}
|
||||
.oe_WidgetWebsiteButton.success .oe_unpublish {
|
||||
.oe_stat_button .o_stat_info.published > .o_stat_text.oe_unpublish {
|
||||
display: none;
|
||||
}
|
||||
.oe_form_field_html_frame iframe {
|
||||
|
||||
@@ -9,10 +9,13 @@ var form_widgets = require('web.form_widgets'); // required to guarantee that
|
||||
var WidgetWebsiteButton = form_common.AbstractField.extend({
|
||||
template: 'WidgetWebsiteButton',
|
||||
render_value: function() {
|
||||
// Hack to replace false value by unpublished because falsy form fields
|
||||
// have classname o_form_field_empty and are hidden
|
||||
if (!this.get_value()) {
|
||||
this.set_value('unpublished');
|
||||
}
|
||||
this._super();
|
||||
this.$()
|
||||
.toggleClass("success", this.get_value())
|
||||
.toggleClass("danger", !this.get_value());
|
||||
this.$el.toggleClass("published", this.get_value() === true);
|
||||
if (this.node.attrs.class) {
|
||||
this.$el.addClass(this.node.attrs.class);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t t-name="WidgetWebsiteButton">
|
||||
<div class="oe_WidgetWebsiteButton success">
|
||||
<strong class="oe_unpublish text-danger">Not<br/>Published</strong>
|
||||
<strong class="oe_publish text-success">Published</strong>
|
||||
</div>
|
||||
</t>
|
||||
<div t-name="WidgetWebsiteButton" class="o_stat_info published">
|
||||
<span class="o_stat_text oe_unpublish text-danger">Not Published</span>
|
||||
<span class="o_stat_text oe_publish text-success">Published</span>
|
||||
</div>
|
||||
|
||||
<t t-name="FieldTextHtmlFrame">
|
||||
<div class="oe_form_field oe_form_field_html_frame oe_form_embedded_html" t-att-style="widget.node.attrs.style">
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Blog Post">
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button class="oe_inline oe_stat_button" name="open_website_url"
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" name="open_website_url"
|
||||
type="object" icon="fa-globe">
|
||||
<field name="website_published" widget="website_button"/>
|
||||
</button>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user