Files
odoo_source/addons/project/views/project_sharing_project_task_views.xml
T
Audric Onockx (auon) fb88a7448c [IMP] project,_*: allow all project features on tasks w/o project
_*: hr_timesheet,sale_project,sale_timesheet
Generally, you don't want subtasks to be displayed at the same level
as their parent tasks. You want to consider the subtasks as part of
their parent's project, but don't want to see them directly in this
project. Rather, you want them to be accessible only via their parent.
(There are exceptions to that and we want to stay flexible.)

First solution that comes to mind is to have `project_id` set to False
for the latter tasks, but then how to get the value of the fields that
are related to the project?

So, second solution would be to have a field `project_root_id`,
which would be the project of the parent, or the grand-parent, etc.
The issue now is that we have to fields "project", and it isn't obvious
when to use one or the other.

The most simple way to answer this need is to keep one field "project",
that will always be set for (non-private) tasks,
and create a boolean field : `display_in_project`.
But we want it to be technical (no checkbox in the view).
So, when the user unsets the project on a subtask, the view will act
as if the project was unset, but in the back-end,
we'll set `display_in_project` to False and set `project_id` back.

The fact that all tasks have a project allows us to know if action x
can be perform on this task t, dependind on t.project_id.allow_x.

task-3367246

closes odoo/odoo#128281

Related: odoo/enterprise#43996
Related: odoo/upgrade#4930
Signed-off-by: Xavier Bol (xbo) <xbo@odoo.com>
2023-07-20 13:06:46 +02:00

