• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / fx-private-relay / d4d9f278-d845-4992-8c81-4f3757c427a1

08 Sep 2025 02:07PM UTC coverage: 86.303% (-1.8%) from 88.121%
d4d9f278-d845-4992-8c81-4f3757c427a1

Pull #5842

circleci

joeherm
fix(deploy): Update CircleCI to use common Dockerfile for building frontend
Pull Request #5842: fix(deploy): Unify Dockerfiles

2744 of 3951 branches covered (69.45%)

Branch coverage included in aggregate %.

17910 of 19981 relevant lines covered (89.64%)

9.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

25.0
/frontend/src/components/dashboard/aliases/AliasDeletionButtonPermanent.tsx
1
import {
2
  OverlayContainer,
3
  FocusScope,
4
  useButton,
5
  useDialog,
6
  useModal,
7
  useOverlay,
8
  usePreventScroll,
9
  AriaOverlayProps,
10
} from "react-aria";
3✔
11
import { useOverlayTriggerState } from "react-stately";
3✔
12
import { ReactElement, ReactNode, useEffect, useRef } from "react";
3✔
13
import styles from "./AliasDeletionButtonPermanent.module.scss";
3✔
14
import { Button } from "../../Button";
3✔
15
import { AliasData, getFullAddress } from "../../../hooks/api/aliases";
3✔
16
import { useL10n } from "../../../hooks/l10n";
3✔
17
import { ErrorTriangleIcon } from "../../Icons";
3✔
18

19
export type Props = {
20
  alias: AliasData;
21
  onDelete: () => void;
22
  setModalOpenedState?: (state: boolean) => void;
23
};
24

25
/**
26
 * A button to delete a given alias, which will pop up a confirmation modal before deleting.
27
 */
28
export const AliasDeletionButtonPermanent = (props: Props) => {
3✔
29
  const l10n = useL10n();
×
30

31
  const openModalButtonRef = useRef<HTMLButtonElement>(null);
×
32
  const openModalButtonProps = useButton(
×
33
    {
34
      onPress: () => modalState.open(),
×
35
    },
36
    openModalButtonRef,
37
  ).buttonProps;
38
  const cancelButtonRef = useRef<HTMLButtonElement>(null);
×
39
  const cancelButton = useButton(
×
40
    { onPress: () => modalState.close() },
×
41
    cancelButtonRef,
42
  );
43

44
  const confirmButtonRef = useRef<HTMLButtonElement>(null);
×
45
  const confirmButton = useButton(
×
46
    {
47
      onPress: () => {
48
        props.onDelete();
×
49
        modalState.close();
×
50
      },
51
    },
52
    confirmButtonRef,
53
  );
54

55
  const modalState = useOverlayTriggerState({});
×
56
  useEffect(() => {
×
57
    if (props.setModalOpenedState === undefined) {
×
58
      return;
×
59
    }
60

61
    if (modalState.isOpen) {
×
62
      props.setModalOpenedState(true);
×
63
      return;
×
64
    }
65

66
    props.setModalOpenedState(false);
×
67

68
    // eslint-disable-next-line react-hooks/exhaustive-deps
69
  }, [modalState.isOpen]);
70

71
  const dialog = modalState.isOpen ? (
×
72
    <OverlayContainer>
73
      <ConfirmationDialog
74
        title={l10n.getString("mask-deletion-header")}
75
        onClose={() => modalState.close()}
×
76
        isOpen={modalState.isOpen}
77
        isDismissable={true}
78
      >
79
        <samp className={styles["alias-to-delete"]}>
80
          {getFullAddress(props.alias)}
81
        </samp>
82

83
        <p className={styles["permanence-warning"]}>
84
          {l10n.getString("mask-deletion-warning-no-recovery")}
85
        </p>
86
        <WarningBanner />
87
        <hr />
88
        <div className={styles.confirm}>
89
          <div className={styles.buttons}>
90
            <button
91
              {...cancelButton.buttonProps}
92
              ref={cancelButtonRef}
93
              className={styles["cancel-button"]}
94
            >
95
              {l10n.getString("profile-label-cancel")}
96
            </button>
97
            <Button
98
              type="submit"
99
              variant="destructive"
100
              className={styles["delete-btn"]}
101
              {...confirmButton.buttonProps}
102
            >
103
              {l10n.getString("profile-label-delete")}
104
            </Button>
105
          </div>
106
        </div>
107
      </ConfirmationDialog>
108
    </OverlayContainer>
109
  ) : null;
110

111
  return (
112
    <>
113
      <button
114
        {...openModalButtonProps}
115
        className={styles["deletion-button"]}
116
        ref={openModalButtonRef}
117
      >
118
        {l10n.getString("profile-label-delete")}
119
      </button>
120
      {dialog}
121
    </>
122
  );
123
};
124

125
const WarningBanner = () => {
3✔
126
  const l10n = useL10n();
×
127

128
  return (
129
    <div className={styles["warning-wrapper"]}>
130
      <div className={styles["left-content"]}>
131
        <ErrorTriangleIcon alt="" className={styles["prefix-error-icon"]} />
132
        <p>{l10n.getString("mask-deletion-warning-sign-ins")}</p>
133
      </div>
134
    </div>
135
  );
136
};
137

138
type ConfirmationDialogProps = {
139
  title: string | ReactElement;
140
  children: ReactNode;
141
  isOpen: boolean;
142
  onClose?: () => void;
143
};
144
const ConfirmationDialog = (
3✔
145
  props: ConfirmationDialogProps & AriaOverlayProps,
146
) => {
147
  const wrapperRef = useRef<HTMLDivElement>(null);
×
148
  const { overlayProps, underlayProps } = useOverlay(props, wrapperRef);
×
149
  usePreventScroll();
×
150
  const { modalProps } = useModal();
×
151
  const { dialogProps, titleProps } = useDialog({}, wrapperRef);
×
152

153
  return (
154
    <div className={styles.underlay} {...underlayProps}>
155
      <FocusScope contain restoreFocus autoFocus>
156
        <div
157
          className={styles["dialog-wrapper"]}
158
          {...overlayProps}
159
          {...dialogProps}
160
          {...modalProps}
161
          ref={wrapperRef}
162
        >
163
          <div className={styles.hero}>
164
            <h3 {...titleProps}>{props.title}</h3>
165
          </div>
166
          {props.children}
167
        </div>
168
      </FocusScope>
169
    </div>
170
  );
171
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc