Overview
Currently Cross Tracker Search (XTS) relies on Tracker Query Language (TQL) in order to express the searches (queries). It turns out that TQL is likely to be a good "intermediate representation" to express data selection more broadly:
- Selection of fields to display
- Selection of trackers to search on
- Selection of fields to sort on
TQL is already deeply inspired from SQL (the WHERE
part), we push this one step further, TQL would like:
SELECT <list of fields> FROM <selection of trackers> WHERE <search criteria> ORDER BY <field to sort on>
We talk about "intermediate representation" because it's a rather tech savvy approach that would not be suitable for all users. However, due to the nature of XTS, some user interactions are rather complex to design. For instance, let say you want to run a query on all "request" tracker of "helpdesk" projects, that might represent 50 trackers with potentially hundreds of different fields. So before we come up with the appropriate UX/UI to deal with those cases extended TQL would allows to use the feature for advanced users at least. When the UI is there we would have UI -> TQL -> Execution
instead of UI -> Execution & TQL -> Execution
that we have today for trackers.
Full TQL
In Full TQL mode a valid query must have SELECT
, FROM
and WHERE
parts. ORDER BY
is optional.
SELECT < list of fields >
Example: SELECT @id, @title, category WHERE @status = OPEN()
will render @id
Always There Field, @title
semantic and category
duck typed field.
There are three categories of fields to take into account:
- Always There Fields
@id
=> int
@submitted_on
=> date time
@last_update_date
=> date time
@submitted_by
=> user
@last_update_by
=> user
- Semantics
@title
=> string
@description
=> text
@status
=> list of static values
@assigned_to
=> list of users
- Duck-typing (referred by their name without
@
, eg category
)
- numeric fields (
int | float
)
- text fields (
string | text
)
- list fields with same bind incl. open lists
- date & date time fields
-
- Special fields
- @project.name => should include the project icon as suffix of the name.
- @tracker.name
- @pretty_title: corresponds to "tracker short name"
#@id @title
with badge that have the tracker color as background.
The following fields are not covered in the first implementation of SuperTableau and will require dedicated stories to fine tune how they should be rendered
- Computed fields
- File attachment
- Cross references
- Artifact Links
- Permissions on artifacts
Excluded fields:
- charts: Burnup, Burndown
- rank: it's unlikely that this fields is useful in table reports (esp if we allow to sort on fields with
ORDER BY
).
- TTM fields (steps definition & steps executions): we don't know how to represent them in table report at the moment
- Per tracker id: it's unlikely to make sense in this context
One field can only be selected once (SELECT i_want_to, description, i_want_to
is not a legit query`)
FROM < selection of trackers >
Example: FROM @project.name = 'gpig' and @tracker.name = 'sla' WHERE @status = OPEN()
will return all open artifacts of SLA tracker of gpig project.
@project.name = 'gpig' and @tracker.name = 'sla'
: one tracker in one project
@project.name = 'gpig'
: all trackers of one project
@project.name IN ('gpig', 'red', 'foo') and @tracker.name = 'sla'
: sla
tracker of several projects.
@project.name = 'gpig' and @tracker.name IN ('sla', 'request')
: sla
or request
tracker in gpig
project
@project.name IN ('gpig', 'red', 'foo') and @tracker.name IN ('sla', 'request')
: sla
and request
tracker in gpig
, red
and foo
projects
@project.category = 'helpdesk'
: all trackers of all projects withhelpdesk
category
@project.category = 'topic::power'
: all trackers of all projects withtopic -> power
category (topic
is parent of power
)
@project = 'self'
Rules:
- Supported selector:
@project.name = 'string'
: select one project based on it's short name. It's an exact match.
@project.name IN (string, ...)
: select projects based on their short name. It's an exact match.
@project.category = 'string'
: select projects that match given project category. It's an exact match.
@project.category IN (string, ...)
: select projects based on their project categories. It's an exact match.
@project = 'self'
: select current project. Works only in the context of a project dashboard. In the context of personal dashboard, this leads to an error.
@project = 'aggregated'
: select all aggregated projects (program management)
- works only in the context of a project dashboard of a project that uses Program Management,
- on the context of a project dashboard of a project that doesn't use Program Management, this leads to an error,
- in the context of personal dashboard, this leads to an error.
@project IN (string)
: select projects with self
and/or aggregated
@tracker.name = 'string'
: select one tracker inside selection of projects (implies @project = 'self'
).
@tracker.name IN (string, ...)
: select all trackers based on their short name inside selection of projects (implies @project = 'self'
).
- It's possible to have zero or one
@project
rule per FROM
:
- OK:
@project.name = 'gpig'
- OK:
@project.category = 'topic::power'
- NOK:
@project.category = 'helpdesk' AND @project.name = 'foo'
- It's possible to have zero or one
tracker
rule per FROM
:
- OK:
@tracker.name = 'sla'
- NOK:
@tracker.name = 'sla' AND @tracker.name = 'request'
- It's possible to use either
@tracker AND @project
as well as @project AND @tracker
with the same result
OR
is not supported
By default there is no limit in the number of trackers involved in a given query, however, there is a kill-switch config-key that allows to define a maximum number of trackers in case of emergency.
When some projects or trackers cannot be accessed due to permissions, they are silently ignored. If no trackers are readable due to permissions, the result is a "no artifact found".
When no project or tracker match the query (eg typo), the result is "no artifact found".
ORDER BY < field to sort on >
Example: @status = OPEN() ORDER BY @last_update_date DESC
: will return all open artifacts, the newest first
Rules:
- Sort can be on any field that is present in all involved tracker (displayed or not, while it's un common to sort on a criteria not displayed with a Table rendering, it's quite common for Kanban rendering)
- Sort is possible only on one field at time
- It's possible to choose the order: ASC (aka ascending) or DESC (aka descending)
- Supported operators:
ASC
, ASCENDING
, DESC
, DESCENDING
ORDER BY
is not mandatory, if not present the default sort is done on @id
implicitly
- When
ORDER BY
is used, the direction of sort is mandatory
ORDER BY
is possible on following types
- String/text (duck-typing)
- Result might be weird for text because of HTML (not stripped for sorting)
- Numerical: int/float/@id (duck-typing)
- date
- datetime
- list values when there is only one possible value (select box / radio)
- For users, the sort is done on displayed value
- For user groups, the sort is done on translated group name
Cross tracker search widget integration
Cross tracker search behavior doesn't change by default. The current default (as per Tuleap 15.10) is called "Legacy" and covers fixed set of columns, the manual selection of trackers and the extension of field search already implemented in initial cross tracker search epic #10407. The format SELECT ... FROM ... WHERE ... ORDER BY ...
is not supported in Legacy mode. Legacy mode only supports the WHERE
part.
It's however possible to switch to "Advanced" mode where everything is under TQL control :
- Selection of columns
- Selection of trackers
- Selection of search criteria
- Selection of sort
It's possible to switch from Advanced to Legacy and vice-versa. Switching to another mode reset the search (there is a warning to inform users).
When Switching to Advanced, there is a default query that is proposed to help users to start SELECT @id, @tracker.name, @title, @status FROM @project = 'self' WHERE @status = OPEN()
Technical task splitting for FROM
- Grammar
- Config-key maximum tracker retrieved by FROM (default to -1 for no limit)
- Begin with
@project = 'self'
then @project.category (= and IN)
- Continue on
@tracker.name
(= and IN)
- Finish @project.name and @project = 'aggregated'
- Add key in json API return to tell number of tracker and project hit by FROM
- Autocompletion @*