Skip to main content
Version: 1.2.2

Customize State Model

You can modify the state model of SDLC Tasks and Subtasks to better suit your development process.

warning

When making a decision to modify the state model, take the following into account:

  • Changing the default state model will disrupt some features of the SDLC application, such as adding tasks to backlog and sprint planning. See below for more details.
  • The modifications may be overwritten by subsequent updates of the application.

Never change the system values of out-of-the-box states.

To customize the task state model, complete the following steps:

  1. Create required options for the State field
  2. Configure transitions for the new states
  3. Add columns for the new states to project boards

Create choice options


warning

Before creating choice options, ensure that the SDLC application is selected in the Admin Preferences of the sidebar.

To create choice options for a new state, complete the following steps:

  1. Navigate to System SettingsAll Tables.

  2. Find the Task (task) table and open its form.

  3. Go to the Related Lists area and open the Columns tab.

  4. Find the State (state) column and open its form.

  5. Go to the Related Lists area and open the Choice tab.

  6. Click New and fill in the fields:

    FieldDescription
    TableSelect the SDLC Task (pda_backlog_item) or Subtask (pda_subtask) table depending on the state model you need to modify.
    TitleSpecify the state title. It is recommended to make it unique for the selected Table.
    Language

    Specify the language for which the option is created:

    • ru for Russian
    • en for English
    ValueSpecify the value that will be used in the system logic. Use latin letters and digits. The value must not match any of the out-of-the-box states. It is recommended to make the value unique for the selected Table.
    OrderEnter a number to determine the position of the new state in the drop-down list relative to the existing states. The states are sorted in ascending order. It is recommended to assign order with an increment of 10 for an option in the middle of the list, and 100 for an option in the end of the list.
  7. Click Save or Save and exit to apply the changes.

  8. If necessary, repeat steps 6–7 for all languages used in the system. As a result, each state should have a choice option for each language that only differ by the Title and Language field values.

  9. (optional) To have the tasks in the new state highlighted with a color in the lists, create a corresponding style rule.

tip

Read the Choice Fields article to learn more about creating choice options.

Configure state transitions


warning

Adding custom states in certain points of the state flow will disrupt some of the system features.

When a custom state is added before the New or Backlog out-of-the-box states:

  • The tasks in custom states will not be displayed in the quick filters on the Add tasks to backlog and Sprint planning pages.
  • The number of incomplete tasks will be calculated incorrectly when publishing a release.
  • The task state may fail to change from New to Backlog when starting a sprint.
  • Some fields on the task forms may behave incorrectly.

When a custom state is added between the Backlog and Done out-of-the-box states:

  • The tasks in custom states will not be displayed in the All available tasks and Current project tasks quick filters on the Add tasks to backlog and Sprint planning pages.
  • The number of incomplete tasks will be calculated incorrectly when publishing a release.
  • Some fields on the task forms may behave incorrectly.

Modifying the Subtask state model may cause the subtask lists on the project board cards to be displayed incorrectly.

To configure the transitions between the new states, complete the following steps:

  1. Navigate to State Flow DesignerState Models.
  2. Find the Backlog item (for SDLC Tasks) or Subtask (for Subtasks) record and open its form.
  3. Go to the Related Lists area and open the State Transition tab.
  4. Create incoming transitions:
    1. Click the title of the state, from which you need to make available the transition into the new state.
    2. Add the new state into the Available transitions field and click Save.
  5. Return to the state model form and, if necessary, repeat step 4 for all incoming transitions.
  6. Create outgoing transitions:
    1. Click New in the State Transition related list.
    2. Specify the new state in the State field.
    3. Add all states, into which you need to make available the transition from the new state, in the Available transitions field.
    4. Click Save.
tip

Read the State Flow Designer article to learn more about configuring state models.

Add new states to project boards


When you create new projects after customizing the state model, the custom states will be automatically added to the project board as columns.

