Screen Widgets

MainScreen

class MainScreen(api: jiratui.api_controller.controller.APIController | None = None, project_key: str | None = None, user_account_id: str | None = None, jql_expression_id: int | None = None, work_item_key: str | None = None, focus_item_on_startup: int | None = None)

Bases: textual.screen.Screen

The main screen of the application.

This is the main screen of the application. It is responsible for:

  • handling different types of work item search

  • handling events for focusing different widgets based on custom key-bindings

  • handling the logic for creating work items

  • handling the logic for copying the key of the currently selected work item

  • handling the logic for copying the url of the currently selected work item

  • handling the logic for creating a local Git branch for the currently selected work item

  • searching Jira users for the assignee input filter

  • searching projects for the project input

  • searching types of issues for the issue type input filter

  • composing the widgets in the UI

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

api

None

The API instance used by the screen to interact with the Jira REST API via a an API controller.

initial_project_key: str | None

None

A project key to set as the initial value of the projects dropdown widget.

initial_work_item_key

None

A work item key to set as the initial value of the work-item-key widget.

initial_assignee_account_id

None

Pre-selected user/assignee account id. This is passed during the initialization of the application.

initial_jql_expression_id: int | None

None

Pre-selected JQL expression ID to load into the JQL expression widget on start-up. This JQL expression will be used for searching issues when the user does not select any filter/criteria in the UI.

focus_item_on_startup

None

The position of the work item to focus and open on startup. Requires search_on_startup to be enabled.

current_loaded_work_item_key: str | None

None

Track the currently loaded work item key to prevent redundant reloads.

compose() textual.app.ComposeResult

Composes the widgets of the application’s main screen.

Returns:

An instance of ComposeResult.

async on_mount() None

Mounts the widgets on the screen.

This method orchestrates the initial data loading and UI population based on configuration settings and launch arguments. It performs the following operations in sequence:

Workers (Asynchronous Tasks):

  • Fetch projects: always runs as a worker to populate the project dropdown.

  • Fetch issue types: runs as a worker unless configured to only fetch projects on startup or an initial project key is provided.

  • Fetch statuses: runs as a worker unless configured to only fetch projects on startup or an initial project key is provided.

  • Fetch work items (search): runs as a worker if search_on_startup is enabled, after waiting for dependent workers to complete.

  • Focus item: Runs as a worker if focus_item_on_startup is specified, after waiting for the search to complete.

API Calls (Direct):

  • get_user(account_id): Fetches user details if initial_assignee_account_id is provided. Used to validate the user exists and retrieve their display name.

Widgets Populated:

  • users_selector: set with the user account ID and display name if initial_assignee_account_id is provided and the user is found via API.

  • jql_expression_input: set with the JQL expression if initial_jql_expression_id is provided and a matching pre-defined expression exists in configuration.

  • Project dropdown: populated by the fetch_projects worker.

  • Issue types dropdown: Populated by the fetch_issue_types worker (if applicable).

  • Status filter: Populated by the fetch_statuses worker (if applicable).

  • Work items list: Populated by the search worker (if search_on_startup is enabled).

Configuration Dependencies:

  • on_start_up_only_fetch_projects: If True, skips fetching issue types and statuses.

  • search_on_startup: If True, triggers a work item search after initial data is loaded.

  • pre_defined_jql_expressions: Dictionary of JQL expressions keyed by expression ID.

Execution Order:

  1. Fetch projects (always).

  2. Fetch issue types and statuses (conditionally, in parallel).

  3. Fetch and set user details (conditionally).

  4. Load and set JQL expression (conditionally).

  5. Trigger search and focus item (conditionally, with proper await sequencing).

