Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/entries/content.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { setupContentUi } from '@/features/content-ui'
import { createSprintHeaderInjector, injectStatusBarSprintButton } from '@/features/sprint-injections'
import {
createSprintHeaderInjector,
injectStatusBarSprintButton,
} from '@/features/sprint-injections'
import {
injectTableEnhancementStyles,
initDragAndDrop,
Expand Down Expand Up @@ -49,7 +52,7 @@ export default defineContentScript({
projectContext.isOrg,
)

const injectSprintHeaders = createSprintHeaderInjector(projectContext, getFields)
const injectSprintHeaders = createSprintHeaderInjector(ctx, projectContext, getFields)
const injectHierarchyChips = createHierarchyChipInjector(projectContext)
const cleanupIssueDetail = setupIssueDetailInjector(projectContext)
const cleanupTableEnhancements = setupTableEnhancements([
Expand Down
14 changes: 14 additions & 0 deletions src/features/__tests__/bulk-edit-flyout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,20 @@ describe('bulk-edit — partitionFieldList', () => {
if (partition.mode !== 'search') return
expect(partition.matches.filter((f) => f.id === relationshipFieldId('parent'))).toHaveLength(1)
})

it('browse mode with no recents yields empty Recent section data', () => {
const partition = partitionFieldList({
fields: baseFields,
recentIds: [],
query: '',
})
expect(partition.mode).toBe('browse')
if (partition.mode !== 'browse') return
expect(partition.recent).toEqual([])
expect(partition.issueProperties.map((f) => f.name)).toEqual(['Comment', 'Description'])
expect(partition.projectFields.map((f) => f.name)).toEqual(['Alpha', 'Status', 'Zeta'])
expect(partition.relationships.map((f) => f.name)).toEqual(['Blocked by', 'Blocking', 'Parent'])
})
})

describe('bulk-edit — buildRelationshipsPayload', () => {
Expand Down
142 changes: 26 additions & 116 deletions src/features/bulk-actions-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { exportSelectedToCSV } from '@/features/bulk-utils'
import type { ProjectData, ProjectField } from '@/features/bulk-edit-utils'
Comment thread
fathiraz marked this conversation as resolved.
import type { ReorderOp } from '@/features/bulk-move-utils'
import { ListCheckIcon, TagIcon, XIcon } from '@/ui/icons'
import { primerCss } from '@/lib/primer-css-helper'
import { Z_OVERLAY } from '@/lib/z-index'
import { BulkActionsMenu } from '@/features/bulk-actions-menu'
import { BulkActionsModals } from '@/features/bulk-actions-modals'
Expand All @@ -28,18 +29,7 @@ export type { ReorderOp } from '@/features/bulk-move-utils'
const RECENT_FIELDS_CAP = 3

/** Shared chip styling for the three top-level inline actions on the bar. */
const chipSx = {
boxShadow: 'none',
display: 'inline-flex',
alignItems: 'center',
transition: '150ms cubic-bezier(0.4, 0, 0.2, 1)',
'&:hover:not(:disabled)': { transform: 'translateY(-1px)' },
'&:active': { transform: 'translateY(0)', transition: '100ms' },
'@media (prefers-reduced-motion: reduce)': {
transition: 'none',
'&:hover:not(:disabled)': { transform: 'none' },
},
} as const
const chipSx = primerCss.chipButton()

interface Props {
projectId: string
Expand Down Expand Up @@ -72,27 +62,12 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
const [randomAssignOpen, setRandomAssignOpen] = useState(false)
const [showCloseModal, setShowCloseModal] = useState(false)
const [closeReason, setCloseReason] = useState<'COMPLETED' | 'NOT_PLANNED'>('COMPLETED')
const [showOpenModal, setShowOpenModal] = useState(false)
const [showDeleteModal, setShowDeleteModal] = useState(false)
const [deleteItemTitles, setDeleteItemTitles] = useState<string[]>([])
const [showLockModal, setShowLockModal] = useState(false)
const [lockReason, setLockReason] = useState<
'OFF_TOPIC' | 'TOO_HEATED' | 'RESOLVED' | 'SPAM' | null
>(null)
const [showPinModal, setShowPinModal] = useState(false)
const [showUnpinModal, setShowUnpinModal] = useState(false)
const [showTransferModal, setShowTransferModal] = useState(false)
const [showHelp, setShowHelp] = useState(false)
const anyModalOpen =
showCloseModal ||
showOpenModal ||
showDeleteModal ||
showLockModal ||
showPinModal ||
showUnpinModal ||
showTransferModal ||
showDupModal ||
showHelp
showCloseModal || showDeleteModal || showTransferModal || showDupModal || showHelp
const anyFlyoutOpen = editFieldsOpen || renameOpen || reorderOpen || randomAssignOpen || markOpen

const resolvedProjectId = projectData?.id || projectId
Expand All @@ -106,11 +81,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
setMenuOpen(false)
setShowDupModal(false)
setShowCloseModal(false)
setShowOpenModal(false)
setShowDeleteModal(false)
setShowLockModal(false)
setShowPinModal(false)
setShowUnpinModal(false)
setShowTransferModal(false)
setShowHelp(false)
setMarkOpen(false)
Expand Down Expand Up @@ -163,11 +134,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
if (anyModalOpen || anyFlyoutOpen) {
setShowDupModal(false)
setShowCloseModal(false)
setShowOpenModal(false)
setShowDeleteModal(false)
setShowLockModal(false)
setShowPinModal(false)
setShowUnpinModal(false)
setShowTransferModal(false)
setShowHelp(false)
setEditFieldsOpen(false)
Expand Down Expand Up @@ -246,7 +213,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
modifiers: { meta: true, shift: true },
context: 'Table Selection',
label: 'Close Issues',
action: handleBulkClose,
action: () => handleBulkClose(),
})

reg({
Expand All @@ -255,7 +222,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
modifiers: { meta: true, shift: true },
context: 'Table Selection',
label: 'Reopen Issues',
action: handleBulkOpen,
action: () => runMarkVerb('reopen'),
})

reg({
Expand All @@ -264,7 +231,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
modifiers: { meta: true, shift: true },
context: 'Table Selection',
label: 'Lock Conversations',
action: handleLock,
action: () => runMarkVerb('lock'),
})

reg({
Expand All @@ -273,7 +240,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
modifiers: { meta: true, shift: true },
context: 'Table Selection',
label: 'Pin Issues',
action: handlePin,
action: () => runMarkVerb('pin'),
})

reg({
Expand Down Expand Up @@ -493,66 +460,10 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
// §3 selection policy — Random Assign preserves selection.
}

async function handleBulkClose() {
setMenuOpen(false)
if (!(await checkToken())) return
setShowCloseModal(true)
}

function handleConfirmClose() {
const itemIds = selectionStore.getAll()
setShowCloseModal(false)
sendMessage('bulkClose', { itemIds, projectId: resolvedProjectId, reason: closeReason })
selectionStore.clear()
}

async function handleBulkOpen() {
async function runMarkVerb(verb: MarkVerb) {
setMenuOpen(false)
if (!(await checkToken())) return
setShowOpenModal(true)
}

function handleConfirmOpen() {
const itemIds = selectionStore.getAll()
setShowOpenModal(false)
sendMessage('bulkOpen', { itemIds, projectId: resolvedProjectId })
}

async function handleLock() {
setMenuOpen(false)
if (!(await checkToken())) return
setShowLockModal(true)
}

function handleConfirmLock() {
const itemIds = selectionStore.getAll()
setShowLockModal(false)
sendMessage('bulkLock', { itemIds, projectId: resolvedProjectId, lockReason })
selectionStore.clear()
}

async function handlePin() {
setMenuOpen(false)
if (!(await checkToken())) return
setShowPinModal(true)
}

function handleConfirmPin() {
const itemIds = selectionStore.getAll()
setShowPinModal(false)
sendMessage('bulkPin', { itemIds, projectId: resolvedProjectId })
}

async function _handleUnpin() {
setMenuOpen(false)
if (!(await checkToken())) return
setShowUnpinModal(true)
}

function handleConfirmUnpin() {
const itemIds = selectionStore.getAll()
setShowUnpinModal(false)
sendMessage('bulkUnpin', { itemIds, projectId: resolvedProjectId })
handleMarkVerb(verb)
}

async function handleTransfer() {
Expand Down Expand Up @@ -625,6 +536,20 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
// §3 selection policy — Reorder preserves selection.
}

async function handleBulkClose() {
setMenuOpen(false)
if (!(await checkToken())) return
if (selectionStore.count() === 0) return
setShowCloseModal(true)
Comment thread
fathiraz marked this conversation as resolved.
}

function handleConfirmClose() {
const itemIds = selectionStore.getAll()
setShowCloseModal(false)
sendMessage('bulkClose', { itemIds, projectId: resolvedProjectId, reason: closeReason })
selectionStore.clear()
}

function handleMarkVerb(verb: MarkVerb) {
setMarkOpen(false)
const itemIds = selectionStore.getAll()
Expand All @@ -633,7 +558,7 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
sendMessage('bulkClose', {
itemIds,
projectId: resolvedProjectId,
reason: closeReason,
reason: 'COMPLETED',
})
selectionStore.clear()
return
Expand Down Expand Up @@ -663,8 +588,8 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
A: { action: () => handleRandomAssign() },
M: { action: () => setMarkOpen((open) => !open) },
C: { action: () => handleBulkClose() },
P: { action: () => handlePin() },
L: { action: () => handleLock() },
P: { action: () => runMarkVerb('pin') },
L: { action: () => runMarkVerb('lock') },
T: { action: () => handleTransfer() },
D: {
action: () => {
Expand All @@ -689,30 +614,15 @@ export function BulkActionsBar({ projectId, owner, isOrg, number, getFields }: P
owner={owner}
isOrg={isOrg}
number={number}
firstRepoName={firstRepoName}
showCloseModal={showCloseModal}
closeReason={closeReason}
onChangeCloseReason={setCloseReason}
onCloseCloseModal={() => setShowCloseModal(false)}
onConfirmClose={handleConfirmClose}
showOpenModal={showOpenModal}
onCloseOpenModal={() => setShowOpenModal(false)}
onConfirmOpen={handleConfirmOpen}
showDeleteModal={showDeleteModal}
deleteItemTitles={deleteItemTitles}
onCloseDeleteModal={() => setShowDeleteModal(false)}
onConfirmDelete={handleConfirmDelete}
showLockModal={showLockModal}
lockReason={lockReason}
onChangeLockReason={setLockReason}
onCloseLockModal={() => setShowLockModal(false)}
onConfirmLock={handleConfirmLock}
showPinModal={showPinModal}
onClosePinModal={() => setShowPinModal(false)}
onConfirmPin={handleConfirmPin}
showUnpinModal={showUnpinModal}
onCloseUnpinModal={() => setShowUnpinModal(false)}
onConfirmUnpin={handleConfirmUnpin}
showTransferModal={showTransferModal}
onCloseTransferModal={() => setShowTransferModal(false)}
onConfirmTransfer={handleConfirmTransfer}
Expand Down
Loading
Loading