300 lines
18 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="project_sharing_quick_create_task_form" model="ir.ui.view">
<field name="name">project.task.form.quick_create</field>
<field name="model">project.task</field>
<field name="priority">999</field>
<field name="groups_id" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="arch" type="xml">
<form>
<group>
<field name="name" string="Task Title" placeholder="e.g. Send Invitations"/>
</group>
</form>
</field>
</record>
<record id="project_sharing_project_task_view_kanban" model="ir.ui.view">
<field name="name">project.sharing.project.task.view.kanban</field>
<field name="model">project.task</field>
<field name="priority">999</field>
<field name="groups_id" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="arch" type="xml">
<kanban
class="o_kanban_small_column o_kanban_project_tasks"
default_group_by="stage_id"
on_create="quick_create"
quick_create_view="project.project_sharing_quick_create_task_form"
archivable="0"
import="0"
groups_draggable="0"
>
<field name="color"/>
<field name="priority"/>
<field name="stage_id" options='{"group_by_tooltip": {"description": "Description"}}'/>
<field name="portal_user_names"/>
<field name="partner_id"/>
<field name="sequence"/>
<field name="state"/>
<field name="displayed_image_id"/>
<field name="active"/>
<field name="closed_subtask_count"/>
<field name="subtask_count"/>
<field name="allow_milestones" />
<field name="has_late_and_unreached_milestone"/>
<progressbar field="state" colors='{"1_done": "success", "03_approved": "success", "02_changes_requested": "warning", "1_canceled": "danger", "04_waiting_normal": "200", "01_in_progress": "200"}'/>
<templates>
<t t-name="kanban-menu" t-if="!selection_mode">
<div role="separator" class="dropdown-divider"></div>
<ul class="oe_kanban_colorpicker" data-field="color"/>
</t>
<t t-name="kanban-box">
<div t-attf-class="{{!selection_mode ? 'oe_kanban_color_' + kanban_getcolor(record.color.raw_value) : ''}} oe_kanban_card oe_kanban_global_click">
<div class="oe_kanban_content">
<div class="o_kanban_record_top">
<div class="o_kanban_record_headings">
<strong class="o_kanban_record_title">
<s t-if="!record.active.raw_value"><field name="name" widget="name_with_subtask_count"/></s>
<t t-else=""><field name="name" widget="name_with_subtask_count"/></t>
</strong>
<span invisible="context.get('default_project_id', False)"><br/><field name="project_id" required="1"/></span>
<span t-if="record.allow_milestones.raw_value and record.milestone_id.raw_value" t-attf-class="{{record.has_late_and_unreached_milestone.raw_value and !record.state.raw_value.startsWith('1_') ? 'text-danger' : ''}}">
<br/>
<field name="milestone_id" />
</span>
<br />
<t t-if="record.partner_id.value">
<field name="partner_id"/>
</t>
</div>
</div>
<div class="o_kanban_record_body">
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" context="{'project_id': project_id}"/>
<div t-if="record.date_deadline.raw_value" name="date_deadline" attrs="{'invisible': [('state', 'in', ['1_done','1_canceled'])]}">
<field name="date_deadline" widget="remaining_days"/>
</div>
<div t-if="record.displayed_image_id.value" groups="base.group_user">
<field name="displayed_image_id" widget="attachment_image"/>
</div>
</div>
<div class="o_kanban_record_bottom" t-if="!selection_mode">
<div class="oe_kanban_bottom_left">
<field name="priority" widget="priority"/>
</div>
<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-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="state" widget="project_task_state_selection" options="{'is_toggle_mode': false}"/>
</div>
</div>
</div>
<div class="clearfix"></div>
</div>
</t>
</templates>
</kanban>
</field>
</record>
<record id="project_sharing_project_task_view_tree" model="ir.ui.view">
<field name="name">project.sharing.project.task.tree</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project_task_view_tree_main_base"/>
<field name="mode">primary</field>
<field name="priority">999</field>
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="delete">0</attribute>
<attribute name="import">0</attribute>
</tree>
<field name="user_ids" position="replace">
<field name="portal_user_names" string="Assignees"/>
</field>
</field>
</record>
<record id="project_sharing_project_task_view_form" model="ir.ui.view">
<field name="name">project.sharing.project.task.view.form</field>
<field name="model">project.task</field>
<field name="priority">999</field>
<field name="groups_id" eval="[(4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="arch" type="xml">
<form string="Project Sharing: Task" class="o_form_project_tasks">
<header>
<field name="stage_id" widget="statusbar" options="{'clickable': '1', 'fold_field': 'fold'}" attrs="{'invisible': [('project_id', '=', False), ('stage_id', '=', False)]}" />
</header>
<div groups="base.group_user" role="status" class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_editable_mode_hidden">
<div class="text-center">This is a preview of how the project will look when it's shared with customers and they have editing access.
<a name="action_redirect_to_project_task_form" type="object"><i class="oi oi-arrow-right me-1"/>Back to edit mode</a>
</div>
</div>
<sheet string="Task">
<div class="oe_button_box" name="button_box">
<field name="display_parent_task_button" invisible="1"/>
<button name="action_project_sharing_view_parent_task" type="object" class="oe_stat_button" icon="fa-tasks" attrs="{'invisible': [('display_parent_task_button', '=', False)]}">
<div class="o_stat_info">
<span class="o_stat_text">Parent Task</span>
</div>
</button>
<button name="action_project_sharing_open_subtasks" type="object" class="oe_stat_button" icon="fa-tasks"
attrs="{'invisible' : ['|', ('id', '=', False), ('subtask_count', '=', 0)]}" context="{'default_user_ids': [(6, 0, [uid])]}">
<field name="subtask_count" widget="statinfo" string="Sub-tasks"/>
</button>
</div>
<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<div class="oe_title pe-0">
<h1 class="d-flex flex-row justify-content-between">
<field name="priority" widget="priority" class="me-3"/>
<field name="name" class="o_task_name text-truncate" placeholder="Task Title..."/>
<field name="state" widget="project_task_state_selection" options="{'is_toggle_mode': false}"/>
</h1>
</div>
<group>
<group>
<field name="project_id" invisible="1"/>
<field name="allow_milestones" invisible="1"/>
<field name="milestone_id"
placeholder="e.g. Product Launch"
context="{'default_project_id': project_id}"
attrs="{'invisible': [('allow_milestones', '=', False)]}"
options="{'no_open': True, 'no_create': True, 'no_edit': True}"
/>
<field name="user_ids" invisible="1" />
<field name="portal_user_names"
string="Assignees"
class="o_task_user_field"/>
<field name="tag_ids" context="{'project_id': project_id}" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True, 'no_edit_color': True}"/>
</group>
<group>
<field name="active" invisible="1"/>
<field name="parent_id" invisible="1" />
<field name="company_id" invisible="1" />
<field name="state" invisible="1" />
<field name="partner_id" options="{'no_open': True, 'no_create': True, 'no_edit': True}" attrs="{'invisible': [('project_id', '=', False)]}"/>
<field name="date_deadline" attrs="{'invisible': [('state', 'in', ['1_done','1_canceled'])]}"/>
</group>
</group>
<notebook>
<page name="description_page" string="Description">
<field name="description" type="html" options="{'collaborative': true}"/>
</page>
<page name="sub_tasks_page" string="Sub-tasks">
<field name="child_ids" context="{'default_parent_id': id, 'default_partner_id': partner_id, 'form_view_ref' : 'project.project_sharing_project_task_view_form'}">
<tree editable="bottom">
<field name="project_id" invisible="1"/>
<field name="state" invisible="1"/>
<field name="sequence" widget="handle"/>
<field name="priority" widget="priority" optional="show" nolabel="1"/>
<field name="state" widget="project_task_state_selection" nolabel="1"/>
<field name="name"/>
<field name="allow_milestones" invisible="1"/>
<field name="milestone_id"
optional="hide"
context="{'default_project_id': project_id}"
attrs="{'invisible': [('allow_milestones', '=', False)], 'column_invisible': [('parent.allow_milestones', '=', False)]}"
/>
<field name="company_id" invisible="1"/>
<field name="partner_id" options="{'no_open': True, 'no_create': True, 'no_edit': True}" optional="hide" attrs="{'invisible': [('project_id', '=', False)]}"/>
<field name="user_ids" invisible="1" />
<field name="portal_user_names" string="Assignees" optional="show"/>
<field name="date_deadline" attrs="{'invisible': [('state', 'in', ['1_done','1_canceled'])]}" optional="show"/>
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="hide"/>
<field name="stage_id" optional="show"/>
<button name="action_open_task" type="object" title="View Task" string="View Task" class="btn btn-link float-end"
context="{'form_view_ref': 'project.project_sharing_project_task_view_form', 'search_view_ref': 'project.project_sharing_project_task_view_search'}"
attrs="{'invisible': &quot;['|', ('project_id', '!=', False), ('project_id', '!=', active_id)]&quot;}"/>
</tree>
</field>
</page>
</notebook>
</sheet>
<div class="oe_chatter"/>
</form>
</field>
</record>
<record id="project_sharing_project_task_view_search" model="ir.ui.view">
<field name="name">project.task.search.form</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_task_search_form_project_base"/>
<field name="mode">primary</field>
<field name="priority">999</field>
<field name="arch" type="xml">
<search position="inside"/>
</field>
</record>
<record id="project_sharing_project_task_action" model="ir.actions.act_window">
<field name="name">Project Sharing</field>
<field name="res_model">project.task</field>
<field name="view_mode">kanban,tree,form</field>
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
<field name="domain">[('project_id', '=', active_id), ('display_in_project', '=', True)]</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No tasks found. Let's create one!
</p>
<p>
Keep track of the progress of your tasks from creation to completion.<br/>
Collaborate efficiently by chatting in real-time or via email.
</p>
</field>
</record>
<record id="project_sharing_kanban_action_view" model="ir.actions.act_window.view">
<field name="view_mode">kanban</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action"/>
<field name="view_id" ref="project.project_sharing_project_task_view_kanban"/>
</record>
<record id="project_sharing_tree_action_view" model="ir.actions.act_window.view">
<field name="view_mode">tree</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action"/>
<field name="view_id" ref="project.project_sharing_project_task_view_tree"/>
</record>
<record id="project_sharing_form_action_view" model="ir.actions.act_window.view">
<field name="view_mode">form</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action"/>
<field name="view_id" ref="project.project_sharing_project_task_view_form"/>
</record>
<record id="project_sharing_project_task_action_sub_task" model="ir.actions.act_window">
<field name="name">Sub-tasks</field>
<field name="res_model">project.task</field>
<field name="view_mode">tree,kanban,form</field>
<field name="search_view_id" ref="project.project_sharing_project_task_view_search"/>
<field name="domain">[('id', 'child_of', active_id), ('id', '!=', active_id)]</field>
<field name="context">{'default_parent_id': active_id}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
No tasks found. Let's create one!
</p><p>
To get things done, use activities and status on tasks.<br/>
Chat in real time or by email to collaborate efficiently.
</p>
</field>
</record>
<record id="project_sharing_subtasks_tree_action_view" model="ir.actions.act_window.view">
<field name="view_mode">tree</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action_sub_task"/>
<field name="view_id" ref="project.project_sharing_project_task_view_tree"/>
</record>
<record id="project_sharing_subtasks_kanban_action_view" model="ir.actions.act_window.view">
<field name="view_mode">kanban</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action_sub_task"/>
<field name="view_id" ref="project.project_sharing_project_task_view_kanban"/>
</record>
<record id="project_sharing_subtasks_form_action_view" model="ir.actions.act_window.view">
<field name="view_mode">form</field>
<field name="act_window_id" ref="project.project_sharing_project_task_action_sub_task"/>
<field name="view_id" ref="project.project_sharing_project_task_view_form"/>
</record>
</odoo>