See the following workflow diagram for an overview.

        flowchart TD
    Start([Start]) --> FetchProjects["Run Worker: Fetch Projects<br/>(Add to workers list)"]
    FetchProjects --> CheckOnStartup{"on_start_up_only_fetch_projects<br/>is False AND<br/>initial_project_key is None?"}
    CheckOnStartup -->|Yes| FetchIssueTypes["Run Worker: Fetch Issue Types"]
    CheckOnStartup -->|Yes| FetchStatuses["Run Worker: Fetch Statuses"]
    CheckOnStartup -->|No| CheckAssignee
    FetchIssueTypes --> CheckAssignee
    FetchStatuses --> CheckAssignee
    CheckAssignee{"initial_assignee_account_id<br/>is set?"}
    CheckAssignee -->|Yes| GetUser["API Call: get_user<br/>(initial_assignee_account_id)"]
    CheckAssignee -->|No| CheckJQL
    GetUser --> UserSuccess{"user_response<br/>success?"}
    UserSuccess -->|Yes| SetUserWidget["Set users_selector<br/>with user details"]
    UserSuccess -->|No| NotifyWarning["Notify: Unable to find user<br/>with account ID"]
    SetUserWidget --> CheckJQL
    NotifyWarning --> CheckJQL
    CheckJQL{"initial_jql_expression_id<br/>is set AND<br/>pre_defined_jql_expressions exist?"}
    CheckJQL -->|Yes| GetExpression{"Get expression from<br/>pre_defined_jql_expressions?"}
    CheckJQL -->|No| CheckSearchOnStartup
    GetExpression -->|Found| SetExpression["Set jql_expression_input<br/>with expression<br/>Clean: replace newlines/tabs"]
    GetExpression -->|Not Found| CheckSearchOnStartup
    SetExpression --> CheckSearchOnStartup
    CheckSearchOnStartup{"search_on_startup<br/>is enabled?"}
    CheckSearchOnStartup -->|No| End([End])
    CheckSearchOnStartup -->|Yes| WaitWorkers["Wait for workers to complete<br/>(projects, issue types, statuses)"]
    WaitWorkers --> RunSearch["Run Worker: Search<br/>(exclusive=True)"]
    RunSearch --> CheckFocusItem{"focus_item_on_startup<br/>is set?"}
    CheckFocusItem -->|No| End
    CheckFocusItem -->|Yes| WaitSearch["Wait for search worker<br/>to complete"]
    WaitSearch --> FocusItem["Run Worker: Focus Item<br/>on Startup"]
    FocusItem --> End
    
Returns:

None

async fetch_projects() None

Fetches the list of available projects.

If the user pre-selects a project using the configuration setting default_project_key_or_id or by passing the --project-key in the CLI command jiratui ui --project-key then the application will only fetch that project. This speeds up the launching of the app because less API requests are needed.

If on the other hand, no project key is pre-selected then the application will fetch all available projects. This may require multiple API requests; making the application launch slower.

If a project is pre-selected the application will pre-select the project from the dropdown list. a value if required.

If no project is found then the application will leave the dropdown empty.

Returns:

Nothing.

async fetch_statuses() list[tuple[str, str]]

Retrieves the valid status codes depending on the selected project and type of work item.

Returns:

A list of tuples with the name and id of every project status code.

async fetch_issue_types() list[tuple[str, str]]

Retrieves the list of type of work items.

If a project is selected then it will retrieve the types of work items associated to the project; otherwise it will retrieve all the possible types of work items.

Returns:

A list of tuples with the id of the type of issue and the name of the type of issue.

async handle_project_selection(event: textual.widgets.Select.Changed) None

Handles the selection of a project.

This will trigger the actions to fetch the types of issues and applicable project status codes. It will also update the project key of the autocomplete widget used for searching Jira users.

Parameters:

event – the event triggered by the selection.

Returns:

Nothing.

async search_issues(next_page_token: str | None = None, search_term: str | None = None, page: int | None = None) None

Searches work items.

If a specific issue is specified in the Issue Key input widget then the app searches the details of that issue only. If, on the other hand, no issue is specified then the app searches issues based on the given criteria.

Once the results are retrieved this method will update a reactive attribute in the search results table to update the results.