To add columns for the custom states to an existing project board, complete the following steps:

  1. Navigate to System SettingServer Scripts.

  2. Click New.

  3. Replace the text in the Script field with the following:

    Script for adding custom states to an existing project board

    const BOARD_ID = 'XXXXXXXXXXXXXXXXXXXXXXXXXX';

    const languagesIds = getLanguagesIds();
    const newStateChoices = getNewStateChoices();
    const createdColumnIds = createAllColumns(newStateChoices);

    if (Object.keys(newStateChoices).length !== createdColumnIds.length) {
    ss.error('An error occurred while creating columns. The number of created columns does not match the expected number.');
    }

    function getBoardColumns() {
    const columns = [];

    const column = new SimpleRecord('board_column');
    column.addQuery('board_id', BOARD_ID);
    column.orderBy('order');
    column.query();

    while (column.next()) {
    columns.push({
    stateValue: column.state.value,
    order: column.order,
    });
    }

    return columns;
    }

    function getNewStateChoices() {
    const SDLC_TASK_TABLE_ID = '169113996804005414';
    const COLUMN_STATE_ID = '155931135900001086';
    const boardColumns = getBoardColumns();
    const choices = {};
    let order = boardColumns[boardColumns.length - 1].order + 100;

    const choice = new SimpleRecord('sys_choice');
    choice.addQuery('table_id', SDLC_TASK_TABLE_ID);
    choice.addQuery('column_id', COLUMN_STATE_ID);
    choice.addQuery('value', 'NOT IN', boardColumns.map(column => column.stateValue));
    choice.selectAttributes(['value', 'title', 'language']);
    choice.orderBy('order');
    choice.query();

    while (choice.next()) {
    if (!choices.hasOwnProperty(choice.value)) {
    choices[choice.value] = {
    title: {},
    stateId: '',
    order,
    };

    order += 100;
    }

    choices[choice.value].title[choice.language] = choice.title;

    if (!choices[choice.value].stateId) {
    choices[choice.value].stateId = choice.sys_id;
    }
    }

    return choices;
    }

    function createColumn(columnParameters) {
    const column = new SimpleRecord('board_column');
    column.board_id = BOARD_ID;
    column.state = columnParameters.stateId;
    column.order = columnParameters.order;
    column.active = true;

    const columnId = column.insert();

    if (!+columnId) {
    ss.error(column.getErrors().join('; '));
    }

    return columnId;
    }

    function createAllColumns(newStateChoices) {
    const createdColumnIds = [];

    for (const stateChoice in newStateChoices) {
    const createdColumnId = createColumn(newStateChoices[stateChoice]);
    createdColumnIds.push(createdColumnId);
    const titles = Object.entries(newStateChoices[stateChoice].title);
    titles.forEach(titleAttributes => createTranslationForColumn(createdColumnId, titleAttributes));
    }

    return createdColumnIds;
    }

    function createTranslationForColumn(columnId, titleAttributes) {
    const TITLE_COLUMN_ID = '169416863206684038';
    const [language, value] = titleAttributes;

    const translation = new SimpleRecord('sys_translation');
    translation.column_id = TITLE_COLUMN_ID;
    translation.language_id = languagesIds[language];
    translation.value = value;
    translation.record_id = columnId;

    if (!+translation.insert()) {
    ss.error(translation.getErrors().join('; '));
    }
    }

    function getLanguagesIds() {
    const languagesIds = {};

    const language = new SimpleRecord('sys_language');
    language.selectAttributes('language');
    language.query();

    while (language.next()) {
    languagesIds[language.language] = language.sys_id;
    }

    return languagesIds;
    }

  4. Replace the XXXXXXXXXXXXXXXXXX in the line const BOARD_ID = 'XXXXXXXXXXXXXXXXXX'; with the project board ID. To find it, open the required project board and copy the ID from the browser's address bar.

  5. Click Run. Saving the record is not required.

  6. If necessary, repeat steps 4-5 for all project boards to which you need to add columns for custom states.