[IMP] project: kanban customization
authorThibault Delavallée <tde@openerp.com>
Fri, 31 Oct 2014 13:02:40 +0000 (14:02 +0100)
committerThibault Delavallée <tde@openerp.com>
Thu, 13 Nov 2014 10:31:39 +0000 (11:31 +0100)
- stage model (project.task.type): add fields holding the eventual specific
legends for kanban states and star (priority) management
- project: task now have labels; you may use project to hold trainings
instead of tasks.
- project form: use label field on tasks statinfo to use the label
- project.task form: use kanban state customization using states_legend option;
- project.task kanban: use kanban column and kanban state cuztomization
using group_by_tooltip and states_legend options
- project_issue: issues now have labels, like tasks.
- issue: same kanban custo as for tasks
- update data and demo data

[IMP] web: statinfo widget now take an optional label_field option allowing
to have strings coming from another field present in the form view

addons/project/project.py
addons/project/project_data.xml
addons/project/project_demo.xml
addons/project/project_view.xml
addons/project_issue/project_issue.py
addons/project_issue/project_issue_demo.xml
addons/project_issue/project_issue_view.xml
addons/web/static/src/js/view_form.js

index 1e4c917..a83962e 100644 (file)
@@ -44,6 +44,18 @@ class project_task_type(osv.osv):
         'case_default': fields.boolean('Default for New Projects',
                         help="If you check this field, this stage will be proposed by default on each new project. It will not assign this stage to existing projects."),
         'project_ids': fields.many2many('project.project', 'project_task_type_rel', 'type_id', 'project_id', 'Projects'),
+        'legend_priority': fields.text(
+            'Priority Management Explanation', translate=True,
+            help='Explanation text to help users using the star and priority mechanism on stages or issues that are in this stage.'),
+        'legend_blocked': fields.char(
+            'Kanban Blocked Explanation', translate=True,
+            help='Override the default value displayed for the blocked state for kanban selection, when the task or issue is in that stage.'),
+        'legend_done': fields.char(
+            'Kanban Valid Explanation', translate=True,
+            help='Override the default value displayed for the done state for kanban selection, when the task or issue is in that stage.'),
+        'legend_normal': fields.char(
+            'Kanban Ongoing Explanation', translate=True,
+            help='Override the default value displayed for the normal state for kanban selection, when the task or issue is in that stage.'),
         'fold': fields.boolean('Folded in Kanban View',
                                help='This stage is folded in the kanban view when'
                                'there are no records in that stage to display.'),
@@ -280,6 +292,7 @@ class project(osv.osv):
             help="Link this project to an analytic account if you need financial management on projects. "
                  "It enables you to connect projects with budgets, planning, cost and revenue analysis, timesheets on projects, etc.",
             ondelete="cascade", required=True, auto_join=True),