Parameters:
  • next_page_token – a token that identifies the next page of results.

  • search_term – a search term to search items using full-text search.

  • page – the page number to fetch results; this is only supported for Jira Data Center (aka. on-premises)

Returns:

Nothing.

Handles the event when the user presses the “search” button or “ctrl+r”.

action_focus_widget(key: str) None

Focuses a widget based on the key pressed by the user.

Parameters:

key – the key the user pressed in the UI.

Returns:

Nothing.

action_copy_issue_url() None

Copy to the clipboard the URL of the item currently selected in the search results.

action_copy_issue_key() None

Copy to the clipboard the key of the item currently selected in the search results.

action_create_git_branch() None

Opens up a modal screen to allow the user to create Git branches.

async action_create_work_item() None

Handles the event to create a new work item.

async create_work_item(data: dict) None

Handles the event to create a work item after the user clicks on the “save” button in the create-work-item screen.

Parameters:

data – a dictionary with the details of the fields and values to create the item.

Returns:

Nothing.

async fetch_issue(selected_work_item_key: str, force_refresh: bool = False) None

Retrieves the details of a work item selected by the user in the search results.

This is triggered from the datatable that holds the search results: IssuesSearchResultsTable

Every time a user selects a work item in the search results the application will do the following:

  • retrieve the details of the work item by sending a request to the API’s get_issue method.

  • update the information on the description tab (summary and description)

  • retrieve the subtasks associated to the selected work item

  • update the data in all the other tabs

Parameters:
  • selected_work_item_key – the key of the work item selected by the user from the search results datatable.

  • force_refresh – if the currently selected work item needs to be reloaded and this is True then the screen fetches the detail sof the work item; otherwise it does not refresh the item. This is useful to avoid reloading the same issue being displayed, i.e. the one currently selected but, it helps to force the reload if the item’s details have been updated.

Returns:

None

async action_find_by_text() None

Opens a screen to allow the user to enter a term to search items by text.

clear_work_item_data(message: jiratui.widgets.search.IssuesSearchResultsTable.WorkItemDeleted) None

Clears the data of a selected item when the item is deleted.

When a work item is deleted and the item is the one currently being displayed in the information tabs on the right-hand panel let’s make sure we clean the forms and widgets. This way we avoid displaying the details of the item that was deleted. This is only done when the item deleted is the one currently being displayed.

Parameters:

message – the message sent by a widget, e.g. the DataTable that holds the search results, when a work item is deleted. The message contains the key of the work item that was deleted.

Returns:

None

ServerInfoScreen

class ServerInfoScreen(server_info: jiratui.models.JiraServerInfo | None = None)

Bases: textual.screen.ModalScreen

The screen that displays information of the Jira instance server.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

QuitScreen

class QuitScreen(name: str | None = None, id: str | None = None, classes: str | None = None)

Bases: textual.screen.ModalScreen[str]

Screen with a dialog to quit.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

ConfirmationScreen

class ConfirmationScreen(message: str | None = None)

Bases: textual.screen.ModalScreen[bool]

Screen with a dialog to confirm an action.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

ConfigFileScreen

class ConfigFileScreen(name: str | None = None, id: str | None = None, classes: str | None = None)

Bases: textual.screen.ModalScreen

The screen that displays the configuration settings.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

HelpScreen

class HelpScreen(anchor: str | None = None)

Bases: textual.screen.ModalScreen

The screen that displays help.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

ConfirmDeleteItemScreen

class ConfirmDeleteItemScreen(work_item_key: str)

Bases: textual.screen.ModalScreen[bool]

A modal screen that allows users to confirm deleting an item.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

JQLEditorScreen

class JQLEditorScreen(content: str | None = None)

Bases: textual.screen.ModalScreen[str]

A screen that displays an editor for JQL expressions.

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

GitScreen

class GitScreen(work_item_key: str)

Bases: textual.screen.ModalScreen[bool]

A modal screen that allows the user to create a new Git branch on a target repository.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

TextSearchScreen

