Skip to content

Commit 293b2b5

Browse files
committed
fix: preserve child creation context and portable coverage queries
1 parent c49d3d6 commit 293b2b5

6 files changed

Lines changed: 38 additions & 55 deletions

File tree

frontend/src/lib/dialogs/CreateModal.svelte

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
compactMode = false,
6464
initialType = 'work-item',
6565
initialWorkspaceId = null,
66+
initialParentContext = null,
6667
skipNavigate = false,
6768
onclose = null,
6869
oncreated = null
@@ -375,6 +376,15 @@
375376
}
376377
});
377378
379+
$effect(() => {
380+
if (isOpen && initialParentContext) {
381+
untrack(() => workItemFormStore.setParentItem(
382+
initialParentContext.parent,
383+
initialParentContext.allowedItemTypes,
384+
));
385+
}
386+
});
387+
378388
// Force work-item type when compact mode is enabled
379389
$effect(() => {
380390
if (compactMode && selectedType !== 'work-item') {
@@ -509,7 +519,7 @@
509519
<ChevronRight size={14} style="color: var(--ds-text-subtle);" />
510520
{/if}
511521
512-
<span class="font-medium" style="color: var(--ds-text);">
522+
<span data-testid="create-modal-heading" class="font-medium" style="color: var(--ds-text);">
513523
{#if workItemFormStore.parentItem}
514524
{t('createModal.newChildItem')}
515525
{:else}

frontend/src/lib/features/items/ItemDetail.svelte

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,48 +1180,24 @@ import NativeSelect from '../../components/NativeSelect.svelte';
11801180
loadRecurrence();
11811181
}
11821182
1183-
// Sub-issue creation function
11841183
function startCreateSubIssue() {
11851184
if (itemDetailStore.availableSubIssueTypes.length === 0) {
11861185
showError(t('items.noSubIssueTypes'), t('items.cannotCreateChildItems'));
11871186
return;
11881187
}
11891188
1190-
// Set up for sub-issue creation and open the global create modal
1191-
1192-
// First, trigger loading the CreateModal component
1193-
window.dispatchEvent(new CustomEvent('show-create-modal'));
1194-
1195-
// Small delay to let the modal load, then configure it
1196-
setTimeout(() => {
1197-
// Set the type first
1198-
window.dispatchEvent(new CustomEvent('set-create-type', {
1199-
detail: { type: 'work-item' }
1200-
}));
1201-
1202-
// Set the parent
1203-
window.dispatchEvent(new CustomEvent('set-create-parent', {
1204-
detail: {
1205-
parentId: itemDetailStore.item.id,
1206-
parentTitle: itemDetailStore.item.title,
1207-
availableItemTypes: itemDetailStore.availableSubIssueTypes
1208-
}
1209-
}));
1210-
1211-
// Open the modal (this will load workspaces)
1212-
window.dispatchEvent(new CustomEvent('open-create-modal'));
1213-
1214-
// After modal is open and workspaces are loaded, set the workspace
1215-
setTimeout(() => {
1216-
window.dispatchEvent(new CustomEvent('set-create-workspace', {
1217-
detail: {
1218-
workspaceId: workspaceId,
1219-
workspaceName: itemDetailStore.workspace?.name
1220-
}
1221-
}));
1222-
}, 200);
1223-
}, 150);
1189+
window.dispatchEvent(new CustomEvent('show-create-modal', {
1190+
detail: {
1191+
type: 'work-item',
1192+
workspaceId,
1193+
parentContext: {
1194+
parent: { id: itemDetailStore.item.id, title: itemDetailStore.item.title },
1195+
allowedItemTypes: itemDetailStore.availableSubIssueTypes,
1196+
},
1197+
},
1198+
}));
12241199
}
1200+
12251201
</script>
12261202
12271203
{#snippet contentSnippet()}

frontend/src/lib/features/items/ItemDetailDescription.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@
211211
{/if}
212212
{#if availableSubIssueTypes.length > 0}
213213
<button
214+
data-testid="item-create-child"
214215
class="action-btn inline-flex items-center gap-1.5 px-2 py-1.5 rounded text-xs transition-all"
215216
style="color: var(--ds-text-subtle);"
216217
onclick={() => oncreateSubIssue?.()}

frontend/src/lib/pages/MainApp.svelte

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
let createModalInitialType = $state('work-item');
5353
let createModalSkipNavigate = $state(false);
5454
let createModalWorkspaceId = $state(null);
55+
let createModalParentContext = $state(null);
5556
let showEmailVerificationBanner = $state(false);
5657
let mobileWorkspaceNavOpen = $state(false);
5758
@@ -146,6 +147,7 @@
146147
createModalInitialType = 'work-item';
147148
createModalSkipNavigate = false;
148149
createModalWorkspaceId = null;
150+
createModalParentContext = null;
149151
}
150152
151153
function closeAllSidebarSurfaces() {
@@ -156,6 +158,7 @@
156158
createModalInitialType = 'work-item';
157159
createModalSkipNavigate = false;
158160
createModalWorkspaceId = null;
161+
createModalParentContext = null;
159162
}
160163
161164
function activateSidebarSurface(surface) {
@@ -192,6 +195,7 @@
192195
function showCreateDropdown() {
193196
closeAllSidebarSurfaces();
194197
createModalWorkspaceId = null;
198+
createModalParentContext = null;
195199
const currentWorkspaceId = $currentRoute.params?.id;
196200
if (currentWorkspaceId && CREATE_MODAL_WORKSPACE_VIEWS.has($currentRoute.view)) {
197201
createModalWorkspaceId = Number.parseInt(currentWorkspaceId, 10);
@@ -204,6 +208,7 @@
204208
closeAllSidebarSurfaces();
205209
if (detail.type) createModalInitialType = detail.type;
206210
createModalSkipNavigate = detail.skipNavigate || false;
211+
createModalParentContext = detail.parentContext ?? null;
207212
createModalWorkspaceId = detail.workspaceId
208213
? Number.parseInt(String(detail.workspaceId), 10)
209214
: null;
@@ -404,6 +409,7 @@
404409
bind:showChatPanel
405410
{createModalInitialType}
406411
{createModalWorkspaceId}
412+
{createModalParentContext}
407413
{createModalSkipNavigate}
408414
onclosecreate={closeCreateModal}
409415
onclosecommand={closeCommandPalette}

frontend/src/lib/pages/MainAppOverlays.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
showChatPanel = $bindable(false),
1818
createModalInitialType = 'work-item',
1919
createModalWorkspaceId = null,
20+
createModalParentContext = null,
2021
createModalSkipNavigate = false,
2122
onclosecreate,
2223
onclosecommand = () => {},
@@ -115,6 +116,7 @@
115116
bind:isOpen={showCreateModal}
116117
initialType={createModalInitialType}
117118
initialWorkspaceId={createModalWorkspaceId}
119+
initialParentContext={createModalParentContext}
118120
skipNavigate={createModalSkipNavigate}
119121
onclose={onclosecreate}
120122
/>

internal/repository/test_coverage_repository.go

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -268,19 +268,9 @@ func (r *TestCoverageRepository) CountRequirements(params RequirementListParams)
268268
return 0, nil
269269
}
270270

271-
whereClause, havingClause, args := buildRequirementFilters(params)
271+
whereClause, args := buildRequirementFilters(params)
272272

273-
query := `
274-
SELECT COUNT(*) FROM (
275-
SELECT
276-
i.id,
277-
(` + coverageLinkedCountSubquery + `) as linked_count
278-
FROM items i
279-
` + whereClause + `
280-
GROUP BY i.id
281-
` + havingClause + `
282-
) sub
283-
`
273+
query := `SELECT COUNT(*) FROM items i ` + whereClause
284274

285275
var total int
286276
if err := r.db.QueryRow(query, args...).Scan(&total); err != nil {
@@ -295,7 +285,7 @@ func (r *TestCoverageRepository) ListRequirements(params RequirementListParams)
295285
return []models.RequirementCoverageItem{}, nil
296286
}
297287

298-
whereClause, havingClause, args := buildRequirementFilters(params)
288+
whereClause, args := buildRequirementFilters(params)
299289
args = append(args, params.Limit, params.Offset)
300290

301291
query := `
@@ -316,8 +306,6 @@ func (r *TestCoverageRepository) ListRequirements(params RequirementListParams)
316306
JOIN item_types it ON i.item_type_id = it.id
317307
LEFT JOIN statuses s ON i.status_id = s.id
318308
` + whereClause + `
319-
GROUP BY i.id
320-
` + havingClause + `
321309
ORDER BY i.created_at DESC
322310
LIMIT ? OFFSET ?
323311
`
@@ -413,7 +401,7 @@ func coverageWhereArgs(workspaceID int, typeIDs []int) (placeholders string, arg
413401
return strings.Join(slots, ","), args
414402
}
415403

416-
func buildRequirementFilters(params RequirementListParams) (where, having string, args []any) {
404+
func buildRequirementFilters(params RequirementListParams) (where string, args []any) {
417405
placeholders, filterArgs := coverageWhereArgs(params.WorkspaceID, params.TypeIDs)
418406
args = filterArgs
419407
where = "WHERE i.workspace_id = ? AND i.item_type_id IN (" + placeholders + ")"
@@ -425,9 +413,9 @@ func buildRequirementFilters(params RequirementListParams) (where, having string
425413

426414
switch params.CoveredFilter {
427415
case "true":
428-
having = " HAVING linked_count > 0"
416+
where += " AND (" + coverageLinkedCountSubquery + ") > 0"
429417
case "false":
430-
having = " HAVING linked_count = 0"
418+
where += " AND (" + coverageLinkedCountSubquery + ") = 0"
431419
}
432-
return where, having, args
420+
return where, args
433421
}

0 commit comments

Comments
 (0)