All files / react-app/src/components/ConfirmationDialog userPrompt.tsx

97.14% Statements 34/35
66.66% Branches 8/12
100% Functions 10/10
97.05% Lines 33/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101                                      105x 9x       9x 9x       10x 10x       105x   105x 9x     105x   6x       105x 29x 29x   29x 9x 18x 8x 8x     10x 10x       9x     29x 2x 2x 2x   2x       29x 2x 2x 2x       29x 17x                                    
import { useEffect, useState } from "react";
 
import { ConfirmationDialog } from "@/components/ConfirmationDialog";
import { Observer } from "@/utils/basic-observable";
 
import { ButtonProps } from "../Inputs";
 
export type UserPrompt = {
  header: string;
  body: string;
  cancelButtonText?: string;
  acceptButtonText?: string;
  areButtonsReversed?: boolean;
  cancelVariant?: ButtonProps["variant"];
  onAccept: () => void;
  onCancel?: () => void;
};
 
class UserPromptObserver extends Observer<UserPrompt> {
  create = (data: UserPrompt) => {
    Iif (this.observed) {
      return;
    }
 
    this.publish(data);
    this.observed = { ...data };
  };
 
  dismiss = () => {
    this.publish(null);
    this.observed = null;
  };
}
 
const userPromptState = new UserPromptObserver();
 
const userPromptFn = (newUserPrompt: UserPrompt) => {
  return userPromptState.create(newUserPrompt);
};
 
export const userPrompt = Object.assign(userPromptFn, {
  dismiss: () => {
    userPromptState.dismiss();
  },
});
 
export const UserPrompt = () => {
  const [activeUserPrompt, setActiveUserPrompt] = useState<UserPrompt | null>(null);
  const [isOpen, setIsOpen] = useState<boolean>(false);
 
  useEffect(() => {
    const unsubscribe = userPromptState.subscribe((userPrompt) => {
      if (userPrompt) {
        setActiveUserPrompt(userPrompt);
        setIsOpen(true);
      } else {
        // artificial delay to prevent content from disappearing first
        setTimeout(() => setActiveUserPrompt(null), 100);
        setIsOpen(false);
      }
    });
 
    return unsubscribe;
  }, []);
 
  const onCancel = () => {
    Eif (activeUserPrompt) {
      Eif (activeUserPrompt.onCancel) {
        activeUserPrompt.onCancel();
      }
      userPromptState.dismiss();
    }
  };
 
  const onAccept = () => {
    Eif (activeUserPrompt) {
      activeUserPrompt.onAccept();
      userPromptState.dismiss();
    }
  };
 
  if (activeUserPrompt === null) {
    return null;
  }
 
  return (
    <ConfirmationDialog
      open={isOpen}
      title={activeUserPrompt.header}
      description="Dialog for user confirmation"
      body={activeUserPrompt.body}
      onAccept={onAccept}
      onCancel={onCancel}
      cancelButtonText={activeUserPrompt.cancelButtonText}
      acceptButtonText={activeUserPrompt.acceptButtonText}
      areButtonsReversed={activeUserPrompt.areButtonsReversed}
      cancelVariant={activeUserPrompt.cancelVariant}
    />
  );
};