Issue
The Issue feature is a ticket management tool integrated within the QFQ framework. It handles issue tracking, permissions, notifications, and comment management.
How to get started
Create a new page in your Typo3 backend.
Set the ‘URL slug’ to
/issue.Create a content element of type ‘QFQ Element’.
Insert
file=_issue.
Configuration
To use the Issue feature, the following configuration steps are required:
Database tables
Ensure the following tables exist in your database:
Grp: Must include records with the following references:qfq_project_access_writeqfq_project_access_readqfq_project_access_adminqfq_upload_issueqfq_upload_commentqfq_upload_commentNewqfq_status_issueqfq_tag_issue
ProjectStatusCommentFileUploadIssue
System store variables
Define the following variables in the SYSTEM-STORE (Dynamic/Custom) via QFQ configuration:
pIdUser: ID of the current useremailUser: Email of the current userpersonTableName: Table name for person recordspersonFirstNameColumnName: First name column in person tablepersonLastNameColumnName: Last name column in person tablepersonEmailColumnName: Email column in person tableissueMailNotificationInterval(optional): Notification delay interval in minutes (default: 2)issueWebsocketMessage(optional): Message for form parametermessage(websocket)
Important
The variables personTableName, personFirstNameColumnName, personLastNameColumnName and personEmailColumnName are always used together in the same query. Therefore, all referenced columns must exist in the specified table.
If your setup stores this information across multiple tables (e.g., email in a separate table), it is recommended to create a database view that consolidates all required fields into a single table-like structure.
Example:
CREATE VIEW PersonIssueView AS
SELECT p.id AS id
, p.firstName AS firstName
, p.lastName AS lastName
, ad.email AS email
FROM (Person AS p, Grp AS gr)
LEFT JOIN Address AS ad
ON ad.pId = p.id
AND ad.grId = gr.id
WHERE gr.reference = 'hr-addressWork'
AND ad.email != ''
GROUP BY p.id
Use
The core interface is accessible via the report at /issue.
Functionality
Displays a table of issues the current user has permission to access
Fully filterable and sortable using tablesorter
Can be embedded for integrations (Integration)
Filter parameters
Issues can be filtered by passing parameters to the /issue page using either SIP or a QFQ function (see Embedded view).
Each parameter corresponds to a column in the Issue table and is applied as part of the query filter.
By default, all parameters use the
=operator.Exceptions:
sea: Applies aLIKEfilter on both thetitleanddescriptioncolumns.tag: UsesFIND_IN_SET()to filter tags stored in theGrptable.rem: Filters for issues with overdue reminders. The actual value is ignored; the presence of the parameter triggers the check.
This mechanism allows for precise filtering when embedding issue views or linking to pre-filtered results.
Parameter |
Column |
|---|---|
pro |
prId |
sta |
stId |
xid |
xId |
fid |
formId |
fna |
formName |
cre |
pIdCreator |
ass |
pIdAssignee |
con |
pIdContact |
mco |
mailContact |
mws |
mailWatcherSet |
mns |
mailNotificationSet |
mno |
mailNotification |
tit |
title |
des |
description |
str |
start |
due |
due |
del |
deleted |
sea |
title, description (LIKE) |
tag |
Grp.name (FIND_IN_SET()) |
rem |
reminder (< NOW() AND != “0”) |
Note
The default value for the del parameter is no, meaning deleted issues are hidden unless explicitly requested.
Additional parameters
When using the embedded view or linking directly to /issue, additional parameters can be passed to customize functionality and content filtering.
Parameter |
Description |
Value |
Default |
|---|---|---|---|
tso |
Enable or disable tablesorter |
|
|
col |
Displayed columns |
Comma separated column headers |
|
dnd |
Drag and drop for table rows |
|
|
Note
When the dnd parameter is enabled, the CSS class table-draggable is added to the table.
Each table row will include the following attributes:
id: A combination of a random string and the record’sid.data-record-id: The record’sid.data-drop-zone-table-origin: The name of the source table (e.g.,Issue).
These attributes enable JavaScript-based actions on records, such as closing an issue by dragging it into a designated drop zone and triggering an API call.
Security Note:
The id attribute is visible to the user, meaning API calls could be manipulated by replacing it with one the user is not authorized to access.
Always validate user permissions on the server side to prevent unauthorized changes.
Additionally, it is recommended to use SIP when possible — for example, in the drop zone — to obfuscate actions, involved tables, ids, and other sensitive data.
Form: issue
Most fields in this form are self-explanatory, but the following may require additional context:
Status: Dropdown listing all records from the
Statustable wheregrId = qfq_status_issueProject: Dropdown listing all records from the
ProjecttableAssignee: TypeAhead input listing all users with permissions on the selected project
Creator: TypeAhead input listing all users. Only visible to users logged into the Typo3 backend or users with admin permissions on the selected project
Tags: TypeAheadTag input listing all existing tags. A new tag is created automatically if no match is found
Contact person: TypeAhead input listing all users
Contact person mail: Optional email address when the contact person is not in the database
Watcher mail (list): Comma-separated list of email addresses
Notification: See Notification
Comment: See Comments
Important
QFQ provides Forms for configuring Status and Project via the Form definitions status.json and project.json.
The issue.json Form includes buttons that link to the corresponding management pages at /status and /project. These pages must be created manually in the Typo3 backend. On each page, add the necessary content to display the respective records incl. links to the mentioned Forms for editing.
Permissions
Access Control
Access is automatically managed by QFQ:
Project-Based Access
Users gain access to issues by being assigned permissions on a project (the issue belongs to) via the
Gluetable. Available permission levels:Level
Reference
Description
Write
qfq_project_access_write
View, create, edit, delete
Read
qfq_project_access_read
View only
Admin
qfq_project_access_admin
Like Write + extra options in form
Contact/Watcher-Based Access
Even without project permissions, users may access an issue if they are:
Listed as a contact person or watcher
And access contact/watcher is enabled
Additional rules
Creators of an issue or comment always have access
Unassigned issues (no project) can be accessed only by:
The creator
The assignee
The contact person (if allowed)
The watcher (if allowed)
Notification
The notification mechanism allows to alert involved parties via email when changes are made to an issue.
Recipients:
Creator
Contact person
Watchers
Assignee
Behavior:
Upon saving an issue/comment, a timestamp (+2 minutes) is added if recipients are selected
This 2-minute delay allows batching of quick consecutive changes
If all recipients are removed, the timestamp is reset to
0000-00-00 00:00:00
Note
Use a cron job to regularly check timestamps and dispatch emails.
Integration
Issue linked to a specific record
Issues can be linked to a specific record (and form) by enabling the issue option under Show button in the form editor of the primary form.
When this option is enabled:
An Issue button appears on the form
The button displays the number of issues associated with the current record, including how many are still open
Clicking the button redirects the user to
/issueWhen creating a new issue from this view, it is automatically assigned to the originating record (
xId) and form (formId)
Link to filtered view
To create a link to the /issue page with pre-defined filters, use SIP to include parameters.
Example:
{
sql = SELECT 'p:/issue?ass=1&pro=1|s' AS _link
}
This generates a secure, parameterized link to the issue list, filtered by the specified parameters.
Embedded view
The /issue page can also be embedded using a QFQ function, which is especially useful for dashboards or integrating views in custom layouts.
Important
A subheader must be defined for /issue, and the variable containing the query string must be set in the RECORD-STORE under the name queryString.
Example:
{
sql = SELECT 'ass=1&pro=1' AS _queryString
}
{
function = issue(queryString)
sql = SELECT '{{_output:RE}}'
}
This renders the filtered issue list within another QFQ-managed page using the specified parameters.
Deleting issues/comments
Issues and comments are never physically deleted; instead, they are marked as deleted by setting deleted = yes.
Comments
There are two ways a user can add a comment to an issue:
Edit Issue
When editing an existing issue, a
Commenttab (pill) is available. This allows users to add a new comment along with its permissions. This method is ideal when the user needs to update the issue and leave a comment simultaneously — for example, when closing an issue and providing a reason.New Comment
Use this option when no changes to the issue itself are required and only a comment needs to be added.
Each comment can have specific permissions:
Comments can be restricted from contact person and watchers
A badge beside the edit button indicates if a comment is restricted or not