Advanced Сustomization: Customize Inner Lists

INNER LISTS OF NATIVE ENTITIES

Here is an example of the customized "User Stories" tab in Feature detail view:

792
"component": {
                      "type": "component",
                      "component": "entity.new.list",
                      "properties": {
                        "name": "User Stories",
                        "lazy": true,
                        "spinnerConfigForLazy": {
                          "isShow": true,
                          "selectorForHeight": ".tau-page-entity",
                          "loaderOptions": {
                            "loaderType": "logo"
                          }
                        },
                        "definition": {
                          "cardSettings": {
                            "list_userstory": {
                              "list": [
                                [
                                  {
                                    "id": "entity_name_1line"
                                  },
                                  {
                                    "id": "general_entity_id"
                                  },
                                  {
                                    "id": "planned_start_date"
                                  },
                                  {
                                    "id": "planned_end_date"
                                  },
                                  {
                                    "id": "time_spent_remain"
                                  },
                                  {
                                    "id": "assigned_users"
                                  }
                                ]
                              ]
                            }
                          },
                          "cells": {
                            "types": [
                              "userstory"
                            ]
                          }
                        }
                      }
                    }

In order to customize the list in the existing tab, you have to replace the "Component" section of this tab in Detailed view configuration:

Before replacement of code:

After replacement of code:

943

How to find the ID of a column

Option 1 - Diagnostic Report

  1. Create a list view with the the corresponding entity type and customize the columns
  2. Go to Settings > Diagnostic and Logs > Diagnostic report. Click "See full report" link.
  3. Scroll down to cardSettings and copy the entire cardSettings section:
443

Option 2 - Inspect Element

  1. Create a list view with the the corresponding entity type and customize the columns
  2. Right-click the column header and find there a name of the unit (data-unit-id):

🚧

This approach is less reliable than Option 1

For example, for the Tags unit the value of "data-unit-id" is "tags_long", while ID of the column which you need to use in Detailed View (and which is available in Diagnostic Report from Option 1) is "tags_short"

1071

INNER LISTS OF EXTENDABLE DOMAIN ENTITIES

A sample for the ExD entity:

763
{
                          "type": "component",
                          "component": "entity.new.list",
                          "properties": {
                            "name": "Estimate",
                            "origin": "request/estimates",
                            "lazy": true,
                            "spinnerConfigForLazy": {
                              "isShow": true,
                              "selectorForHeight": ".tau-page-entity",
                              "loaderOptions": {
                                "loaderType": "logo"
                              }
                            },
                            "definition": {
                              "cardSettings": {
                                "list_estimate": {
                                  "list": [
                                    [
                                      {
                                        "id": "entity_name_1line"
                                      },
                                      {
                                        "id": "general_entity_id"
                                      },
                                      {
                                        "id": "planned_start_date"
                                      },
                                      {
                                        "id": "planned_end_date"
                                      }
                                    ]
                                  ]
                                }
                              },
                              "cells": {
                                "types": [
                                  "estimate"
                                ]
                              },
                              "entityAxisId": "extendable_domain_one_to_many_request_request"
                            }
                          },
                          "componentId": "component_ugfmnh2"
                        },

Hierarchical Lists with One to Many References

In some cases, you might need to create a hierarchical Inner List where the cards are ExD entities and they are grouped by ExD entities to which they have a many-to-one reference.

Please note in case of creating a hierarchical list there should be direct connections between the main entity and both entities from the hierarchical list
e.g. Tech Project should have a collection of Tech Activities as well as a collection of Work Allocations

To customize columns of the 2nd level of such a list, you have to use a composite key. An example extract from an Inner List’s config is below:

"definition": {
  "cells": {
    "types": [
      "workallocation"
    ]
  },
  "cardSettings": {
    "list_workallocation": {
      "list": [
        [
          {
            "id": "entity_name_1line"
          },
          {
            "id": "general_entity_id"
          },
          {
            "id": "assigned_users_last_name"
          },
          {
            "id": "extendable_domain_TechActivity_techactivity"
          },
          {
            "id": "action_delete"
          }
        ]
      ]
    },
    "list_extendable_domain_one_to_many_techactivity_techactivity": {
    "list": [
        [
          {
            "id": "entity_name_1line"
          },
          {
            "id": "general_entity_id"
          },
          {
            "id": "comments_count"
          },
          {
            "id": "state_full_length"
          },
          {
            "id": "planned_start_date"
          },
          {
            "id": "planned_end_date"
          },
          {
            "id": "action_delete"
          }
        ]
      ]
    }
  },
  "x": {
    "types": [
      "extendable_domain_one_to_many_techactivity_techactivity"
    ]
  },
  "entityAxisId": "extendable_domain_one_to_many_techproject_techproject"
}
792

