[IMP] project: improve globally the UX
The UX of the 4 main views (kanban, form, list, portal) of the project app has been globally improved. In particular, different icons color/style were changed along with several strings, and the order of a few elements was revised to improve readability. task-2508723 See odoo/enterprise#18387 closes odoo/odoo#71011 Related: odoo/upgrade#2506 Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
<field name="inherit_id" ref="project.project_project_view_form_simplified"/>
|
||||
<field name="priority">24</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="user_id" position="before">
|
||||
<field name="allow_timesheets"/>
|
||||
</field>
|
||||
</field>
|
||||
@@ -36,8 +36,8 @@
|
||||
<field name="inherit_id" ref="project.edit_project"/>
|
||||
<field name="priority">24</field>
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button class="oe_stat_button" name="%(act_hr_timesheet_line_by_project)d" type="action" icon="fa-calendar" attrs="{'invisible': [('allow_timesheets', '=', False)]}" groups="hr_timesheet.group_hr_timesheet_user">
|
||||
<xpath expr="//button[@name='%(project.project_milestone_all)d']" position="after">
|
||||
<button class="oe_stat_button" name="%(act_hr_timesheet_line_by_project)d" type="action" icon="fa-clock-o" attrs="{'invisible': [('allow_timesheets', '=', False)]}" groups="hr_timesheet.group_hr_timesheet_user">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<div class="oe_inline">
|
||||
<span class="o_stat_value mr-1">
|
||||
@@ -50,7 +50,7 @@
|
||||
<span class="o_stat_text">Recorded</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='rating_settings']" position="before">
|
||||
<div class="col-lg-6 o_setting_box" id="timesheet_settings">
|
||||
<div class="o_setting_left_pane">
|
||||
|
||||
@@ -15,7 +15,6 @@ This module adds a PAD in all project form views.
|
||||
'data': [
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/project_views.xml',
|
||||
'views/project_portal_templates.xml',
|
||||
],
|
||||
'auto_install': True,
|
||||
'assets': {
|
||||
|
||||
@@ -11,10 +11,6 @@ class ProjectTask(models.Model):
|
||||
|
||||
description_pad = fields.Char('Pad URL', pad_content_field='description', copy=False)
|
||||
use_pad = fields.Boolean(related="project_id.use_pads", string="Use collaborative pad", readonly=True)
|
||||
pad_availability = fields.Selection(
|
||||
related="project_id.pad_availability",
|
||||
string="Availability of collaborative pads",
|
||||
readonly=True)
|
||||
|
||||
@api.onchange('use_pad')
|
||||
def _onchange_use_pads(self):
|
||||
@@ -36,14 +32,6 @@ class ProjectTask(models.Model):
|
||||
self = self.with_context(pad_no_create=True)
|
||||
return super(ProjectTask, self).create(vals)
|
||||
|
||||
def _use_portal_pad(self):
|
||||
"""
|
||||
Indicates if the task configuration requires to provide
|
||||
an access to a portal pad.
|
||||
"""
|
||||
self.ensure_one()
|
||||
return self.use_pad and self.pad_availability == 'portal'
|
||||
|
||||
def _get_pad_content(self):
|
||||
"""
|
||||
Gets the content of the pad used to edit the task description
|
||||
@@ -61,15 +49,3 @@ class ProjectProject(models.Model):
|
||||
description_pad = fields.Char('Pad URL', pad_content_field='description', copy=False)
|
||||
use_pads = fields.Boolean("Use collaborative pads", default=True,
|
||||
help="Use collaborative pad for the tasks on this project.")
|
||||
|
||||
pad_availability = fields.Selection([
|
||||
('internal', 'Internal Users'),
|
||||
('portal', 'Internal Users & Portal Users')
|
||||
], compute='_compute_pad_availability', store=True, readonly=False,
|
||||
string='Availability of collaborative pads', required=True, default='internal')
|
||||
|
||||
@api.depends('use_pads', 'privacy_visibility')
|
||||
def _compute_pad_availability(self):
|
||||
for project in self:
|
||||
if project.privacy_visibility != 'portal' or not project.use_pads:
|
||||
project.pad_availability = 'internal'
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="portal_my_task" inherit_id="project.portal_my_task" priority="40">
|
||||
|
||||
<!-- add a button to the right of the 'description' title according to the mode (edit/read) -->
|
||||
<xpath expr="//div[@t-if='task.description']//div[hasclass('d-flex')]" position="inside">
|
||||
<t t-if="task._use_portal_pad()">
|
||||
<t t-if="request.params.get('edit')">
|
||||
<a role="button" class="btn btn-primary btn-sm ml-auto" t-attf-href="/my/task/#{task.id}">Save</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<a role="button" class="btn btn-primary btn-sm ml-auto" t-attf-href="/my/task/#{task.id}?edit=1">Edit</a>
|
||||
</t>
|
||||
</t>
|
||||
</xpath>
|
||||
|
||||
<!-- show the description (read mode) or a pad (edit mode) -->
|
||||
<xpath expr="//div[@t-field='task.description']" position="replace">
|
||||
<t t-if="task._use_portal_pad()">
|
||||
<t t-if="request.params.get('edit')">
|
||||
<div class="o_pad_project_container">
|
||||
<iframe width="100%" height="100%" frameborder="0" t-att-src="task.description_pad + '?showChat=false&userName=' + request.env.user.name"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="py-1 px-2 bg-100 small" t-esc="task._get_pad_content()"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t>$0</t>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -31,12 +31,6 @@
|
||||
Edit tasks' description collaboratively in real time.<br/>
|
||||
See each author's text in a distinct color.
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': ['|', ('use_pads', '=', False), ('privacy_visibility', '!=', 'portal')]}">
|
||||
<div class="mt16 row">
|
||||
<label for="pad_availability" string="Available to:" class="col-3 col-lg-3 o_light_label"/>
|
||||
<field name="pad_availability" widget="radio"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
|
||||
@@ -210,18 +210,19 @@ class Project(models.Model):
|
||||
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True,
|
||||
help="Internal email associated with this project. Incoming emails are automatically synchronized "
|
||||
"with Tasks (or optionally Issues if the Issue Tracker module is installed).")
|
||||
alias_value = fields.Char(string='Alias email', compute='_compute_alias_value')
|
||||
privacy_visibility = fields.Selection([
|
||||
('followers', 'Invited employees'),
|
||||
('employees', 'All employees'),
|
||||
('portal', 'Portal users and all employees'),
|
||||
('portal', 'Invited portal users and all employees'),
|
||||
],
|
||||
string='Visibility', required=True,
|
||||
default='portal',
|
||||
help="Defines the visibility of the tasks of the project:\n"
|
||||
"- Invited employees: employees may only see the followed project and tasks.\n"
|
||||
"- All employees: employees may see all project and tasks.\n"
|
||||
"- Portal users and all employees: employees may see everything."
|
||||
" Portal users may see project and tasks followed by.\n"
|
||||
"- Invited portal users and all employees: employees may see everything."
|
||||
" Invited portal users may see project and tasks followed by.\n"
|
||||
" them or by someone of their company.")
|
||||
doc_count = fields.Integer(compute='_compute_attached_docs_count', string="Number of documents attached")
|
||||
date_start = fields.Date(string='Start Date')
|
||||
@@ -330,6 +331,14 @@ class Project(models.Model):
|
||||
for project in self:
|
||||
project.milestone_count = mapped_count.get(project.id, 0)
|
||||
|
||||
@api.depends('alias_name', 'alias_domain')
|
||||
def _compute_alias_value(self):
|
||||
for project in self:
|
||||
if not project.alias_name or not project.alias_domain:
|
||||
project.alias_value = ''
|
||||
else:
|
||||
project.alias_value = "%s@%s" % (project.alias_name, project.alias_domain)
|
||||
|
||||
@api.model
|
||||
def _map_tasks_default_valeus(self, task, project):
|
||||
""" get the default value for the copied task on project duplication """
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 5px;
|
||||
|
||||
&:first-child {
|
||||
margin: 0 5px 0 0;
|
||||
padding-left: 12px
|
||||
}
|
||||
|
||||
.o_value {
|
||||
font-weight: 800;
|
||||
}
|
||||
@@ -46,6 +51,15 @@
|
||||
top: 15%;
|
||||
}
|
||||
}
|
||||
|
||||
.o_kanban_record {
|
||||
div[name="is_favorite"] .fa-star-o {
|
||||
visibility: hidden;
|
||||
}
|
||||
&:hover div[name="is_favorite"] .fa-star-o {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_dow_widget {
|
||||
|
||||
@@ -87,25 +87,29 @@
|
||||
</t>
|
||||
<t t-set="card_body">
|
||||
<div class="row">
|
||||
<div t-if="project.partner_id" class="col-12 col-md-6 mb-2 mb-md-0">
|
||||
<h6>Customer</h6>
|
||||
<div class="row">
|
||||
<div class="col flex-grow-0 pr-3">
|
||||
<img class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(project.partner_id.avatar_1024)" alt="Contact"/>
|
||||
</div>
|
||||
<div class="col pl-sm-0">
|
||||
<address t-field="project.partner_id" t-options='{"widget": "contact", "fields": ["name", "email", "phone"]}'/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="project.user_id" class="col-12 col-md-6">
|
||||
<h6>Project Manager</h6>
|
||||
<h6><strong> Project Manager </strong></h6>
|
||||
<div class="row">
|
||||
<div class="col flex-grow-0 pr-3">
|
||||
<img class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(project.user_id.avatar_1024)" alt="Contact"/>
|
||||
</div>
|
||||
<div class="col pl-sm-0">
|
||||
<address t-field="project.user_id" t-options='{"widget": "contact", "fields": ["name", "email", "phone"]}'/>
|
||||
<div t-field="project.user_id" t-options='{"widget": "contact", "fields": ["name"]}'/>
|
||||
<a t-attf-href="mailto:{{project.user_id.email}}" t-if="project.user_id.email"><div t-field="project.user_id" t-options='{"widget": "contact", "fields": ["email"]}'/></a>
|
||||
<a t-attf-href="tel:{{project.user_id.phone}}" t-if="project.user_id.phone"><div t-field="project.user_id" t-options='{"widget": "contact", "fields": ["phone"]}'/></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="project.partner_id" class="col-12 col-md-6 mb-2 mb-md-0">
|
||||
<h6><strong> Customer </strong></h6>
|
||||
<div class="row">
|
||||
<div class="col flex-grow-0 pr-3">
|
||||
<img class="rounded-circle mt-1 o_portal_contact_img" t-att-src="image_data_uri(project.partner_id.avatar_1024)" alt="Contact"/>
|
||||
</div>
|
||||
<div class="col pl-sm-0">
|
||||
<div t-field="project.partner_id" t-options='{"widget": "contact", "fields": ["name"]}'/>
|
||||
<a t-attf-href="mailto:{{project.partner_email}}" t-if="project.partner_email"><div t-field="project.partner_id" t-options='{"widget": "contact", "fields": ["email"]}'/></a>
|
||||
<a t-attf-href="tel:{{project.partner_phone}}" t-if="project.partner_phone"><div t-field="project.partner_id" t-options='{"widget": "contact", "fields": ["phone"]}'/></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -246,6 +246,16 @@
|
||||
name="%(act_project_project_2_project_task_all)d" icon="fa-tasks">
|
||||
<field string="Tasks In Progress" name="task_count" widget="statinfo" options="{'label_field': 'label_tasks'}"/>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="%(project.project_milestone_all)d" type="action" icon="fa-check-square-o">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
<field name="milestone_count" nolabel="1"/>
|
||||
</span>
|
||||
<span class="o_stat_text">
|
||||
Milestones
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_view_all_rating" type="object" attrs="{'invisible': ['|', ('rating_active', '=', False), ('rating_percentage_satisfaction', '=', -1)]}" class="oe_stat_button oe_read_only" icon="fa-smile-o" groups="project.group_project_rating">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
@@ -274,16 +284,6 @@
|
||||
<field name="last_update_status" widget="status_with_color" options="{'color_field': 'last_update_color', 'no_quick_edit': 1}"/>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button" name="%(project.project_milestone_all)d" type="action" icon="fa-check-square-o">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value">
|
||||
<field name="milestone_count" nolabel="1"/>
|
||||
</span>
|
||||
<span class="o_stat_text">
|
||||
Milestones
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<div class="oe_title">
|
||||
@@ -306,26 +306,18 @@
|
||||
<field name="date" string="Deadline"/>
|
||||
<div name="alias_def" colspan="2" attrs="{'invisible': [('alias_domain', '=', False)]}">
|
||||
<!-- Always display the whole alias in edit mode. It depends in read only -->
|
||||
<label for="alias_enabled" class="font-weight-bold" string="Create tasks by sending an email"/>
|
||||
<field name="alias_enabled" invisible="1"/>
|
||||
<span>
|
||||
<span class="font-weight-bold oe_read_only" attrs="{'invisible': [('alias_name', '=', False)]}">to </span>
|
||||
<span class="font-weight-bold oe_edit_only">to </span>
|
||||
<field name="alias_name" class="oe_inline"/>
|
||||
<span class="oe_read_only" attrs="{'invisible': [('alias_name', '=', False)]}">@</span>
|
||||
<span class="oe_edit_only">@</span>
|
||||
<field name="alias_domain"
|
||||
attrs="{'invisible': [('alias_name', '=', False)]}"
|
||||
class="oe_inline oe_read_only"
|
||||
readonly="1"/>
|
||||
<field name="alias_domain"
|
||||
class="oe_inline oe_edit_only"
|
||||
readonly="1"/>
|
||||
</span>
|
||||
<span class="font-weight-bold oe_read_only" attrs="{'invisible': [('alias_name', '=', False)]}">Create tasks by sending an email to </span>
|
||||
<span class="font-weight-bold oe_edit_only">Create tasks by sending an email to </span>
|
||||
<field name="alias_value" class="oe_read_only d-inline" readonly="1" widget="email" attrs="{'invisible': [('alias_name', '=', False)]}" />
|
||||
<span class="oe_edit_only">
|
||||
<field name="alias_name" class="oe_inline"/>@
|
||||
<field name="alias_domain" class="oe_inline" readonly="1"/>
|
||||
</span>
|
||||
</div>
|
||||
<!-- the alias contact must appear when the user start typing and it must disappear
|
||||
when the string is deleted. -->
|
||||
<field name="alias_contact" class="oe_inline oe_edit_only" string="Accept Emails From"
|
||||
<field name="alias_contact" class="oe_inline" string="Accept Emails From"
|
||||
attrs="{'invisible': ['|', ('alias_name', '=', ''), ('alias_name', '=', False)]}"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -413,6 +405,7 @@
|
||||
<field name="name" string="Project"/>
|
||||
<field name="user_id" string="Project Manager"/>
|
||||
<field name="partner_id" string="Customer" filter_domain="[('partner_id', 'child_of', self)]"/>
|
||||
<field name="analytic_account_id"/>
|
||||
<filter string="My Favorites" name="my_projects" domain="[('favorite_user_ids', 'in', uid)]"/>
|
||||
<separator/>
|
||||
<filter string="Followed" name="followed_by_me" domain="[('message_is_follower', '=', True)]"/>
|
||||
@@ -437,13 +430,12 @@
|
||||
<field name="message_needaction" invisible="1"/>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="name" string="Name" class="font-weight-bold"/>
|
||||
<field name="user_id" optional="show" string="Project Manager" widget="many2one_avatar_user"/>
|
||||
<field name="partner_id" optional="show" string="Customer"/>
|
||||
<field name="analytic_account_id" optional="hide" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="privacy_visibility" optional="hide"/>
|
||||
<field name="label_tasks" optional="hide"/>
|
||||
<field name="company_id" optional="show" groups="base.group_multi_company"/>
|
||||
<field name="date" string="Deadline" widget="remaining_days" optional="show"/>
|
||||
<field name="company_id" optional="show" groups="base.group_multi_company" options="{'no_create': True, 'no_create_edit': True}"/>
|
||||
<field name="analytic_account_id" optional="hide" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="date" optional="hide" string="Deadline" widget="remaining_days"/>
|
||||
<field name="user_id" optional="show" string="Project Manager" widget="many2one_avatar_user" options="{'no_open':True, 'no_create': True, 'no_create_edit': True}"/>
|
||||
<field name="last_update_color" invisible="1"/>
|
||||
<field name="last_update_status" string="Status" optional="show" widget="status_with_color" options="{'color_field': 'last_update_color'}"/>
|
||||
</tree>
|
||||
@@ -490,7 +482,6 @@
|
||||
<field name="name" class="o_project_name oe_inline"
|
||||
string="Project Name" placeholder="e.g. Office Party"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="allow_recurring_tasks" groups="project.group_project_recurring_tasks" />
|
||||
</group>
|
||||
<div name="alias_def" colspan="2" attrs="{'invisible': [('alias_domain', '=', False)]}">
|
||||
<label for="alias_name" class="oe_inline" string="Create tasks by sending an email to"/>
|
||||
@@ -524,6 +515,7 @@
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="project_project_view_form_simplified_footer"/>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{"default_allow_billable": 1}</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_project_kanban">
|
||||
@@ -552,30 +544,28 @@
|
||||
<field name="last_update_status"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click o_has_icon oe_kanban_content">
|
||||
<div t-attf-class="#{kanban_color(record.color.raw_value)} oe_kanban_global_click o_has_icon oe_kanban_content oe_kanban_card">
|
||||
<div class="o_project_kanban_main ">
|
||||
<div class="o_kanban_card_content mw-100">
|
||||
<div class="o_kanban_primary_left">
|
||||
<div class="o_primary">
|
||||
<span class="o_text_overflow"><t t-esc="record.name.value"/></span>
|
||||
<span class="o_text_overflow" t-if="record.partner_id.value">
|
||||
<strong><t t-esc="record.commercial_partner_id.value"/></strong>
|
||||
<span class="o_text_overflow text-muted" t-if="record.partner_id.value">
|
||||
<span class="fa fa-user mr-2" aria-label="Partner" title="Partner"></span><t t-esc="record.partner_id.value"/>
|
||||
</span>
|
||||
<div t-if="record.date.raw_value">
|
||||
<field name="date" widget="remaining_days"/>
|
||||
<div t-if="record.date.raw_value" class="text-muted">
|
||||
<span class="fa fa-clock-o mr-2" aria-label="Remaining days" title="Remaining days"></span><field name="date" widget="remaining_days"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="record.alias_name.value and record.alias_domain.value">
|
||||
<span><i class="fa fa-envelope" role="img" aria-label="Domain Alias" title="Domain Alias"></i> <a t-att-href="'mailto:' + record.alias_id.value" title="Send an email"><t t-esc="record.alias_id.value"/></a></span>
|
||||
</div>
|
||||
<div t-if="record.rating_active.raw_value" class="text-primary" title="Percentage of happy ratings over the past 30 days." groups="project.group_project_rating">
|
||||
<b>
|
||||
<a name="action_view_all_rating" type="object" context="{'search_default_rating_last_30_days':1}">
|
||||
<div t-if="record.alias_name.value and record.alias_domain.value" class="text-muted">
|
||||
<span class="fa fa-envelope-o mr-2" aria-label="Domain Alias" title="Domain Alias"></span><t t-esc="record.alias_id.value"/>
|
||||
</div>
|
||||
<div t-if="record.rating_active.raw_value" class="text-muted" title="Percentage of happy ratings over the past 30 days." groups="project.group_project_rating">
|
||||
<b>
|
||||
<t t-if="record.rating_percentage_satisfaction.value != -1">
|
||||
<i class="fa fa-smile-o" role="img" aria-label="Percentage of satisfaction" title="Percentage of satisfaction"/> <t t-esc="record.rating_percentage_satisfaction.value"/>%
|
||||
</t>
|
||||
</a>
|
||||
</b>
|
||||
</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -614,10 +604,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="o_kanban_manage_toggle_button o_left" href="#" groups="base.group_user"><i class="fa fa-ellipsis-v" role="img" aria-label="Manage" title="Manage"/></a>
|
||||
<span class="o_right"><field name="is_favorite" widget="boolean_favorite" nolabel="1" force_save="1" /></span>
|
||||
<a class="o_kanban_manage_toggle_button o_dropdown_kanban" href="#" groups="base.group_user">
|
||||
<i class="fa fa-ellipsis-v" role="img" aria-label="Manage" title="Manage"/>
|
||||
</a>
|
||||
<span>
|
||||
<field name="is_favorite" widget="boolean_favorite" nolabel="1" force_save="1" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="o_kanban_record_bottom mt-3">
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<div class="o_project_kanban_boxes">
|
||||
<a class="o_project_kanban_box" name="action_view_tasks" type="object">
|
||||
@@ -651,7 +645,7 @@
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found. Let's create one!
|
||||
</p><p>
|
||||
Projects regroup tasks on the same topic and each have their own dashboard.
|
||||
Projects regroup tasks on the same topic, and each has its dashboard.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
@@ -670,7 +664,7 @@
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No projects found. Let's create one!
|
||||
</p><p>
|
||||
Projects regroup tasks on the same topic and each have their own dashboard.
|
||||
Projects regroup tasks on the same topic, and each has its dashboard.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="project_project_view_inherit_project_filter" model="ir.ui.view">
|
||||
<field name="name">project.project.select.inherit.project</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project_project_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="sale_order_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="project_project_view_tree_inherit_sale_project" model="ir.ui.view">
|
||||
<field name="name">project.project.tree.inherit.sale.project</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="project.view_project"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='analytic_account_id']" position="after">
|
||||
<field name="sale_order_id" optional="hide" widget="sale_order_many2one"/>
|
||||
<xpath expr="//field[@name='partner_id']" position="after">
|
||||
<field name="sale_line_id" optional="hide" widget="sale_order_many2one" readonly="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
||||
@@ -60,11 +60,7 @@ tour.register('sale_timesheet_tour', {
|
||||
run: function (actions) {
|
||||
actions.text('Project for Freeman', this.$anchor);
|
||||
},
|
||||
}, {
|
||||
trigger: 'div[name="allow_billable"] input',
|
||||
content: 'Click on the checkbox to have a billable project.',
|
||||
run: 'click',
|
||||
}, {
|
||||
}, {
|
||||
trigger: 'button[name="action_view_tasks"]',
|
||||
content: 'Click on Create button to create and enter to this newest project.',
|
||||
run: 'click',
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="hr_timesheet.project_invoice_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div class="oe_button_box" position="inside">
|
||||
<button string="Project Overview" class="oe_stat_button" type="object" name="action_view_timesheet" icon="fa-puzzle-piece" attrs="{'invisible': [('allow_billable', '=', False)]}" groups="project.group_project_manager"/>
|
||||
<xpath expr="//button[@name='%(project.action_project_task_burndown_chart_report)d']" position="after">
|
||||
<button string="Costs / Revenues" class="oe_stat_button" type="object" name="action_view_timesheet" icon="fa-puzzle-piece" attrs="{'invisible': [('allow_billable', '=', False)]}" groups="project.group_project_manager"/>
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='%(project.act_project_project_2_project_task_all)d']" position="before">
|
||||
<button class="d-none d-md-inline oe_stat_button"
|
||||
type="object" name="action_view_so" icon="fa-dollar"
|
||||
attrs="{'invisible': ['|', ('allow_billable', '=', False), ('sale_order_id', '=', False)]}"
|
||||
string="Sales Order"
|
||||
groups="sales_team.group_sale_salesman_all_leads"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//header" position="inside">
|
||||
<button name="action_make_billable" string="Create Sales Order" type="object" attrs="{'invisible': [('display_create_order', '=', False)]}" groups="sales_team.group_sale_salesman"/>
|
||||
</xpath>
|
||||
@@ -73,7 +75,7 @@
|
||||
<field name="model">project.project</field>
|
||||
<field name="inherit_id" ref="hr_timesheet.project_project_view_form_simplified_inherit_timesheet"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="allow_timesheets" position="after">
|
||||
<field name="allow_timesheets" position="before">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="allow_billable"/>
|
||||
</field>
|
||||
@@ -92,9 +94,11 @@
|
||||
<field name="pricing_type" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_kanban_manage_reporting')]" position="inside">
|
||||
<div t-if="record.allow_timesheets.raw_value and record.allow_billable.raw_value" role="menuitem" groups="project.group_project_manager">
|
||||
<a name="action_view_timesheet" type="object">Costs / Revenues</a>
|
||||
</div>
|
||||
<div role="menuitem" groups="project.group_project_manager">
|
||||
<a name="action_view_all_rating" type="object" context="{'search_default_rating_last_30_days':1}">
|
||||
Customer Ratings
|
||||
</a>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('o_kanban_manage_view')]" position="inside">
|
||||
<div t-if="record.allow_billable.raw_value and record.sale_order_id.raw_value and record.pricing_type.raw_value != 'task_rate'"
|
||||
@@ -202,5 +206,4 @@
|
||||
<field name="res_model">project.project</field>
|
||||
<field name="view_mode">qweb</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user