Sfoglia il codice sorgente

[web] Remove bootstrap (#1274)

Fixes the issues we started seeing with broken CSS after removing the
emotion cache.
Manav Rathi 1 anno fa
parent
commit
881c94be05

+ 1 - 2
web/apps/payments/package.json

@@ -5,7 +5,6 @@
     "dependencies": {
         "@/next": "*",
         "@stripe/stripe-js": "^1.17.0",
-        "axios": "^1.6.7",
-        "bootstrap": "4.6.0"
+        "axios": "^1.6.7"
     }
 }

+ 2 - 7
web/apps/payments/src/components/EnteSpinner.tsx

@@ -1,10 +1,5 @@
 import * as React from "react";
-import { Spinner } from "react-bootstrap";
 
-export const EnteSpinner: React.FC = () => {
-    return (
-        <Spinner animation="border" variant="success" role="status">
-            <span className="sr-only">Loading...</span>
-        </Spinner>
-    );
+export const Spinner: React.FC = () => {
+    return <div className="loading-spinner"></div>;
 };

+ 0 - 1
web/apps/payments/src/pages/_app.tsx

@@ -1,4 +1,3 @@
-import "bootstrap/dist/css/bootstrap.min.css";
 import type { AppProps } from "next/app";
 import Head from "next/head";
 import constants from "utils/strings";

+ 2 - 2
web/apps/payments/src/pages/index.tsx

@@ -1,5 +1,5 @@
 import { Container } from "components/Container";
-import { EnteSpinner } from "components/EnteSpinner";
+import { Spinner } from "components/EnteSpinner";
 import * as React from "react";
 import { parseAndHandleRequest } from "services/billingService";
 import { CUSTOM_ERROR } from "utils/error";
@@ -35,7 +35,7 @@ export default function Home() {
             {errorMessageView ? (
                 <div>{constants.SOMETHING_WENT_WRONG}</div>
             ) : (
-                loading && <EnteSpinner />
+                loading && <Spinner />
             )}
         </Container>
     );

+ 16 - 0
web/apps/payments/src/styles/globals.css

@@ -20,3 +20,19 @@ body {
     display: flex;
     flex-direction: column;
 }
+
+.loading-spinner {
+    color: #28a745;
+    width: 2rem;
+    height: 2rem;
+    border: 0.25em solid currentColor;
+    border-right-color: transparent;
+    border-radius: 50%;
+    animation: 0.75s linear infinite spinner-border;
+}
+
+@keyframes spinner-border {
+    100% {
+        transform: rotate(360deg);
+    }
+}

+ 0 - 2
web/apps/photos/package.json

@@ -18,7 +18,6 @@
         "@tensorflow/tfjs-tflite": "0.0.1-alpha.7",
         "bip39": "^3.0.4",
         "blazeface-back": "^0.0.9",
-        "bootstrap": "^4.5.2",
         "bs58": "^5.0.0",
         "chrono-node": "^2.2.6",
         "comlink": "^4.3.0",
@@ -45,7 +44,6 @@
         "photoswipe": "file:./thirdparty/photoswipe",
         "piexifjs": "^1.0.6",
         "pure-react-carousel": "^1.30.1",
-        "react-bootstrap": "^1.3.0",
         "react-datepicker": "^4.16.0",
         "react-dropzone": "^11.2.4",
         "react-otp-input": "^2.3.1",

+ 102 - 137
web/apps/photos/src/components/FixCreationTime.tsx

@@ -1,32 +1,43 @@
-import { Row, Value } from "@ente/shared/components/Container";
 import DialogBox from "@ente/shared/components/DialogBox/";
-import { Button, LinearProgress } from "@mui/material";
-import EnteDateTimePicker from "components/EnteDateTimePicker";
+import {
+    Button,
+    FormControl,
+    FormControlLabel,
+    FormLabel,
+    LinearProgress,
+    Radio,
+    RadioGroup,
+} from "@mui/material";
 import { ComfySpan } from "components/ExportInProgress";
-import { Formik } from "formik";
+import { useFormik } from "formik";
 import { t } from "i18next";
 import { GalleryContext } from "pages/gallery";
-import React, { ChangeEvent, useContext, useEffect, useState } from "react";
-import { Form } from "react-bootstrap";
+import React, { useContext, useEffect, useState } from "react";
 import { updateCreationTimeWithExif } from "services/updateCreationTimeWithExif";
 import { EnteFile } from "types/file";
+import EnteDateTimePicker from "./EnteDateTimePicker";
 
 export interface FixCreationTimeAttributes {
     files: EnteFile[];
 }
 
-type Step = "running" | "completed" | "error";
+type Step = "running" | "completed" | "completed-with-errors";
 
-export enum FIX_OPTIONS {
-    DATE_TIME_ORIGINAL,
-    DATE_TIME_DIGITIZED,
-    METADATA_DATE,
-    CUSTOM_TIME,
-}
+export type FixOption =
+    | "date-time-original"
+    | "date-time-digitized"
+    | "metadata-date"
+    | "custom-time";
 
-interface formValues {
-    option: FIX_OPTIONS;
-    customTime: Date;
+interface FormValues {
+    option: FixOption;
+    /**
+     * Date.toISOString()
+     *
+     * Formik doesn't have native support for JS dates, so we instead keep the
+     * corresponding date's ISO string representation as the form state.
+     */
+    customTimeString: string;
 }
 
 interface FixCreationTimeProps {
@@ -52,22 +63,19 @@ const FixCreationTime: React.FC<FixCreationTimeProps> = (props) => {
         }
     }, [props.isOpen]);
 
-    const startFix = async (option: FIX_OPTIONS, customTime: Date) => {
+    const onSubmit = async (values: FormValues) => {
+        console.log({ values });
         setStep("running");
-        const failed = await updateCreationTimeWithExif(
+        const completedWithErrors = await updateCreationTimeWithExif(
             props.attributes.files,
-            option,
-            customTime,
+            values.option,
+            new Date(values.customTimeString),
             setProgressTracker,
         );
-        setStep(failed ? "error" : "completed");
+        setStep(completedWithErrors ? "completed-with-errors" : "completed");
         await galleryContext.syncWithRemote();
     };
 
-    const onSubmit = (values: formValues) => {
-        startFix(Number(values.option), new Date(values.customTime));
-    };
-
     const title =
         step === "running"
             ? t("FIX_CREATION_TIME_IN_PROGRESS")
@@ -96,34 +104,10 @@ const FixCreationTime: React.FC<FixCreationTimeProps> = (props) => {
                 {message && <div>{message}</div>}
 
                 {step === "running" && (
-                    <FixCreationTimeRunning progressTracker={progressTracker} />
+                    <FixCreationTimeRunning {...{ progressTracker }} />
                 )}
-                <Formik<formValues>
-                    initialValues={{
-                        option: FIX_OPTIONS.DATE_TIME_ORIGINAL,
-                        customTime: new Date(),
-                    }}
-                    validateOnBlur={false}
-                    onSubmit={onSubmit}
-                >
-                    {({ values, handleChange, handleSubmit }) => (
-                        <>
-                            {(step === undefined || step === "error") && (
-                                <div style={{ marginTop: "10px" }}>
-                                    <FixCreationTimeOptions
-                                        handleChange={handleChange}
-                                        values={values}
-                                    />
-                                </div>
-                            )}
-                            <FixCreationTimeFooter
-                                step={step}
-                                startFix={handleSubmit}
-                                hide={props.hide}
-                            />
-                        </>
-                    )}
-                </Formik>
+
+                <OptionsForm {...{ step, onSubmit }} hide={props.hide} />
             </div>
         </DialogBox>
     );
@@ -134,101 +118,82 @@ export default FixCreationTime;
 const messageForStep = (step?: Step) => {
     switch (step) {
         case undefined:
-            return t("UPDATE_CREATION_TIME_NOT_STARTED");
+            return undefined;
         case "running":
             return undefined;
         case "completed":
             return t("UPDATE_CREATION_TIME_COMPLETED");
-        case "error":
+        case "completed-with-errors":
             return t("UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR");
     }
 };
 
-const Option = ({
-    value,
-    selected,
-    onChange,
-    label,
-}: {
-    value: FIX_OPTIONS;
-    selected: FIX_OPTIONS;
-    onChange: (e: string | ChangeEvent<any>) => void;
-    label: string;
-}) => (
-    <Form.Check
-        name="group1"
-        style={{
-            margin: "5px 0",
-            color: value !== Number(selected) ? "#aaa" : "#fff",
-        }}
-    >
-        <Form.Check.Input
-            id={value.toString()}
-            type="radio"
-            value={value}
-            checked={value === Number(selected)}
-            onChange={onChange}
-        />
-        <Form.Check.Label
-            style={{ cursor: "pointer" }}
-            htmlFor={value.toString()}
-        >
-            {label}
-        </Form.Check.Label>
-    </Form.Check>
-);
+interface OptionsFormProps {
+    step?: Step;
+    onSubmit: (values: FormValues) => void | Promise<any>;
+    hide: () => void;
+}
+
+const OptionsForm: React.FC<OptionsFormProps> = ({ step, onSubmit, hide }) => {
+    const { values, handleChange, handleSubmit } = useFormik({
+        initialValues: {
+            option: "date-time-original",
+            customTimeString: new Date().toISOString(),
+        },
+        validateOnBlur: false,
+        onSubmit,
+    });
 
-function FixCreationTimeOptions({ handleChange, values }) {
     return (
-        <Form noValidate>
-            <Row style={{ margin: "0" }}>
-                <Option
-                    value={FIX_OPTIONS.DATE_TIME_ORIGINAL}
-                    onChange={handleChange("option")}
-                    label={t("DATE_TIME_ORIGINAL")}
-                    selected={Number(values.option)}
-                />
-            </Row>
-            <Row style={{ margin: "0" }}>
-                <Option
-                    value={FIX_OPTIONS.DATE_TIME_DIGITIZED}
-                    onChange={handleChange("option")}
-                    label={t("DATE_TIME_DIGITIZED")}
-                    selected={Number(values.option)}
-                />
-            </Row>
-            <Row style={{ margin: "0" }}>
-                <Option
-                    value={FIX_OPTIONS.METADATA_DATE}
-                    onChange={handleChange("option")}
-                    label={t("METADATA_DATE")}
-                    selected={Number(values.option)}
-                />
-            </Row>
-            <Row style={{ margin: "0" }}>
-                <Value width="50%">
-                    <Option
-                        value={FIX_OPTIONS.CUSTOM_TIME}
-                        onChange={handleChange("option")}
-                        label={t("CUSTOM_TIME")}
-                        selected={Number(values.option)}
-                    />
-                </Value>
-                {Number(values.option) === FIX_OPTIONS.CUSTOM_TIME && (
-                    <Value width="40%">
-                        <EnteDateTimePicker
-                            onSubmit={(x: Date) =>
-                                handleChange("customTime")(x.toUTCString())
-                            }
-                        />
-                    </Value>
-                )}
-            </Row>
-        </Form>
+        <>
+            {(step === undefined || step === "completed-with-errors") && (
+                <div style={{ marginTop: "10px" }}>
+                    <form onSubmit={handleSubmit}>
+                        <FormControl>
+                            <FormLabel>
+                                {t("UPDATE_CREATION_TIME_NOT_STARTED")}
+                            </FormLabel>
+                        </FormControl>
+                        <RadioGroup name={"option"} onChange={handleChange}>
+                            <FormControlLabel
+                                value={"date-time-original"}
+                                control={<Radio size="small" />}
+                                label={t("DATE_TIME_ORIGINAL")}
+                            />
+                            <FormControlLabel
+                                value={"date-time-digitized"}
+                                control={<Radio size="small" />}
+                                label={t("DATE_TIME_DIGITIZED")}
+                            />
+                            <FormControlLabel
+                                value={"metadata-date"}
+                                control={<Radio size="small" />}
+                                label={t("METADATA_DATE")}
+                            />
+                            <FormControlLabel
+                                value={"custom-time"}
+                                control={<Radio size="small" />}
+                                label={t("CUSTOM_TIME")}
+                            />
+                        </RadioGroup>
+                        {values.option === "custom-time" && (
+                            <EnteDateTimePicker
+                                onSubmit={(d: Date) =>
+                                    handleChange("customTimeString")(
+                                        d.toISOString(),
+                                    )
+                                }
+                            />
+                        )}
+                    </form>
+                </div>
+            )}
+            <Footer step={step} startFix={handleSubmit} hide={hide} />
+        </>
     );
-}
+};
 
-const FixCreationTimeFooter = ({ step, startFix, ...props }) => {
+const Footer = ({ step, startFix, ...props }) => {
     return (
         step !== "running" && (
             <div
@@ -239,7 +204,7 @@ const FixCreationTimeFooter = ({ step, startFix, ...props }) => {
                     justifyContent: "space-around",
                 }}
             >
-                {(step === undefined || step === "error") && (
+                {(step === undefined || step === "completed-with-errors") && (
                     <Button
                         color="secondary"
                         size="large"
@@ -255,7 +220,7 @@ const FixCreationTimeFooter = ({ step, startFix, ...props }) => {
                         {t("CLOSE")}
                     </Button>
                 )}
-                {(step === undefined || step === "error") && (
+                {(step === undefined || step === "completed-with-errors") && (
                     <>
                         <div style={{ width: "30px" }} />
 

+ 0 - 1
web/apps/photos/src/pages/_app.tsx

@@ -43,7 +43,6 @@ import { SetTheme } from "@ente/shared/themes/types";
 import ArrowForward from "@mui/icons-material/ArrowForward";
 import { CssBaseline, useMediaQuery } from "@mui/material";
 import { ThemeProvider } from "@mui/material/styles";
-import "bootstrap/dist/css/bootstrap.min.css";
 import Notification from "components/Notification";
 import { REDIRECTS } from "constants/redirects";
 import { t } from "i18next";

+ 9 - 12
web/apps/photos/src/services/updateCreationTimeWithExif.ts

@@ -1,15 +1,14 @@
 import { logError } from "@ente/shared/sentry";
-import { FIX_OPTIONS } from "components/FixCreationTime";
+import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
+import type { FixOption } from "components/FixCreationTime";
+import { FILE_TYPE } from "constants/file";
+import { getFileType } from "services/typeDetectionService";
 import { EnteFile } from "types/file";
 import {
     changeFileCreationTime,
     updateExistingFilePubMetadata,
 } from "utils/file";
 import downloadManager from "./download";
-
-import { validateAndGetCreationUnixTimeInMicroSeconds } from "@ente/shared/time";
-import { FILE_TYPE } from "constants/file";
-import { getFileType } from "services/typeDetectionService";
 import { getParsedExifData } from "./upload/exifService";
 
 const EXIF_TIME_TAGS = [
@@ -29,7 +28,7 @@ export type SetProgressTracker = React.Dispatch<
 
 export async function updateCreationTimeWithExif(
     filesToBeUpdated: EnteFile[],
-    fixOption: FIX_OPTIONS,
+    fixOption: FixOption,
     customTime: Date,
     setProgressTracker: SetProgressTracker,
 ) {
@@ -42,7 +41,7 @@ export async function updateCreationTimeWithExif(
         for (const [index, file] of filesToBeUpdated.entries()) {
             try {
                 let correctCreationTime: number;
-                if (fixOption === FIX_OPTIONS.CUSTOM_TIME) {
+                if (fixOption === "custom-time") {
                     correctCreationTime = customTime.getTime() * 1000;
                 } else {
                     if (file.metadata.fileType !== FILE_TYPE.IMAGE) {
@@ -60,24 +59,22 @@ export async function updateCreationTimeWithExif(
                         fileTypeInfo,
                         EXIF_TIME_TAGS,
                     );
-                    if (fixOption === FIX_OPTIONS.DATE_TIME_ORIGINAL) {
+                    if (fixOption === "date-time-original") {
                         correctCreationTime =
                             validateAndGetCreationUnixTimeInMicroSeconds(
                                 exifData?.DateTimeOriginal ??
                                     exifData?.DateCreated,
                             );
-                    } else if (fixOption === FIX_OPTIONS.DATE_TIME_DIGITIZED) {
+                    } else if (fixOption === "date-time-digitized") {
                         correctCreationTime =
                             validateAndGetCreationUnixTimeInMicroSeconds(
                                 exifData?.CreateDate,
                             );
-                    } else if (fixOption === FIX_OPTIONS.METADATA_DATE) {
+                    } else if (fixOption === "metadata-date") {
                         correctCreationTime =
                             validateAndGetCreationUnixTimeInMicroSeconds(
                                 exifData?.MetadataDate,
                             );
-                    } else {
-                        throw new Error("Invalid fix option");
                     }
                 }
                 if (

+ 10 - 109
web/yarn.lock

@@ -41,7 +41,7 @@
     chalk "^2.4.2"
     js-tokens "^4.0.0"
 
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
   version "7.23.9"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
   integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==
@@ -516,23 +516,11 @@
   resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.24.tgz#58601079e11784d20f82d0585865bb42305c4df3"
   integrity sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==
 
-"@popperjs/core@^2.11.6", "@popperjs/core@^2.11.8", "@popperjs/core@^2.9.2":
+"@popperjs/core@^2.11.8", "@popperjs/core@^2.9.2":
   version "2.11.8"
   resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
   integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
 
-"@restart/context@^2.1.4":
-  version "2.1.4"
-  resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02"
-  integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q==
-
-"@restart/hooks@^0.4.7":
-  version "0.4.16"
-  resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.16.tgz#95ae8ac1cc7e2bd4fed5e39800ff85604c6d59fb"
-  integrity sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==
-  dependencies:
-    dequal "^2.0.3"
-
 "@rushstack/eslint-patch@^1.3.3":
   version "1.7.2"
   resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz#2d4260033e199b3032a08b41348ac10de21c47e9"
@@ -622,11 +610,6 @@
     "@types/react" "*"
     hoist-non-react-statics "^3.3.0"
 
-"@types/invariant@^2.2.33":
-  version "2.2.37"
-  resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.37.tgz#1709741e534364d653c87dff22fc76fa94aa7bc0"
-  integrity sha512-IwpIMieE55oGWiXkQPSBY1nw1nFs6bsKXTFskNY8sdS17K24vyEBRQZEwlRS7ZmXCWnJcQtbxWzly+cODWGs2A==
-
 "@types/json-schema@^7.0.12":
   version "7.0.15"
   resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
@@ -693,7 +676,7 @@
   resolved "https://registry.yarnpkg.com/@types/photoswipe/-/photoswipe-4.1.6.tgz#41d1e0a54c1b27628688e8abf9b95baab472a247"
   integrity sha512-6kN4KYjNF4sg79fSwZ46s4Pron4+YJxoW0DQOcHveUZc/3cWd8Q4B9OLlDmEYw9iI6fODU8kyyq8ZBy+8F/+zQ==
 
-"@types/prop-types@*", "@types/prop-types@^15.7.11", "@types/prop-types@^15.7.3":
+"@types/prop-types@*", "@types/prop-types@^15.7.11":
   version "15.7.11"
   resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563"
   integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==
@@ -732,7 +715,7 @@
     "@types/react-dom" "*"
     "@types/react-transition-group" "*"
 
-"@types/react-transition-group@*", "@types/react-transition-group@^4.4.1", "@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.5":
+"@types/react-transition-group@*", "@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.5":
   version "4.4.10"
   resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac"
   integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==
@@ -761,7 +744,7 @@
   dependencies:
     "@types/react" "*"
 
-"@types/react@*", "@types/react@>=16.14.8", "@types/react@>=16.9.11", "@types/react@^18":
+"@types/react@*", "@types/react@^18":
   version "18.2.58"
   resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.58.tgz#22082d12898d11806f4a1aefb5583116a047493d"
   integrity sha512-TaGvMNhxvG2Q0K0aYxiKfNDS5m5ZsoIBBbtfUorxdH4NGSXIlYvZxLJI+9Dd3KjeB3780bciLyAb7ylO8pLhPw==
@@ -790,11 +773,6 @@
   resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba"
   integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==
 
-"@types/warning@^3.0.0":
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.3.tgz#d1884c8cc4a426d1ac117ca2611bf333834c6798"
-  integrity sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==
-
 "@types/wicg-file-system-access@^2020.9.5":
   version "2020.9.8"
   resolved "https://registry.yarnpkg.com/@types/wicg-file-system-access/-/wicg-file-system-access-2020.9.8.tgz#a8b739854ccb74b8048ef607d3701e9d506830e7"
@@ -1205,16 +1183,6 @@ blazeface-back@^0.0.9:
   resolved "https://registry.yarnpkg.com/blazeface-back/-/blazeface-back-0.0.9.tgz#a8a26a0022950eb21136693f2fca3c52315ad2a4"
   integrity sha512-t0i5V117j074d7d7mlLaRq9n/bYchXcSEgpWVbGGloV68A6Jn22t4SNoEC3t+MOsU8H+eXoDv2/6+JsqActM1g==
 
-bootstrap@4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7"
-  integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==
-
-bootstrap@^4.5.2:
-  version "4.6.2"
-  resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.2.tgz#8e0cd61611728a5bf65a3a2b8d6ff6c77d5d7479"
-  integrity sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==
-
 brace-expansion@^1.1.7:
   version "1.1.11"
   resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1316,7 +1284,7 @@ chrono-node@^2.2.6:
   dependencies:
     dayjs "^1.10.0"
 
-classnames@^2.2.6, classnames@^2.3.1:
+classnames@^2.2.6:
   version "2.5.1"
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
   integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
@@ -1544,7 +1512,7 @@ doctrine@^3.0.0:
   dependencies:
     esutils "^2.0.2"
 
-dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1:
+dom-helpers@^5.0.1:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
   integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -2443,13 +2411,6 @@ internal-slot@^1.0.5, internal-slot@^1.0.7:
     hasown "^2.0.0"
     side-channel "^1.0.4"
 
-invariant@^2.2.4:
-  version "2.2.4"
-  resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
-  integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
-  dependencies:
-    loose-envify "^1.0.0"
-
 is-any-array@^2.0.0, is-any-array@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-2.0.1.tgz#9233242a9c098220290aa2ec28f82ca7fa79899e"
@@ -3334,14 +3295,6 @@ process-nextick-args@~2.0.0:
   resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
   integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
 
-prop-types-extra@^1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b"
-  integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==
-  dependencies:
-    react-is "^16.3.2"
-    warning "^4.0.0"
-
 prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
   version "15.8.1"
   resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
@@ -3382,29 +3335,6 @@ queue-microtask@^1.2.2:
   resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
   integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
 
-react-bootstrap@^1.3.0:
-  version "1.6.8"
-  resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.6.8.tgz#e9380d81cdb92c433f61b37a9120b8edd49912a1"
-  integrity sha512-yD6uN78XlFOkETQp6GRuVe0s5509x3XYx8PfPbirwFTYCj5/RfmSs9YZGCwkUrhZNFzj7tZPdpb+3k50mK1E4g==
-  dependencies:
-    "@babel/runtime" "^7.14.0"
-    "@restart/context" "^2.1.4"
-    "@restart/hooks" "^0.4.7"
-    "@types/invariant" "^2.2.33"
-    "@types/prop-types" "^15.7.3"
-    "@types/react" ">=16.14.8"
-    "@types/react-transition-group" "^4.4.1"
-    "@types/warning" "^3.0.0"
-    classnames "^2.3.1"
-    dom-helpers "^5.2.1"
-    invariant "^2.2.4"
-    prop-types "^15.7.2"
-    prop-types-extra "^1.1.0"
-    react-overlays "^5.1.2"
-    react-transition-group "^4.4.1"
-    uncontrollable "^7.2.1"
-    warning "^4.0.3"
-
 react-datepicker@^4.16.0:
   version "4.25.0"
   resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.25.0.tgz#86b3ee8ac764bad1650046d0cf9280837bf6d845"
@@ -3459,7 +3389,7 @@ react-input-autosize@^3.0.0:
   dependencies:
     prop-types "^15.5.8"
 
-react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0:
+react-is@^16.13.1, react-is@^16.7.0:
   version "16.13.1"
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
   integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -3469,11 +3399,6 @@ react-is@^18.2.0:
   resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
   integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
 
-react-lifecycles-compat@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
-  integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
-
 react-onclickoutside@^6.13.0:
   version "6.13.0"
   resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz#e165ea4e5157f3da94f4376a3ab3e22a565f4ffc"
@@ -3484,20 +3409,6 @@ react-otp-input@^2.3.1:
   resolved "https://registry.yarnpkg.com/react-otp-input/-/react-otp-input-2.4.0.tgz#0f0a3de1d8c8d564e2e4fbe5d6b7b56e29e3a6e6"
   integrity sha512-AIgl7u4sS9BTNCxX1xlaS5fPWay/Zml8Ho5LszXZKXrH1C/TiFsTQGmtl13UecQYO3mSF3HUzG2rrDf0sjEFmg==
 
-react-overlays@^5.1.2:
-  version "5.2.1"
-  resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-5.2.1.tgz#49dc007321adb6784e1f212403f0fb37a74ab86b"
-  integrity sha512-GLLSOLWr21CqtJn8geSwQfoJufdt3mfdsnIiQswouuQ2MMPns+ihZklxvsTDKD3cR2tF8ELbi5xUsvqVhR6WvA==
-  dependencies:
-    "@babel/runtime" "^7.13.8"
-    "@popperjs/core" "^2.11.6"
-    "@restart/hooks" "^0.4.7"
-    "@types/warning" "^3.0.0"
-    dom-helpers "^5.2.0"
-    prop-types "^15.7.2"
-    uncontrollable "^7.2.1"
-    warning "^4.0.3"
-
 react-popper@^2.2.5, react-popper@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba"
@@ -3524,7 +3435,7 @@ react-top-loading-bar@^2.0.1:
   resolved "https://registry.yarnpkg.com/react-top-loading-bar/-/react-top-loading-bar-2.3.1.tgz#d727eb6aaa412eae52a990e5de9f33e9136ac714"
   integrity sha512-rQk2Nm+TOBrM1C4E3e6KwT65iXyRSgBHjCkr2FNja1S51WaPulRA5nKj/xazuQ3x89wDDdGsrqkqy0RBIfd0xg==
 
-react-transition-group@^4.3.0, react-transition-group@^4.4.1, react-transition-group@^4.4.5:
+react-transition-group@^4.3.0, react-transition-group@^4.4.5:
   version "4.4.5"
   resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
   integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
@@ -4197,16 +4108,6 @@ unbox-primitive@^1.0.2:
     has-symbols "^1.0.3"
     which-boxed-primitive "^1.0.2"
 
-uncontrollable@^7.2.1:
-  version "7.2.1"
-  resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738"
-  integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==
-  dependencies:
-    "@babel/runtime" "^7.6.3"
-    "@types/react" ">=16.9.11"
-    invariant "^2.2.4"
-    react-lifecycles-compat "^3.0.4"
-
 undici-types@~5.26.4:
   version "5.26.5"
   resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
@@ -4244,7 +4145,7 @@ vscode-uri@^3.0.7:
   resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
   integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
 
-warning@^4.0.0, warning@^4.0.2, warning@^4.0.3:
+warning@^4.0.2:
   version "4.0.3"
   resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
   integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==