class TextSearchScreen(name: str | None = None, id: str | None = None, classes: str | None = None)

Bases: textual.screen.ModalScreen[str]

A modal screen that shows an input field to allow the user to provide a text for searching work items using full-text search.

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

DisplayTextContentScreen

class DisplayTextContentScreen(content: str, title: str | None = None)

Bases: textual.screen.ModalScreen

compose() textual.app.ComposeResult

EditTextContentScreen

class EditTextContentScreen(content: str, jira_field_key: str, title: str | None = None)

Bases: textual.screen.Screen[dict]

A modal screen that displays a TextArea editor to allow users to edit Plain Text/Markdown content.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

FlagWorkItemScreen

class FlagWorkItemScreen(work_item_key: str, work_item_is_flagged: bool = False)

Bases: textual.screen.Screen[dict]

A modal screen to allow the user to add/remove a flag to a work item.

The screen’s result is a dictionary with the following keys: { ‘update_flag’: if True then the issue’s flag will be added or removed. ‘note’: an optional comment. }

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

WorkItemReadOnlyDetailsScreen

class WorkItemReadOnlyDetailsScreen(work_item_key: str)

Bases: textual.screen.ModalScreen

A modal screen that displays the details of a work item in read-only mode.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

WorkItemWorkLogScreen

class WorkItemWorkLogScreen(work_item_key: str)

Bases: textual.screen.Screen[dict]

A screen that displays the work logs of a work item.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult
on_work_log_collapsible_deleted(message: jiratui.widgets.work_item_details.work_log.WorkLogCollapsible) None

Refreshes the subtitle of the main container to reflect the number of work logs remaining after deleting one.

async fetch_work_log() None

Retrieves the work log data associated to a work item and updates the details in the screen.

Returns:

None.

LogWorkScreen

class LogWorkScreen(work_item_key: str, current_remaining_estimate: str | None = None)

Bases: textual.screen.Screen[dict]

A modal screen to allow the user to log work for a work item.

The screen’s result is a dictionary with the following keys:

1{
2    'key': the key of the issue whose work lo we are updating.
3    'time_spent': the time spent as provided by the user in the screen's form.
4    'time_remaining': the time remaining as provided by the user in the screen's form.
5    'description': an optional as provided by the user in the screen's form.
6    'started': an optional datetime string.
7    'current_remaining_estimate': the issue's current remaining time.
8}

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

AddRemoteLinkScreen

class AddRemoteLinkScreen(work_item_key: str | None = None)

Bases: textual.screen.Screen[dict]

A screen that allows a user to add a new remote link, aka. web link, to a work item.

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

AddWorkItemRelationshipScreen

class AddWorkItemRelationshipScreen(work_item_key: str | None = None)

Bases: textual.screen.Screen[dict]

A modal screen that allows users to relate 2 work items.

The screen does not create the relationship between the work items. Instead, it returns the relationship’s data to the caller via the dismiss() call and the caller will proceed to create the relationship via the API.

The screen sends back the caller the following dictionary:

1{
2    'right_issue_key': 'WI-123',
3    'link_type': 'relates-to',
4    'link_type_id': 1,
5}

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

AddWorkItemScreen

class AddWorkItemScreen(project_key: str | None = None, reporter_account_id: str | None = None, parent_work_item_key: str | None = None)

Bases: textual.screen.Screen[dict[str, typing.Any]]

A modal screen for creating work items.

The screen is pushed from the main screen of the application. It is responsible for:

  • Displaying a form to allow the user to fill in the basic details to create the work item.

  • Building the required Widgets for the form based on the metadata associated to the project and type of work item being created.

The screen uses the API to:

  • Retrieve the list of projects

  • Retrieve the list of work items types associated to the selected project

  • Retrieve the necessary metadata for creating the work item in within the project.

  • Verify that the reporter provided to the screen does actually exist.

The screen can be initialized with:

  • A project key

  • The account ID of the reporter

  • An optional key that identifies the parent item of the work item being created. This is useful when the screen is open from the Widget that shows the list of subtasks associated to an item.

