// imports import clsx from 'clsx'; import moment from 'moment'; import { Float } from '@headlessui-float/react'; import { Listbox } from '@headlessui/react'; import React, { useCallback, useEffect, useState } from 'react'; import { IconBranch, IconSearch, IconEdit, IconPlus } from '@chirper/react/src/icons'; // locals import Input from '../Input'; import Button from '../Button'; import useTeam from '../../hooks/useTeam'; import ApiSignal from '../../signals/Api'; import ButtonIcon from '../Button/Icon'; import { useSignal } from '../../signal'; import { useCommits } from '../../data/useCommit'; import { useBranches } from '../../data/useBranch'; import { DropdownItem } from '../Dropdown'; import { branch as BranchSignal } from './Modal'; /** * branch dropdown * * @param param0 * @returns */ const BranchDropdown = ({ value = null, workflow = null, onChange = (b) => {}, commit = null, onCommit = (c) => {}, }) => { // signals const [sApi] = useSignal(ApiSignal); const [,setBranch] = useSignal(BranchSignal); // team const team = useTeam(); // items const { branches, handleItem } = useBranches({ team : team?.id, workflow : workflow?.id, }, { disable : !workflow?.id || !team?.id, }); const { commits, handleItem : handleCommit } = useCommits({ team : team?.id, branch : value?.id || workflow?.branch?.id || workflow?.branch, workflow : workflow?.id, }, { disable : !workflow?.id || !team?.id || !(value?.id || workflow?.branch?.id || workflow?.branch), }); // current branch const currentBranch = branches.find(branch => branch.id === (value ? value.id : (workflow?.branch?.id || workflow?.branch))); // shorten commit to len characters const shortenId = useCallback((id, len = 7) => id.slice(0, len) + '...', []); const [open, setOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [activeTab, setActiveTab] = useState('branches'); const filteredBranches = branches.filter(branch => branch.name.toLowerCase().includes(searchQuery.toLowerCase()) ); // handle create branch const handleCreate = async (opts = {}) => { // create branch const { branch } = await sApi.Branch.create({ ...opts, team : team?.id, workflow : workflow?.id, }); // add to handle item handleItem(branch); // set current branch onChange(branch); }; // handle edit branch const handleUpdate = (e, branch) => { e.stopPropagation(); setBranch(branch); }; // use effect useEffect(() => { console.log('COMMIT UPDATED!'); // check commit if (!commit?.id) return; if (commit?.branch !== value?.id) return; // handle commit handleCommit(commit); }, [commit]); useEffect(() => { // check value if (!value?.id) return; if (!commits.length) return; // get most recent commit, with this branch const found = commits.find(c => c.branch === value.id); // set commit if (found) onCommit(found); }, [value?.id, commits]); // return jsx return (
setOpen(true)} onHide={() => setOpen(false)} >
setSearchQuery(e.target.value)} placeholder="Search or create a branch" startAdornment={} />
{activeTab === 'branches' ? (
{filteredBranches.map((branch) => ( { onChange?.(branch); setOpen(false); }} className={clsx( '!py-2 group', value?.id === branch.id && 'bg-primary-500/50', )} >
{branch.name} {(branch.id === (workflow?.branch?.id || workflow?.branch)) && ( default )}
handleUpdate(e, branch)} className="ml-2 opacity-0 group-hover:opacity-100" >
))} {searchQuery.length > 0 && filteredBranches.length === 0 && ( { handleCreate({ name: searchQuery, }); }} > Create "{searchQuery}" branch )}
) : (
{commits.map((commitItem) => ( { onCommit(commitItem); setOpen(false); }} className={clsx( 'group', commit?.id === commitItem.id && 'bg-primary-500/50', )} >
{commitItem.message}
#{shortenId(commitItem.id)} · {moment(commitItem.createdAt).fromNow()}
))}
)}
); }; export default BranchDropdown;