Example of a hierarchical Inner List of ExD entities

The name of the 2nd level key (here: list_extendable_domain_one_to_many_techactivity_techactivity) is composed as list_{type from the 'x.types' key}. The x.types of a list’s definition contains the axis name composed as extendable_domain_one_to_many_{the entity type to which the cards refer}_{the attribute through which they refer}.

In this particular example, the type in the key name list_extendable_domain_one_to_many_techactivity_techactivity means that the cards (here: 'WorkAllocation' ExD entities) refer to 'TechActivity' entities through the 'TechActivity' attribute.

The key name should be all lowercase.

INNER LIST OF SEVERAL ENTITY TYPES

To customize inner list that consists of several entity types use the following property list_entitytypename1_entitytypename2

You can also use _info_headerText parameter to customize displayable name of the header in list

Here is an example of the configuration for User Story detail view that adds tab with inner list that consists of Tasks (Native) and Time Records (ExD) entities:

{
                    "type": "section",
                    "title": {
                      "type": "string",
                      "value": "Tasks and Time Records",
                      "localize": true
                    },
                    "component": {
                      "type": "stack",
                      "components": [
                        {
                          "type": "component",
                          "component": "entity.new.list",
                          "properties": {
                            "name": "UserStory",
                            "definition": {
                              "cells": {
                                "types": [
                                  "task",
                                  "timerecord"
                                ]
                              },
                              "cardSettings": {
                                "list_task_timerecord": {
                                  "list": [
                                    [
                                      {
                                        "id": "entity_name_1line",
                                        "alignment": "base"
                                      },
                                      {
                                        "id": "general_entity_id",
                                        "alignment": "base",
                                        "_info_headerText": "ID"
                                      },
                                      {
                                        "_info_headerText": "Entity Type: Id",
                                        "id": "entity_type_icon_id",
                                        "alignment": "base"
                                      },
                                      {
                                        "_info_headerText": "Entity Type",
                                        "id": "entity_type_icon_full",
                                        "alignment": "base"
                                      },
                                      {
                                        "id": "assigned_users",
                                        "alignment": "base",
                                        "_info_headerText": "Assignments"
                                      },
                                      {
                                        "id": "planned_start_date",
                                        "alignment": "base",
                                        "_info_headerText": "Planned Start"
                                      }
                                    ]
                                  ]
                                }
                              }
                            }
                          },
                          "componentId": "component_pNbqft8rFCrBqb7T"
                        }
                      ],
                      "componentId": "stack_KrT8CRBkQC7trqqN"
                    },
                    "componentId": "section_7689nf8LLcj8MpjQ"
                  }

GENERAL CUSTOMIZATIONS

Any entity list

You can add a list with any entity type using "entity.new.list" component. Apply a filter with the same syntax as in Views: "filter": "?It is not None"

Tab counter

After you filter our entities from the inner list you still see the same value in the counter that is displayed on the tab header. It is possible to customize this value. You can add a similar filter as for the entities in the list using the following syntax:

{
                    "title": {
                      "type": "string",
                      "value": "userStory",
                      "localize": true,
                      "useTerms": true,
                      "isPlural": true
                    },
                    "titleExtra": {
                      "type": "component",
                      "component": "label.generalCounter",
                      "properties": {
                        "text": "",
                        "entityTypeColor": "userstory",
                        "collectionField": "userStories",
                        "collectionQuery": "count(project.id==13 and entitystate.isfinal = false)"
                      },
                      "componentId": "component_ts8hp4n"
                    },
                    "component": {
                      "type": "component",
                      "component": "layout.list",
                      "properties": {
                        "listType": "userStories",
                        "definition": {
                          "cells": {
                            "types": [
                              "userstory"
                            ],
                            "filter": "?project.id==13 and entitystate.isfinal is false",
                            "useFilter": true
                          }
                        }
                      },
                      "componentId": "component_i3gqhgw"
                    },
                    "componentId": "section_r7hx61w",
                    "type": "section"
                  }

