addons/isl/src/stackEdit/ui/BaseSplitButton.tsxblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import type {TrackEventName} from 'isl-server/src/analytics/eventNames';
b69ab319import type {CommitInfo} from '../../types';
b69ab3110
b69ab3111import {Button} from 'isl-components/Button';
b69ab3112import {Tooltip} from 'isl-components/Tooltip';
b69ab3113import {useAtomValue, useSetAtom} from 'jotai';
b69ab3114import {tracker} from '../../analytics';
b69ab3115import {t} from '../../i18n';
b69ab3116import {uncommittedChangesWithPreviews} from '../../previews';
b69ab3117import {useConfirmUnsavedEditsBeforeSplit} from './ConfirmUnsavedEditsBeforeSplit';
b69ab3118import {
b69ab3119 bumpStackEditMetric,
b69ab3120 editingStackIntentionHashes,
b69ab3121 shouldAutoSplitState,
b69ab3122} from './stackEditState';
b69ab3123
b69ab3124export interface BaseSplitButtonProps {
b69ab3125 /** The commit to split */
b69ab3126 commit: CommitInfo;
b69ab3127 /** The event name to track when the button is clicked */
b69ab3128 trackerEventName: TrackEventName;
b69ab3129 /** Whether to automatically trigger AI split */
b69ab3130 autoSplit?: boolean;
b69ab3131 /** Function to call after the split action is initiated */
b69ab3132 onSplitInitiated?: () => void;
b69ab3133 /** Whether to bump the "splitFromSuggestion" metric */
b69ab3134 bumpSplitFromSuggestion?: boolean;
b69ab3135 /** Children to render inside the button */
b69ab3136 children: React.ReactNode;
b69ab3137}
b69ab3138
b69ab3139/** Base button component for initiating split operations */
b69ab3140export function BaseSplitButton({
b69ab3141 commit,
b69ab3142 trackerEventName,
b69ab3143 autoSplit = false,
b69ab3144 onSplitInitiated,
b69ab3145 bumpSplitFromSuggestion = false,
b69ab3146 children,
b69ab3147 ...buttonProps
b69ab3148}: BaseSplitButtonProps & React.ComponentProps<typeof Button>) {
b69ab3149 const confirmUnsavedEditsBeforeSplit = useConfirmUnsavedEditsBeforeSplit();
b69ab3150 const setEditStackIntentionHashes = useSetAtom(editingStackIntentionHashes);
b69ab3151 const setShouldAutoSplit = useSetAtom(shouldAutoSplitState);
b69ab3152
b69ab3153 const uncommittedChanges = useAtomValue(uncommittedChangesWithPreviews);
b69ab3154 const hasUncommittedChanges = uncommittedChanges.length > 0;
b69ab3155
b69ab3156 const onClick = async (e: React.MouseEvent) => {
b69ab3157 if (!(await confirmUnsavedEditsBeforeSplit([commit], 'split'))) {
b69ab3158 return;
b69ab3159 }
b69ab3160 setEditStackIntentionHashes(['split', new Set([commit.hash])]);
b69ab3161 if (autoSplit) {
b69ab3162 setShouldAutoSplit(true);
b69ab3163 }
b69ab3164 if (bumpSplitFromSuggestion) {
b69ab3165 bumpStackEditMetric('splitFromSuggestion');
b69ab3166 }
b69ab3167 tracker.track(trackerEventName);
b69ab3168 if (onSplitInitiated) {
b69ab3169 onSplitInitiated();
b69ab3170 }
b69ab3171 e.stopPropagation();
b69ab3172 };
b69ab3173
b69ab3174 return (
b69ab3175 <Tooltip
b69ab3176 title={hasUncommittedChanges ? t('Cannot currently split with uncommitted changes') : ''}
b69ab3177 trigger={hasUncommittedChanges ? 'hover' : 'disabled'}>
b69ab3178 <Button onClick={onClick} disabled={hasUncommittedChanges} {...buttonProps}>
b69ab3179 {children}
b69ab3180 </Button>
b69ab3181 </Tooltip>
b69ab3182 );
b69ab3183}