import type { SampleGroup } from '../types' import { getSampleGroupMajorPrefix } from '../utils/sampleGroupPath' export { getSampleGroupMajorPrefix, getSampleGroupParentPath, splitSampleGroupPath, } from '../utils/sampleGroupPath' export type GroupDragKind = 'major' | 'sub' | 'flat' export type GroupReorderPosition = 'before' | 'after' export function detectSampleGroupSeparator(groups: SampleGroup[]): string { return groups.some(group => group.name.includes('/')) ? '/' : '_' } export function moveSampleToGroup( groups: SampleGroup[], sample: string, sourceGroup: string | null, targetGroup: string, ): SampleGroup[] { if (sourceGroup === targetGroup) return groups return groups.map(group => { if (sourceGroup && group.name === sourceGroup) { return { ...group, samples: group.samples.filter(item => item !== sample) } } if (group.name === targetGroup && !group.samples.includes(sample)) { return { ...group, samples: [...group.samples, sample] } } return group }) } /** * Drop every named group. Callers pass the concrete group names beneath the * node being removed, so one helper covers a single group, a whole family, or * any intermediate hierarchy level. */ export function removeSampleGroups(groups: SampleGroup[], groupNames: string[]): SampleGroup[] { const removing = new Set(groupNames) return groups.filter(group => !removing.has(group.name)) } export function removeSampleFromGroup( groups: SampleGroup[], sample: string, groupName: string, ): SampleGroup[] { return groups.map(group => group.name === groupName ? { ...group, samples: group.samples.filter(item => item !== sample) } : group, ) } export function reorderSampleGroup( groups: SampleGroup[], source: string, target: string, position: GroupReorderPosition, ): SampleGroup[] { if (source === target) return groups const nextGroups = [...groups] const sourceIndex = nextGroups.findIndex(group => group.name === source) if (sourceIndex === -1) return groups const [item] = nextGroups.splice(sourceIndex, 1) const targetIndex = nextGroups.findIndex(group => group.name === target) if (targetIndex === -1) return groups nextGroups.splice(position === 'before' ? targetIndex : targetIndex + 1, 0, item) return nextGroups } export function reorderSampleMajorGroup( groups: SampleGroup[], source: string, target: string, position: GroupReorderPosition, ): SampleGroup[] { if (source === target) return groups const separator = detectSampleGroupSeparator(groups) const isSource = (group: SampleGroup) => getSampleGroupMajorPrefix(group.name, separator) === source const isTarget = (group: SampleGroup) => getSampleGroupMajorPrefix(group.name, separator) === target const sourceGroups = groups.filter(isSource) if (sourceGroups.length === 0) return groups const remainingGroups = groups.filter(group => !isSource(group)) let firstTargetIndex = -1 let lastTargetIndex = -1 remainingGroups.forEach((group, index) => { if (isTarget(group)) { if (firstTargetIndex === -1) firstTargetIndex = index lastTargetIndex = index } }) if (firstTargetIndex === -1) return groups const insertIndex = position === 'before' ? firstTargetIndex : lastTargetIndex + 1 remainingGroups.splice(insertIndex, 0, ...sourceGroups) return remainingGroups }