+        'label_tasks': fields.char('Use Tasks as', help="Gives label to tasks on project's kanaban view."),
         'members': fields.many2many('res.users', 'project_user_rel', 'project_id', 'uid', 'Project Members',
             help="Project's members are users who can have an access to the tasks related to this project.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
         'tasks': fields.one2many('project.task', 'project_id', "Task Activities"),
@@ -347,6 +360,7 @@ class project(osv.osv):
     _defaults = {
         'active': True,
         'type': 'contract',
+        'label_tasks': 'Tasks',
         'state': 'open',
         'sequence': 10,
         'type_ids': _get_type_common,
@@ -1230,7 +1244,7 @@ class account_analytic_account(osv.osv):
     _inherit = 'account.analytic.account'
     _description = 'Analytic Account'
     _columns = {
-        'use_tasks': fields.boolean('Tasks',help="If checked, this contract will be available in the project menu and you will be able to manage tasks or track issues"),
+        'use_tasks': fields.boolean('Tasks', help="If checked, this contract will be available in the project menu and you will be able to manage tasks or track issues"),
         'company_uom_id': fields.related('company_id', 'project_time_mode_id', string="Company UOM", type='many2one', relation='product.uom'),
     }
 
index bf3eed1..d4d3907 100644 (file)
         <record id="project_stage_0" model="project.task.type">
             <field name="sequence">1</field>
             <field name="name">To Do</field>
+            <field name="legend_blocked">Not validated</field>
+            <field name="legend_priority">Use the priority for tasks related to gold customers</field>
             <field name="case_default" eval="True"/>
         </record>
         <record id="project_stage_1" model="project.task.type">
             <field name="sequence">10</field>
             <field name="name">In Progress</field>
+            <field name="legend_blocked">Need functional or technical help</field>
+            <field name="legend_done">Buzz or set as done</field>
             <field name="case_default" eval="True"/>
         </record>
         <record id="project_stage_2" model="project.task.type">
@@ -50,6 +54,7 @@
             <field name="sequence">30</field>
             <field name="name">Cancelled</field>
             <field name="case_default" eval="True"/>
+            <field name="legend_done">Ready to reopen</field>
             <field name="fold" eval="True"/>
         </record>
     </data>
index 74c35b9..6289396 100644 (file)
@@ -63,6 +63,7 @@
             <field name="sequence">10</field>
             <field name="parent_id" ref="all_projects_account"/>
             <field name="name">E-Learning Integration</field>
+            <field name="label_tasks">Trainings</field>
             <field name="user_id" ref="base.user_demo"/>
             <field name="alias_model">project.task</field>
             <field name="privacy_visibility">employees</field>
@@ -77,6 +78,7 @@
             <field name="sequence">20</field>
             <field name="parent_id" ref="all_projects_account"/>
             <field name="name">Website Design Templates</field>
+            <field name="label_tasks">Designs</field>
             <field name="user_id" ref="base.user_root"/>
             <field name="privacy_visibility">followers</field>
             <field name="alias_model">project.task</field>
@@ -93,6 +95,7 @@
             <field name="parent_id" ref="all_projects_account"/>
             <field name="partner_id" ref="base.res_partner_7"/>
             <field name="name">Data Import/Export Plugin</field>
+            <field name="label_tasks">Databases</field>
             <field name="alias_model">project.task</field>
             <field name="privacy_visibility">followers</field>
             <field name="members" eval="[(6, 0, [
index 5cff324..59c532c 100644 (file)
                         <h1>
                             <field name="name" string="Project Name"/>
                         </h1>
-                        <div name="options_active" invisible="1">
-                            <field name="use_tasks" class="oe_inline"/>
-                            <label for="use_tasks" name="use_task" string="Use Tasks"/>
+                        <div name="options_active">
+                            <div>
+                                <field name="use_tasks" class="oe_inline" string="Use Tasks"/>
+                                <label for="use_tasks" class="oe_inline"/> as <field name="label_tasks" class="oe_inline"/>
+                            </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','=', 0)]}"
                             name="%(act_project_project_2_project_task_all)d" icon="fa-tasks">
-                            <field string="Tasks" name="task_count" widget="statinfo"/>
+                            <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"/>
                                     </div>
                                     <div class="row oe_margin_top_8 oe_kanban_project_list">
                                         <a t-if="record.use_tasks.raw_value" class="oe_sparkline_bar_link" name="%(act_project_project_2_project_task_all)d" type="action" style="margin-right: -5px">
-                                            <t t-raw="record.task_ids.raw_value.length" /> Tasks
+                                            <t t-raw="record.task_ids.raw_value.length" /> <field name="label_tasks"/>
                                             <field name="monthly_tasks" widget="sparkline_bar" options="{'delayIn': '1000'}">
                                                 Created Tasks
                                             </field>
                             <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"/>
+                            <field name="kanban_state" class="oe_inline" widget="kanban_state_selection"
+                                options='{
+                                "states_legend_field": "stage_id",
+                                "states_legend": {"normal": "legend_normal", "blocked": "legend_blocked", "done": "legend_done"}}'/>
                         </div>
                     </div>
                     <group>
             <field name="name">project.task.kanban</field>
             <field name="model">project.task</field>
             <field name="arch" type="xml">
-                <kanban default_group_by="stage_id" >
+                <kanban default_group_by="stage_id">
                     <field name="color"/>
                     <field name="priority"/>
-                    <field name="stage_id"/>
+                    <field name="stage_id" options='{"group_by_tooltip": {"description": "Description", "legend_priority": "Use of stars"}}'/>
                     <field name="user_id"/>
                     <field name="user_email"/>
                     <field name="description"/>
                     <field name="sequence"/>
-                    <field name="kanban_state"/>
                     <field name="remaining_hours" sum="Remaining Time" groups="project.group_time_work_estimation_tasks"/>
                     <field name="date_deadline"/>
                     <field name="message_summary"/>
                                     <div class="oe_kanban_bottom_right">
                                         <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="kanban_state" widget="kanban_state_selection"/>
+                                            <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>
                         <group>
                             <field name="name"/>
                             <field name="sequence"/>
-                        </group>
-                        <group>
                             <field name="case_default"/>
                             <field name="fold"/>
                         </group>
+                        <group>
+                            <field name="legend_blocked"/>
+                            <field name="legend_done"/>
+                            <field name="legend_normal"/>
+                            <field name="legend_priority"/>
+                        </group>
                     </group>
                     <field name="description" placeholder="Add a description..."/>
                 </form>
index 51a7c81..bc9e879 100644 (file)
@@ -548,8 +548,13 @@ class account_analytic_account(osv.Model):
 class project_project(osv.Model):
     _inherit = 'project.project'
 
+    _columns = {
+        'label_issues': fields.char('Use Issues as', help="Customize the issues label, for example to call them cases."),
+    }
+
     _defaults = {
-        'use_issues': True
+        'use_issues': True,
+        'label_issues': 'Issues',
     }
 
     def _check_create_write_values(self, cr, uid, vals, context=None):
index ef012a1..6241d0c 100644 (file)
@@ -7,12 +7,15 @@
         </record>
         <record id="project.project_project_2" model="project.project">
             <field name="use_issues" eval="True"/>
+            <field name="label_issues">Bugs</field>
         </record>
         <record id="project.project_project_3" model="project.project">
             <field name="use_issues" eval="True"/>
+            <field name="label_issues">Feedbacks</field>
         </record>
         <record id="project.project_project_4" model="project.project">
             <field name="use_issues" eval="True"/>
+            <field name="label_issues">Bugs</field>
         </record>
         <record id="project.project_project_5" model="project.project">
             <field name="use_issues" eval="True"/>
index 04c2f54..ee6b123 100644 (file)
                             <field name="name" class="oe_inline"/>
                         </h1>
                         <div class="col-xs-1 text-right">
-                            <field name="kanban_state" class="oe_inline" widget="kanban_state_selection"/>
+                            <field name="kanban_state" class="oe_inline" widget="kanban_state_selection"
+                                options='{
+                                "states_legend_field": "stage_id",
+                                "states_legend": {"normal": "legend_normal", "blocked": "legend_blocked", "done": "legend_done"}}'/>
                         </div>
                     </div>
                     <label for="categ_ids" class="oe_edit_only"/>
             <field name="model">project.issue</field>
             <field name="arch" type="xml">
                 <kanban default_group_by="stage_id">
