[IMP] sale_(project): improve the UX for project app
Purpose of this commit to improve generic usage of project app. So in this commit done the following changes: - switch the id and the priority fields from place for task list view - add a 'view sales order' button that should open the form view of the SO linked to the SOL set on the milestone for milestone list view - add a 'sales order' stat button that should open the form view of the SO linked to the SOL set on the milestone for milestone form view - add a 'done' option; represent it in purple in status field - if there is only 1 assignee, display its name on the card instead of 1 assignee for project sharing kanban view - add an 'all tasks' menu on the right of the 'my tasks' one task-2917086 closes odoo/odoo#97669 Related: odoo/upgrade#3893 Related: odoo/enterprise#30195 Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
This commit is contained in:
committed by
Barad Mahendra
parent
eebc3e0483
commit
f7f3d9610b
@@ -1332,5 +1332,11 @@ Send it ASAP, its urgent.</field>
|
||||
<field name="progress" eval="35"/>
|
||||
<field name="status">at_risk</field>
|
||||
</record>
|
||||
<record id="project_update_3" model="project.update" context="{'default_project_id': ref('project.project_project_3')}">
|
||||
<field name="name">Status</field>
|
||||
<field name="user_id" eval="ref('base.user_admin')"/>
|
||||
<field name="progress" eval="100"/>
|
||||
<field name="status">done</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -409,6 +409,7 @@ class Project(models.Model):
|
||||
('off_track', 'Off Track'),
|
||||
('on_hold', 'On Hold'),
|
||||
('to_define', 'Set Status'),
|
||||
('done', 'Done'),
|
||||
], default='to_define', compute='_compute_last_update_status', store=True, readonly=False, required=True)
|
||||
last_update_color = fields.Integer(compute='_compute_last_update_color')
|
||||
milestone_ids = fields.One2many('project.milestone', 'project_id', copy=True)
|
||||
|
||||
@@ -14,6 +14,7 @@ STATUS_COLOR = {
|
||||
'at_risk': 2, # orange
|
||||
'off_track': 23, # red / danger
|
||||
'on_hold': 4, # light blue
|
||||
'done': 5, # purple
|
||||
False: 0, # default grey -- for studio
|
||||
# Only used in project.task
|
||||
'to_define': 0,
|
||||
@@ -46,7 +47,8 @@ class ProjectUpdate(models.Model):
|
||||
('on_track', 'On Track'),
|
||||
('at_risk', 'At Risk'),
|
||||
('off_track', 'Off Track'),
|
||||
('on_hold', 'On Hold')
|
||||
('on_hold', 'On Hold'),
|
||||
('done', 'Done'),
|
||||
], required=True, tracking=True)
|
||||
color = fields.Integer(compute='_compute_color')
|
||||
progress = fields.Integer(tracking=True)
|
||||
|
||||
@@ -51,6 +51,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_counter_progress .bg-purple {
|
||||
background-color: purple;
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.o_view_nocontent {
|
||||
top: 15%;
|
||||
|
||||
@@ -8,6 +8,7 @@ export const STATUS_COLORS = {
|
||||
'at_risk': 2,
|
||||
'off_track': 1,
|
||||
'on_hold': 4,
|
||||
'done': 5,
|
||||
};
|
||||
|
||||
export const STATUS_COLOR_PREFIX = 'o_status_bubble mx-0 o_color_bubble_';
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
<xpath expr="//div[hasclass('o_portal_sidebar')]" position="inside">
|
||||
<t t-set="o_portal_fullwidth_alert" groups="project.group_project_user">
|
||||
<t t-call="portal.portal_back_in_edit_mode">
|
||||
<t t-set="backend_url" t-value="'/web#model=project.task&id=%s&action=%s&view_type=form' % (task.id, task.env.ref('project.action_view_all_task').id)"/>
|
||||
<t t-set="backend_url" t-value="'/web#model=project.task&id=%s&action=%s&view_type=form' % (task.id, task.env.ref('project.action_view_my_task').id)"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -100,9 +100,8 @@
|
||||
<div class="oe_kanban_bottom_right" t-if="!selection_mode">
|
||||
<span t-if="record.portal_user_names.raw_value.length > 0" class="pe-2" t-att-title="record.portal_user_names.raw_value">
|
||||
<t t-set="user_count" t-value="record.portal_user_names.raw_value.split(',').length"/>
|
||||
<t t-out="user_count"/>
|
||||
<t t-if="user_count > 1"> assignees</t>
|
||||
<t t-else=""> assignee</t>
|
||||
<t t-if="user_count > 1"><t t-out="user_count"/> assignees</t>
|
||||
<t t-else="" t-out="record.portal_user_names.raw_value"/>
|
||||
</span>
|
||||
<field name="kanban_state" widget="state_selection"/>
|
||||
</div>
|
||||
|
||||
@@ -826,7 +826,7 @@
|
||||
<field name="last_update_color"/>
|
||||
<field name="last_update_status"/>
|
||||
<field name="tag_ids"/>
|
||||
<progressbar field="last_update_status" colors='{"on_track": "success", "at_risk": "warning", "off_track": "danger", "on_hold": "info"}'/>
|
||||
<progressbar field="last_update_status" colors='{"on_track": "success", "at_risk": "warning", "off_track": "danger", "on_hold": "info", "done": "purple"}'/>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
@@ -1508,8 +1508,8 @@
|
||||
<field name="is_closed" invisible="1" />
|
||||
<field name="sequence" invisible="1" readonly="1"/>
|
||||
<field name="allow_milestones" invisible="1"/>
|
||||
<field name="priority" widget="priority" optional="show" nolabel="1"/>
|
||||
<field name="id" optional="hide"/>
|
||||
<field name="priority" widget="priority" optional="show" nolabel="1"/>
|
||||
<field name="child_text" invisible="1"/>
|
||||
<field name="allow_subtasks" invisible="1"/>
|
||||
<field name="name" widget="name_with_subtask_count"/>
|
||||
@@ -1650,7 +1650,19 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_all_task" model="ir.actions.act_window">
|
||||
<record id="view_task_kanban_inherit_all_task" model="ir.ui.view">
|
||||
<field name="name">project.task.kanban.inherit.all.task</field>
|
||||
<field name="model">project.task</field>
|
||||
<field name="inherit_id" ref="view_task_kanban"/>
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//kanban" position="attributes">
|
||||
<attribute name="default_group_by">project_id</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_my_task" model="ir.actions.act_window">
|
||||
<field name="name">My Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_mode">kanban,tree,form,calendar,pivot,graph,activity</field>
|
||||
@@ -1690,16 +1702,51 @@
|
||||
<field name="act_window_id" ref="action_view_task"/>
|
||||
</record>
|
||||
|
||||
<record id="open_view_all_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<record id="open_view_my_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="view_id" ref="view_task_kanban_inherit_my_task"/>
|
||||
<field name="act_window_id" ref="action_view_all_task"/>
|
||||
<field name="act_window_id" ref="action_view_my_task"/>
|
||||
</record>
|
||||
<record id="open_view_all_task_list_tree" model="ir.actions.act_window.view">
|
||||
<record id="open_view_my_task_list_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="open_view_my_tasks_list_view"/>
|
||||
<field name="act_window_id" ref="action_view_my_task"/>
|
||||
</record>
|
||||
<record id="open_view_my_task_list_calendar" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="40"/>
|
||||
<field name="view_mode">calendar</field>
|
||||
<field name="act_window_id" ref="action_view_my_task"/>
|
||||
<field name="view_id" ref="view_task_all_calendar"/>
|
||||
</record>
|
||||
|
||||
<record id="action_view_all_task" model="ir.actions.act_window">
|
||||
<field name="name">All Tasks</field>
|
||||
<field name="res_model">project.task</field>
|
||||
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
|
||||
<field name="context">{'search_default_open_tasks': 1, 'default_user_ids': [(4, uid)]}</field>
|
||||
<field name="search_view_id" ref="view_task_search_form_extended"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No tasks found. Let's create one!
|
||||
</p>
|
||||
<p>
|
||||
Organize your tasks by dispatching them across the pipeline.<br/>
|
||||
Collaborate efficiently by chatting in real-time or via email.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_view_all_task_list_tree" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="act_window_id" ref="action_view_all_task"/>
|
||||
</record>
|
||||
<record id="open_view_all_task_list_kanban" model="ir.actions.act_window.view">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view_mode">kanban</field>
|
||||
<field name="view_id" ref="view_task_kanban_inherit_all_task"/>
|
||||
<field name="act_window_id" ref="action_view_all_task"/>
|
||||
</record>
|
||||
<record id="open_view_all_task_list_calendar" model="ir.actions.act_window.view">
|
||||
@@ -1710,7 +1757,10 @@
|
||||
</record>
|
||||
|
||||
<menuitem name="My Tasks" id="menu_project_management" parent="menu_main_pm"
|
||||
action="action_view_all_task" sequence="2" groups="base.group_no_one,group_project_user"/>
|
||||
action="action_view_my_task" sequence="2" groups="group_project_user"/>
|
||||
|
||||
<menuitem name="All Tasks" id="menu_project_management_all_tasks" parent="menu_main_pm"
|
||||
action="action_view_all_task" sequence="2" groups="group_project_user"/>
|
||||
|
||||
<record id="project_task_action_from_partner" model="ir.actions.act_window">
|
||||
<field name="name">Tasks</field>
|
||||
|
||||
@@ -67,7 +67,7 @@ class ProjectTaskTypeDelete(models.TransientModel):
|
||||
elif self.env.context.get('stage_view'):
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("project.open_task_type_form")
|
||||
else:
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("project.action_view_all_task")
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("project.action_view_my_task")
|
||||
|
||||
context = action.get('context', '{}')
|
||||
context = context.replace('uid', str(self.env.uid))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
class ProjectMilestone(models.Model):
|
||||
_name = 'project.milestone'
|
||||
@@ -19,3 +19,13 @@ class ProjectMilestone(models.Model):
|
||||
@api.model
|
||||
def _get_fields_to_export(self):
|
||||
return super()._get_fields_to_export() + ['allow_billable', 'quantity_percentage', 'sale_line_name']
|
||||
|
||||
def action_view_sale_order(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Sales Order'),
|
||||
'res_model': 'sale.order',
|
||||
'res_id': self.sale_line_id.order_id.id,
|
||||
'view_mode': 'form',
|
||||
}
|
||||
|
||||
@@ -123,6 +123,13 @@
|
||||
<field name="quantity_percentage" groups="sales_team.group_sale_salesman" widget="percentage" readonly="0"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='%(project.action_view_task_from_milestone)d']" position="before">
|
||||
<button name="action_view_sale_order" type="object" class="oe_stat_button" icon="fa-dollar" attrs="{'invisible': [('sale_line_id', '=', False)]}">
|
||||
<div class="o_stat_info">
|
||||
<span class="o_stat_text">Sales Order</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -140,6 +147,10 @@
|
||||
<field name="quantity_percentage" optional="hide" widget="percentage" readonly="1" groups="!sales_team.group_sale_salesman"/>
|
||||
<field name="quantity_percentage" optional="hide" widget="percentage" groups="sales_team.group_sale_salesman"/>
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='action_view_tasks']" position="after">
|
||||
<button name="action_view_sale_order" type="object" string="View Sales Order"
|
||||
class="btn btn-link float-end" attrs="{'invisible': [('sale_line_id', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user