Important

This screen does not actually create the work item. Instead, upon dismissing the screen the caller will receive the necessary data to create the work item via the Jira API.

See Also:

Initialization

Initializes the screen.

Parameters:
  • project_key – the key of the project for which the work item will be created. If not defined the user will need to choose it from a dropdown list.

  • reporter_account_id – the account id of the user that acts as a reporter. This is injected from the main screen which in turn can be picked up from the cli or the configuration file. If not defined the user will need to choose it from a dropdown list.

  • parent_work_item_key – the key of the parent work item to which this work item belongs. If not defined the user will be able to set one.

compose() textual.app.ComposeResult
on_mount()

Mounts the widgets.

This fetches the required data to populate the widgets.

  1. It fetches the available projects.

  2. It fetches the available types of issues that can be created.

  3. If the reporter account id is set and the reporter field is editable then this will also fetch the details of the user identified by the reporter account and will set the reporter dropdown if the user exists.

  4. It mounts the autocomplete widgets required for selecting reporter and assignee.

async fetch_available_projects() None

Fetches the available projects and updates the project dropdown widget.

async fetch_available_issue_types(project_key: str | None = None) None

Fetches the applicable types of work items for the selected project and updates the issue type dropdown widget.

This also removes all the dynamically-created textarea-based widgets. This does not remove the pane that contains the description widget.

Parameters:

project_key – the key of the project selected by the user.

Returns:

None

handle_project_selection() None

Fetches the applicable types of work items for creating issues in the selected project.

This also:

  • updates the status of the “Save” button.

  • remove all the panes used for displaying textarea-based field widgets.

Returns:

None.

handle_issue_type_selection() None

Fetches metadata for creating issues in the selected project and of the selected type.

This also updates the status of the “Save” button.

Returns:

None.

handle_reporter_selection() None

Updates the status of the “Save” button after the user selects a Reporter.

handle_summary_value_change() None

Updates the status of the “Save” button after the user updates the summary field.

handle_description_value_change() None

Updates the status of the “Save” button after the user updates the description field.

async fetch_issue_create_metadata(project_key: str, issue_type_id: str) None

Fetches the metadata for creating work items of a given type in the given project.

This function does a few things:

  • Retrieves the metadata for creating work items of a given type in the given project.

  • Builds and mounts the necessary widgets that compose the create-work-item form.

Parameters:
  • project_key – the key of the project for which we want to create a work item.

  • issue_type_id – the type of work item we want to create.

Returns:

None

handle_save() None

Builds the necessary payload data for creating a new work item.

This does not actually create the work item. Instead, it passes the payload data to the main screen upon dismissal. The main screen is then responsible for requesting the API to create a new work item with the given payload.

Returns:

None

AddCommentScreen

class AddCommentScreen(work_item_key: str | None = None)

Bases: textual.screen.Screen[str]

A modal screen that allows users to add a comment to a work item.

The screen does not add the comment to the work item. Instead, it returns the comment’s text to the caller via the dismiss() call and the caller will proceed to add the comment via the API.

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

ViewAttachmentScreen

class ViewAttachmentScreen(attachment_id: str, attachment_file_type: str, attachment_file_name: str)

Bases: textual.screen.ModalScreen

A modal screen to display files attached to a work item.

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

compose() textual.app.ComposeResult

AddAttachmentScreen

class AddAttachmentScreen(work_item_key: str | None = None)

Bases: textual.screen.Screen[str]

The screen to select files to attach and attach them to a work item.

See Also:

Initialization

Initialize the screen.

Parameters:
  • name – The name of the screen.

  • id – The ID of the screen in the DOM.

  • classes – The CSS classes for the screen.

DEFAULT_ATTACHMENTS_SOURCE_DIRECTORY

‘/’

The default source directory for searching files to attach. This can be overridden by the config variable attachments_source_directory

compose() textual.app.ComposeResult