-                    <field name="stage_id"/>
+                    <field name="stage_id" options='{"group_by_tooltip": {"Description": "description", "Use of stars": "legend_priority"}}'/>
                     <field name="color"/>
                     <field name="priority"/>
                     <field name="user_email"/>
                     <field name="user_id"/>
                     <field name="date_deadline"/>
-                    <field name="kanban_state"/>
                     <field name="message_summary"/>
                     <templates>
                         <t t-name="kanban-tooltip">
                                     <div class="oe_kanban_bottom_right">
                                         <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="kanban_state" widget="kanban_state_selection"/>
+                                            <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>
                     <attribute name="invisible">0</attribute>
                 </xpath>
                 <xpath expr='//div[@name="options_active"]' position='inside'>
-                    <field name="use_issues" class="oe_inline"
-                            on_change="on_change_use_tasks_or_issues(use_tasks, use_issues)"/>
-                    <label for="use_issues"/>
+                    <div>
+                        <field name="use_issues" class="oe_inline" string="Use Issues"
+                                on_change="on_change_use_tasks_or_issues(use_tasks, use_issues)"/>
+                        <label for="use_issues" class="oe_inline"/> as <field name="label_issues" class="oe_inline"/>
+                    </div>
                 </xpath>
                 <xpath expr='//div[@name="buttons"]' position='inside'>
                     <button class="oe_inline 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"/>
+                        <field string="Issues" name="issue_count" widget="statinfo" options="{'label_field': 'label_issues'}"/>
                     </button>
                 </xpath>
                 <xpath expr='//page[@name="project_stages"]' position="attributes">
                 <xpath expr="//div[contains(@class, 'oe_kanban_project_list')]/a" position="after">
                     <a t-if="record.use_issues.raw_value" style="margin-right: 20px" class="pull-right"
                         name="%(act_project_project_2_project_issue_all)d" type="action">
-                        <t t-raw="record.issue_ids.raw_value.length"/> Issues
+                        <t t-raw="record.issue_ids.raw_value.length"/> <field name="label_issues"/>
                         <field name="monthly_issues" widget="sparkline_bar" options="{'delayIn': '1000'}">
                             Closed Issues
                         </field>
index 20cba67..15f6e80 100644 (file)
@@ -6233,7 +6233,12 @@ instance.web.form.StatInfo = instance.web.form.AbstractField.extend({
             value: this.get("value") || 0,
         };
         if (! this.node.attrs.nolabel) {
-            options.text = this.string
+            if(this.options.label_field && this.view.datarecord[this.options.label_field]) {
+                options.text = this.view.datarecord[this.options.label_field];
+            }
+            else {
+                options.text = this.string;
+            }
         }
         this.$el.html(QWeb.render("StatInfo", options));
     },