It's also possible to customize tab counter in order to see few values there. For example, you might be interested in showing both count of opened User Stories and total count of them for the Feature.

{
                    "title": {
                      "type": "string",
                      "value": "userStory",
                      "localize": true,
                      "useTerms": true,
                      "isPlural": true
                    },
                    "titleExtra": {
                      "type": "stack",
                      "components": [
                        {
                          "type": "component",
                          "component": "label.generalCounter",
                          "properties": {
                            "text": "",
                            "collectionField": "userStories",
                            "collectionQuery": "count(entitystate.isfinal = false)",
                            "entityTypeColor": "userstory"
                          },
                          "componentId": "component_DtCtj9FtjH8KmFKL",
                          "visibilityConfig": {
                            "entityQuerySelector": "userstories.count(entitystate.isfinal = false)>0"
                          }
                        },
                        {
                          "type": "component",
                          "component": "label",
                          "properties": {
                            "text": "/"
                          },
                          "componentId": "component_pQ6DkgnqqqWJW9Wc",
                          "visibilityConfig": {
                            "entityQuerySelector": "userstories.count(entitystate.isfinal = false)>0"
                          }
                        },
                        {
                          "type": "component",
                          "component": "label.generalCounter",
                          "properties": {
                            "text": "",
                            "collectionField": "userStories",
                            "collectionQuery": "",
                            "entityTypeColor": "userstory"
                          },
                          "componentId": "component_bfbfPKR9FG6w8jHT"
                        }
                      ],
                      "componentId": "stack_7cHKjRhqfzMCwrqw"
                    },
                    "component": {
                      "type": "component",
                      "component": "layout.list",
                      "properties": {
                        "listType": "userStories",
                        "definition": {
                          "cells": {
                            "types": [
                              "userstory"
                            ]
                          }
                        }
                      },
                      "componentId": "component_i3gqhgw"
                    },
                    "componentId": "section_r7hx61w",
                    "type": "section"
                  }

NOTE that tab counters for Test Case Runs, Project Members, Requesters, and Team Members are implemented with the "label" component instead of the "label.generalCounter" component. The "label" component doesn't use the "collectionField" property. It uses the "countFieldNames" property to show the number, and it's impossible to use the "collectionQuery" property to customize it. However, the "label" component does use the "entityTypeColor" property. Here's a sample JSON for a Requesters counter:

"titleExtra": {
  "type": "component",
  "component": "label",
  "properties": {
    "text": "",
    "countFieldNames": [
      "requesters"
    ],
    "entityTypeColor": "userstory"
  }
}

Custom fields as columns

It is possible to add Custom Fields as columns to the list.
To get the exact name of the custom field, create a List view, add required Custom Fields using the Customize cards tab and then find CF label id in the JSON of the board, just in the same way as with native units.

Here is an example of json for the Features list:

1029
{
                          "type": "component",
                          "component": "entity.new.list",
                          "properties": {
                            "name": "feature",
                            "lazy": true,
                            "definition": {
                              "x": {
                                "types": [
                                  "feature"
                                ],
                                "filter": "?It is not None",
                                "useFilter": true
                              },
                              "cells": {
                                "types": [
                                  "userstory"
                                ]
                              },
                              "cardSettings": {
                                "list_feature": {
                                  "list": [
                                    [
                                      {
                                        "id": "entity_name_1line"
                                      },
                                      {
                                        "id": "custom_field__100__ZHVlIGRhdGU__3"
                                      },
                                      {
                                        "id": "custom_field__100__YWUgcHJvY2Vzcw__3__3"
                                      },
                                      {
                                        "id": "general_entity_id"
                                      },
                                      {
                                        "id": "state_full_length"
                                      },
                                      {
                                        "id": "assigned_users"
                                      },
                                      {
                                        "id": "us_opentotal"
                                      }
                                    ]
                                  ]
                                }
                              }
                            }
                          },
                          "componentId": "component_qjujfxq"
                        }

