BE: Fix empty projects list in modal of child work items
What does this MR do and why?
This MR does two things:
- Adds
work_item_types
field toNamespaceType
- Make
namespace.projects
support forProjectNamespace
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
- Run above mentioned queries to get expected results for project/group namespaces
Edited by Abhilash Kotte