Skip to content

BE: Fix empty projects list in modal of child work items

What does this MR do and why?

This MR does two things:

  1. Adds work_item_types field to NamespaceType
  2. Make namespace.projects support for ProjectNamespace and return projects from parent group

These will be used to replace project/group level fetching and we can use this single query to get work_item_types and linkable projects for project/group.

This will be first step to fix #470371 (closed) and FE changes can be tracked here !158570 (merged)

more context can be found here - #470371 (comment 1983029667)

GraphQl Queries

Projects at Group level
query groupProjectsForLinksWidget($fullPath: ID!, $projectSearch: String) {
  namespace(fullPath: $fullPath) {
    id
    projects(search: $projectSearch, includeSubgroups: true) {
      nodes {
        id
        name
        avatarUrl
        nameWithNamespace
        fullPath
        namespace {
          id
          name
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}

Variables:

{
  "fullPath": "flightjs",
  "projectSearch": ""
}

Response:

{
  "data": {
    "namespace": {
      "id": "gid://gitlab/Group/33",
      "projects": {
        "nodes": [
          {
            "id": "gid://gitlab/Project/7",
            "name": "Flight",
            "avatarUrl": null,
            "nameWithNamespace": "Flightjs / Flight",
            "fullPath": "flightjs/Flight",
            "namespace": {
              "id": "gid://gitlab/Group/33",
              "name": "Flightjs",
              "__typename": "Namespace"
            },
            "__typename": "Project"
          }
        ],
        "__typename": "ProjectConnection"
      },
      "__typename": "Namespace"
    }
  }
}
Projects at project level(return projects under parent group)
query linkableProjectsForLinksWidget($fullPath: ID!, $projectSearch: String) {
  namespace(fullPath: $fullPath) {
    id
    projects(search: $projectSearch, includeSubgroups: true) {
      nodes {
        id
        name
        avatarUrl
        nameWithNamespace
        fullPath
        namespace {
          id
          name
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}

Variables:

{
  "fullPath": "flightjs/Flight",
  "projectSearch": ""
}

Response:

{
  "data": {
    "namespace": {
      "id": "gid://gitlab/Namespaces::ProjectNamespace/34",
      "projects": {
        "nodes": [
          {
            "id": "gid://gitlab/Project/7",
            "name": "Flight",
            "avatarUrl": null,
            "nameWithNamespace": "Flightjs / Flight",
            "fullPath": "flightjs/Flight",
            "namespace": {
              "id": "gid://gitlab/Group/33",
              "name": "Flightjs",
              "__typename": "Namespace"
            },
            "__typename": "Project"
          }
        ],
        "__typename": "ProjectConnection"
      },
      "__typename": "Namespace"
    }
  }
}
WorkItem Types at Namespace level
query groupWorkItemTypes($fullPath: ID!, $name: IssueType) {
  workspace: namespace(fullPath: $fullPath) {
    id
    workItemTypes(name: $name) {
      nodes {
        ...WorkItemTypeFragment
        __typename
      }
      __typename
    }
    __typename
  }
}

fragment WorkItemTypeFragment on WorkItemType {
  id
  name
  widgetDefinitions {
    type
    ... on WorkItemWidgetDefinitionAssignees {
      allowsMultipleAssignees
      canInviteMembers
      __typename
    }
    ... on WorkItemWidgetDefinitionLabels {
      allowsScopedLabels
      __typename
    }
    __typename
  }
  __typename
}
Response

{
  "data": {
    "workspace": {
      "id": "gid://gitlab/Namespaces::ProjectNamespace/34",
      "workItemTypes": {
        "nodes": [
          {
            "id": "gid://gitlab/WorkItems::Type/8",
            "name": "Epic",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "LABELS",
                "allowsScopedLabels": true,
                "__typename": "WorkItemWidgetDefinitionLabels"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "START_AND_DUE_DATE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HEALTH_STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "COLOR",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "ROLLEDUP_DATES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/2",
            "name": "Incident",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "DEVELOPMENT",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/1",
            "name": "Issue",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "LABELS",
                "allowsScopedLabels": true,
                "__typename": "WorkItemWidgetDefinitionLabels"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "START_AND_DUE_DATE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "MILESTONE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "ITERATION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "WEIGHT",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HEALTH_STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "DESIGNS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "DEVELOPMENT",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/7",
            "name": "Key Result",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "LABELS",
                "allowsScopedLabels": true,
                "__typename": "WorkItemWidgetDefinitionLabels"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "START_AND_DUE_DATE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HEALTH_STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PROGRESS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/6",
            "name": "Objective",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "LABELS",
                "allowsScopedLabels": true,
                "__typename": "WorkItemWidgetDefinitionLabels"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "MILESTONE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HEALTH_STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PROGRESS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/4",
            "name": "Requirement",
            "widgetDefinitions": [
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "REQUIREMENT_LEGACY",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TEST_REPORTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/5",
            "name": "Task",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "LABELS",
                "allowsScopedLabels": true,
                "__typename": "WorkItemWidgetDefinitionLabels"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "START_AND_DUE_DATE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "MILESTONE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "ITERATION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "WEIGHT",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/3",
            "name": "Test Case",
            "widgetDefinitions": [
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          },
          {
            "id": "gid://gitlab/WorkItems::Type/9",
            "name": "Ticket",
            "widgetDefinitions": [
              {
                "type": "ASSIGNEES",
                "allowsMultipleAssignees": true,
                "canInviteMembers": false,
                "__typename": "WorkItemWidgetDefinitionAssignees"
              },
              {
                "type": "LABELS",
                "allowsScopedLabels": true,
                "__typename": "WorkItemWidgetDefinitionLabels"
              },
              {
                "type": "DESCRIPTION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HIERARCHY",
                "__typename": "WorkItemWidgetDefinitionHierarchy"
              },
              {
                "type": "START_AND_DUE_DATE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "MILESTONE",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTES",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "ITERATION",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "WEIGHT",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "HEALTH_STATUS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "NOTIFICATIONS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "CURRENT_USER_TODOS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "AWARD_EMOJI",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "LINKED_ITEMS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "PARTICIPANTS",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              },
              {
                "type": "TIME_TRACKING",
                "__typename": "WorkItemWidgetDefinitionGeneric"
              }
            ],
            "__typename": "WorkItemType"
          }
        ],
        "__typename": "WorkItemTypeConnection"
      },
      "__typename": "Namespace"
    }
  }
}

SQL QUERY FOR NAMESPACE WORK_ITEM_TYPES

SELECT "work_item_types".* FROM "work_item_types" WHERE "work_item_types"."namespace_id" IS NULL ORDER BY LOWER("work_item_types"."name") ASC, "work_item_types"."id" DESC LIMIT 101

Query plan: https://console.postgres.ai/gitlab/gitlab-production-main/sessions/29701/commands/92204

Screenshots or screen recordings

No UI Changes

How to set up and validate locally

  1. Run above mentioned queries to get expected results for project/group namespaces
Edited by Abhilash Kotte

Merge request reports