Ordering

It's possible to order inner list by some property. For this we can add ordering under cells section:

"definition": {
  "cells": {
    "types": ["userstory"],
    "ordering": {
      "direction": "Desc",
      "name": "entityState.name"
    }
  }
}

Inner lists might be not properly ordered by states, for this pupose the next code might be used:

"definition": {
  "cells": {
    "types": ["userstory"],
"ordering": {
  "direction": "Desc",
  "name": "RankWithFinalInTheBottom"
  }
 }
}

For correct ordering names, we can create a regular list and check its definition in treeView requests. Please find detailed description of how this can be done here

finderModel: Error in Search within custom inner lists

Tests tab:
In certain cases after the customization of the Inner list, the error occurs while using the magnifying glass icon.
Examples: Tests Tab in a Test Plan returns an error "There is no 'testPlan' member in TestItem."
How to resolve:
The following component is required for adding to JSON code:

"behaviorsSettings": {
                          "finderModel": "linkTestItem"
                        },

Here's an example of the customized Tests section with the added definition of the finderModel:

{
                    "type": "section",
                    "title": {
                      "type": "string",
                      "value": "Tests",
                      "localize": true
                    },
                    "component": {
                      "type": "component",
                      "component": "entity.new.list",
                      "properties": {
                        "behaviorsSettings": {
                          "finderModel": "linkTestItem"
                        },
                        "name": "Tests",
                        "definition": {
                          "cells": {
                            "types": [
                              "TestCase",
                              "TestPlan"
                            ]
                          },
                          "cardSettings": {
                            "list_testcase_testplan": {
                              "list": [
                                [
                                  {
                                    "id": "entity_name_1line"
                                  },
                                  {
                                    "id": "general_entity_id"
                                  },
                                  {
                                    "id": "owner"
                                  },
                                  {
                                    "id": "tags_short"
                                  },
                                  {
                                    "id": "tc_last_status"
                                  },
                                  {
                                    "id": "test_case_icon"
                                  },
                                  {
                                    "id": "last_comment_date"
                                  },
                                  {
                                    "id": "project_abbr"
                                  }
                                ]
                              ]
                            }
                          }
                        }
                      },
                      "componentId": "component_jRJJ9Prq7hqrwGGz"
                    },
                    "titleExtra": {
                      "type": "testHierarchyLabel",
                      "componentId": "testHierarchyLabel_djjjt1t"
                    },
                    "componentId": "section_h8rRKWkFfLbm6GfG"
                  },

Requesters:
Error: "There is no 'request' member in user"
This error may appear in the customized Requesters tab while searching for a user.

Solution:

"behaviorsSettings": {
                  "finderModel": "userToRequest"
               },

Extendable Domain:
Error: "There is no 'entitytype of the inner list' member in base entitytype"
This error may appear in the customized tab with extendable domain entities while searching.

Solution:

"behaviorsSettings": {
                  "referenceFieldName": "Put here the name of the entity type from the inner list"
               },

example:


  "behaviorsSettings": {
                      "referenceFieldName": "opportunities"
                    }

Other customizations

To hide a quick add button in the list, use listOptions section inside list Properties.

"listOptions": {
    "quickAddOptions": {
         "disabled": true
     }
}

To hide a lookup in the list, use listOptions section inside list Properties.

"listOptions": {
    "disableLookup": true
}

Both buttons hidden:

"properties": {
                        "name": "Bugs",
                        "lazy": true,
                        "spinnerConfigForLazy": {
                          "isShow": true,
                          "selectorForHeight": ".tau-page-entity",
                          "loaderOptions": {
                            "loaderType": "logo"
                          }
                        },
                        "listOptions": {
                          "quickAddOptions": {
                            "disabled": true
                          },
                          "disableLookup": true
                        },
451

Both buttons shown

456

Both buttons hidden

The list can get a custom header using the following parameter in listOptions:

"listOptions": {
    "cellsHeader": "Bugs related to the User Story"
}
470

You can also specify the default number of entities displayed per the customized list:

809 988
"properties": {
                        "name": "User Stories",
                        "listOptions": {
                          "forcedPageSize": 50
                        },