Ver Fonte

env var tab improvements (#3780)

Feroze Mohideen há 2 anos atrás
pai
commit
a45aba29e8

+ 1 - 1
dashboard/src/main/home/app-dashboard/app-view/tabs/Environment.tsx

@@ -57,7 +57,7 @@ const Environment: React.FC<Props> = ({ latestSource, buttonStatus }) => {
     <>
       <Text size={16}>Environment variables</Text>
       <Spacer y={0.5} />
-      <Text color="helper">Shared among all services.</Text>
+      <Text color="helper">Shared among all services. All non-secret variables are also available at build time.</Text>
       <EnvSettings
         appName={latestProto.name}
         revision={previewRevision ? previewRevision : latestRevision} // get versions of env groups attached to preview revision if set

+ 1 - 2
dashboard/src/main/home/app-dashboard/validate-apply/app-settings/EnvSettings.tsx

@@ -5,7 +5,6 @@ import { PopulatedEnvGroup } from "./types";
 import EnvVariables from "./EnvVariables";
 import EnvGroups from "./EnvGroups";
 import { AppRevision } from "lib/revisions/types";
-import { DetectedServices } from "lib/porter-apps/services";
 
 type Props = {
   appName?: string;
@@ -18,7 +17,7 @@ type Props = {
 const EnvSettings: React.FC<Props> = (props) => {
   return (
     <>
-      <EnvVariables />
+      <EnvVariables syncedEnvGroups={[]}/>
       <EnvGroups {...props} attachedEnvGroups={props.attachedEnvGroups} />
     </>
   );

+ 263 - 0
dashboard/src/main/home/app-dashboard/validate-apply/app-settings/EnvVarRow.tsx

@@ -0,0 +1,263 @@
+import React from "react";
+import { KeyValueType } from "main/home/cluster-dashboard/env-groups/EnvGroupArray";
+import Tooltip from "components/porter/Tooltip";
+import { Controller, useFormContext } from "react-hook-form";
+import { PorterAppFormData } from "lib/porter-apps";
+import Spacer from "components/porter/Spacer";
+import Text from "components/porter/Text";
+import styled from "styled-components";
+
+type Props = {
+    entry: KeyValueType;
+    index: number;
+    remove: () => void;
+    isKeyOverriding: (key: string) => boolean;
+}
+const EnvVarRow: React.FC<Props> = ({
+    entry,
+    index,
+    remove,
+    isKeyOverriding,
+}) => {
+    const { control: appControl, watch } = useFormContext<PorterAppFormData>();
+    const hidden = watch(`app.env.${index}.hidden`);
+
+    return (
+        <InputWrapper>
+            {entry.locked ? (
+                <Tooltip
+                    content={"Secrets are immutable. To edit, delete and recreate the key with your new value."}
+                    position={"bottom"}
+                >
+                    <Input
+                        placeholder="ex: key"
+                        width="270px"
+                        value={entry.key}
+                        disabled
+                        spellCheck={false}
+                        override={isKeyOverriding(entry.key)}
+                    />
+                </Tooltip>
+            ) : (
+                <Controller
+                    name={`app.env.${index}.key`}
+                    control={appControl}
+                    render={({ field: { value, onChange } }) => (
+                        <Input
+                            placeholder="ex: key"
+                            width="270px"
+                            value={value}
+                            onChange={(e) => onChange(e.target.value)}
+                            spellCheck={false}
+                            override={isKeyOverriding(value)}
+                        />
+                    )}
+                />
+            )}
+            <Spacer x={0.5} inline />
+            {hidden ? (
+                entry.locked ? (
+                    <Tooltip
+                        content={"Secrets are immutable. To edit, delete and recreate the key with your new value."}
+                        position={"bottom"}
+                    >
+                        <Input
+                            placeholder="ex: value"
+                            width="270px"
+                            value={entry.value}
+                            disabled
+                            type={"password"}
+                            spellCheck={false}
+                            override={isKeyOverriding(entry.key)}
+                        />
+                    </Tooltip>
+                ) : (
+                    <Controller
+                        name={`app.env.${index}.value`}
+                        control={appControl}
+                        render={({ field: { value, onChange } }) => (
+                            <Input
+                                placeholder="ex: value"
+                                width="270px"
+                                value={value}
+                                onChange={(e) => onChange(e.target.value)}
+                                type={"password"}
+                                spellCheck={false}
+                                override={isKeyOverriding(entry.key)}
+                            />
+                        )}
+                    />
+                )
+            ) : (
+                <Controller
+                    name={`app.env.${index}.value`}
+                    control={appControl}
+                    render={({ field: { value, onChange } }) => (
+                        <MultiLineInputer
+                            placeholder="ex: value"
+                            width="270px"
+                            value={value}
+                            onChange={(e) => onChange(e.target.value)}
+                            rows={value?.split("\n").length}
+                            spellCheck={false}
+                            override={isKeyOverriding(entry.key)}
+                        />
+                    )}
+                />
+            )}
+            {hidden ? (
+                <Controller
+                    name={`app.env.${index}.hidden`}
+                    control={appControl}
+                    render={({ field: { value, onChange } }) => (
+                        <HideButton
+                            onClick={() => {
+                                onChange(!value)
+                            }}
+                            disabled={entry.locked}
+                        >
+                            <i className="material-icons">lock_open</i>
+                        </HideButton>
+                    )}
+                />
+            ) : (
+                <Tooltip
+                    content={"Click to turn this variable into a secret"}
+                    position={"bottom"}
+                >
+                    <Controller
+                        name={`app.env.${index}.hidden`}
+                        control={appControl}
+                        render={({ field: { value, onChange } }) => (
+                            <HideButton
+                                onClick={() => {
+                                    onChange(!value)
+                                }}
+                                disabled={entry.locked}
+                            >
+                                <i className="material-icons">lock</i>
+                            </HideButton>
+                        )}
+                    />
+                </Tooltip>
+            )}
+            <DeleteButton
+                onClick={() => {
+                    remove()
+                }}
+            >
+                <i className="material-icons">cancel</i>
+            </DeleteButton>
+            {isKeyOverriding(entry.key) && (
+                <>
+                    <Spacer x={1} inline />
+                    <Text color={'#6b74d6'}>Key is overriding value in an environment group</Text>
+                </>
+            )}
+        </InputWrapper>
+    );
+};
+export default EnvVarRow;
+
+const InputWrapper = styled.div`
+  display: flex;
+  align-items: center;
+  margin-top: 5px;
+
+`;
+
+type InputProps = {
+    disabled?: boolean;
+    width: string;
+    override?: boolean;
+};
+
+const Input = styled.input<InputProps>`
+    outline: none;
+    border: none;
+    margin-bottom: 5px;
+    font-size: 13px;
+    background: #ffffff11;
+    border: ${(props) => (props.override ? '2px solid #6b74d6' : ' 1px solid #ffffff55')};
+    border-radius: 3px;
+    width: ${(props) => props.width ? props.width : "270px"};
+    color: ${(props) => props.disabled ? "#ffffff44" : "white"};
+    padding: 5px 10px;
+    height: 35px;
+  `;
+
+const MultiLineInputer = styled.textarea<InputProps>`
+  outline: none;
+  border: none;
+  margin-bottom: 5px;
+  font-size: 13px;
+  background: #ffffff11;
+  border: ${(props) => (props.override ? '2px solid #6b74d6' : ' 1px solid #ffffff55')};
+  border-radius: 3px;
+  min-width: ${(props) => (props.width ? props.width : "270px")};
+  max-width: ${(props) => (props.width ? props.width : "270px")};
+  color: ${(props) => (props.disabled ? "#ffffff44" : "white")};
+  padding: 8px 10px 5px 10px;
+  min-height: 35px;
+  max-height: 100px;
+  white-space: nowrap;
+
+  ::-webkit-scrollbar {
+    width: 8px;
+    :horizontal {
+      height: 8px;
+    }
+  }
+
+  ::-webkit-scrollbar-corner {
+    width: 10px;
+    background: #ffffff11;
+    color: white;
+  }
+
+  ::-webkit-scrollbar-track {
+    width: 10px;
+    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+  }
+
+  ::-webkit-scrollbar-thumb {
+    background-color: darkgrey;
+    outline: 1px solid slategrey;
+  }
+`;
+
+const DeleteButton = styled.div`
+  width: 15px;
+  height: 15px;
+  display: flex;
+  align-items: center;
+  margin-left: 8px;
+  margin-top: -3px;
+  justify-content: center;
+
+  > i {
+    font-size: 17px;
+    color: #ffffff44;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    :hover {
+      color: #ffffff88;
+    }
+  }
+`;
+
+const HideButton = styled(DeleteButton)`
+  margin-top: -5px;
+  > i {
+    font-size: 19px;
+    cursor: ${(props: { disabled: boolean }) =>
+        props.disabled ? "default" : "pointer"};
+    :hover {
+      color: ${(props: { disabled: boolean }) =>
+        props.disabled ? "#ffffff44" : "#ffffff88"};
+    }
+  }
+`;

+ 161 - 19
dashboard/src/main/home/app-dashboard/validate-apply/app-settings/EnvVariables.tsx

@@ -1,31 +1,173 @@
-import React from "react";
-import { Controller, useFormContext } from "react-hook-form";
+import React, { useState } from "react";
+import styled from "styled-components";
+import Modal from "main/home/modals/Modal";
+import EnvEditorModal from "main/home/modals/EnvEditorModal";
 
+import upload from "assets/upload.svg";
+import { dotenv_parse } from "shared/string_utils";
+import { NewPopulatedEnvGroup } from "components/porter-form/types";
+import Spacer from "components/porter/Spacer";
 import { PorterAppFormData } from "lib/porter-apps";
-import EnvGroupArrayV2 from "main/home/cluster-dashboard/env-groups/EnvGroupArrayV2";
-import { KeyValueType } from "main/home/cluster-dashboard/env-groups/EnvGroupArrayV2";
+import { useFormContext, useFieldArray } from "react-hook-form";
+import EnvVarRow from "./EnvVarRow";
 
-const EnvVariables: React.FC = () => {
-  const { control } = useFormContext<PorterAppFormData>();
+export type KeyValueType = {
+  key: string;
+  value: string;
+  hidden: boolean;
+  locked: boolean;
+  deleted: boolean;
+};
+
+type PropsType = {
+  syncedEnvGroups?: NewPopulatedEnvGroup[];
+};
+
+const EnvVariables = ({
+  syncedEnvGroups
+}: PropsType) => {
+  const [showEditorModal, setShowEditorModal] = useState(false);
+
+  const { control: appControl } = useFormContext<PorterAppFormData>();
+
+  const { append, remove, update, fields: environmentVariables } = useFieldArray({
+    control: appControl,
+    name: "app.env",
+  });
+
+  const isKeyOverriding = (key: string) => {
+    if (!syncedEnvGroups) return false;
+    return syncedEnvGroups.some(envGroup =>
+      key in envGroup.variables || key in envGroup?.secret_variables
+    );
+  };
+
+  const readFile = (env: string) => {
+    const envObj = dotenv_parse(env);
+    for (const key in envObj) {
+      const match = environmentVariables.find(envVar => envVar.key === key);
+      if (match && !match.deleted) {
+        const index = environmentVariables.indexOf(match);
+        update(index, { ...match, value: envObj[key] });
+      } else {
+        append({
+          key,
+          value: envObj[key],
+          hidden: false,
+          locked: false,
+          deleted: false,
+        })
+      }
+    }
+  };
 
   return (
-    <Controller
-      name={`app.env`}
-      control={control}
-      render={({ field: { value, onChange } }) => (
-        <>
-          <EnvGroupArrayV2
-            values={value ? value : []}
-            setValues={(x: KeyValueType[]) => {
-              onChange(x);
+    <>
+      <StyledInputArray>
+        {environmentVariables.map((entry, i) =>
+          <EnvVarRow
+            key={entry.id}
+            entry={entry}
+            index={i}
+            remove={() => remove(i)}
+            isKeyOverriding={isKeyOverriding}
+          />
+        )}
+        <InputWrapper>
+          <AddRowButton
+            onClick={() => {
+              append({
+                key: "",
+                value: "",
+                hidden: false,
+                locked: false,
+                deleted: false,
+              })
             }}
-            fileUpload={true}
-            syncedEnvGroups={[]}
+          >
+            <i className="material-icons">add</i> Add Row
+          </AddRowButton>
+          <Spacer x={0.5} inline />
+            <UploadButton
+              onClick={() => {
+                setShowEditorModal(true);
+              }}
+            >
+              <img src={upload} alt="Upload" /> Copy from File
+            </UploadButton>
+        </InputWrapper>
+      </StyledInputArray>
+      {showEditorModal && (
+        <Modal
+          onRequestClose={() => setShowEditorModal(false)}
+          width="60%"
+          height="650px"
+        >
+          <EnvEditorModal
+            closeModal={() => setShowEditorModal(false)}
+            setEnvVariables={(envFile: string) => readFile(envFile)}
           />
-        </>
+        </Modal>
       )}
-    />
+    </>
   );
 };
 
 export default EnvVariables;
+
+
+const AddRowButton = styled.div`
+  display: flex;
+  align-items: center;
+  width: 270px;
+  font-size: 13px;
+  color: #aaaabb;
+  height: 32px;
+  border-radius: 3px;
+  cursor: pointer;
+  background: #ffffff11;
+  :hover {
+    background: #ffffff22;
+  }
+
+  > i {
+    color: #ffffff44;
+    font-size: 16px;
+    margin-left: 8px;
+    margin-right: 10px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+`;
+
+const UploadButton = styled(AddRowButton)`
+  background: none;
+  position: relative;
+  border: 1px solid #ffffff55;
+  > i {
+    color: #ffffff44;
+    font-size: 16px;
+    margin-left: 8px;
+    margin-right: 10px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+  > img {
+    width: 14px;
+    margin-left: 10px;
+    margin-right: 12px;
+  }
+`;
+
+const InputWrapper = styled.div`
+  display: flex;
+  align-items: center;
+  margin-top: 5px;
+`;
+
+const StyledInputArray = styled.div`
+  margin-bottom: 15px;
+  margin-top: 22px;
+`;

+ 0 - 403
dashboard/src/main/home/cluster-dashboard/env-groups/EnvGroupArrayV2.tsx

@@ -1,403 +0,0 @@
-import React, { useEffect, useState } from "react";
-import styled from "styled-components";
-import Modal from "main/home/modals/Modal";
-import EnvEditorModal from "main/home/modals/EnvEditorModal";
-
-import upload from "assets/upload.svg";
-import { MultiLineInput } from "components/porter-form/field-components/KeyValueArray";
-import { dotenv_parse } from "shared/string_utils";
-import { NewPopulatedEnvGroup, PopulatedEnvGroup } from "components/porter-form/types";
-import Text from "components/porter/Text";
-import Spacer from "components/porter/Spacer";
-export type KeyValueType = {
-  key: string;
-  value: string;
-  hidden: boolean;
-  locked: boolean;
-  deleted: boolean;
-};
-
-type PropsType = {
-  label?: string;
-  values: KeyValueType[];
-  setValues: (x: KeyValueType[]) => void;
-  disabled?: boolean;
-  fileUpload?: boolean;
-  secretOption?: boolean;
-  syncedEnvGroups?: NewPopulatedEnvGroup[];
-};
-
-const EnvGroupArrayV2 = ({
-  label,
-  values,
-  setValues,
-  disabled,
-  fileUpload,
-  secretOption,
-  syncedEnvGroups
-}: PropsType) => {
-  const [showEditorModal, setShowEditorModal] = useState(false);
-
-  useEffect(() => {
-    if (!values) {
-      setValues([]);
-    }
-  }, [values]);
-  const isKeyOverriding = (key: string) => {
-    if (!syncedEnvGroups) return false;
-    return syncedEnvGroups.some(envGroup =>
-      key in envGroup.variables || key in envGroup?.secret_variables
-    );
-  };
-
-  const readFile = (env: string) => {
-    const envObj = dotenv_parse(env);
-    const _values = [...values];
-
-    for (const key in envObj) {
-      let push = true;
-
-      for (let i = 0; i < values.length; i++) {
-        const existingKey = values[i]["key"];
-        const isExistingKeyDeleted = values[i]["deleted"];
-        if (key === existingKey && !isExistingKeyDeleted) {
-          _values[i]["value"] = envObj[key];
-          push = false;
-        }
-      }
-
-      if (push) {
-        _values.push({
-          key,
-          value: envObj[key],
-          hidden: false,
-          locked: false,
-          deleted: false,
-        });
-      }
-    }
-
-    setValues(_values);
-  };
-
-  if (!values) {
-    return null;
-  }
-
-  return (
-    <>
-      <StyledInputArray>
-        <Label>{label}</Label>
-        {!!values?.length &&
-          values.map((entry: KeyValueType, i: number) => {
-            if (!entry.deleted) {
-              return (
-                <InputWrapper key={i}>
-                  <Input
-                    placeholder="ex: key"
-                    width="270px"
-                    value={entry.key}
-                    onChange={(e: any) => {
-                      const _values = [...values];
-                      _values[i].key = e.target.value;
-                      setValues(_values);
-                    }}
-                    disabled={disabled || entry.locked}
-                    spellCheck={false}
-                    override={isKeyOverriding(entry.key)}
-                  />
-                  < Spacer x={.5} inline />
-                  {entry.hidden ? (
-                    entry.value?.includes("PORTERSECRET") ? (
-                      <Input
-                        placeholder="ex: value"
-                        width="270px"
-                        value={entry.value}
-                        disabled
-                        type={"password"}
-                        spellCheck={false}
-                        override={isKeyOverriding(entry.key)}
-                      />) : (
-                      <Input
-                        placeholder="ex: value"
-                        width="270px"
-                        value={entry.value}
-                        onChange={(e: any) => {
-                          const _values = [...values];
-                          _values[i].value = e.target.value;
-                          setValues(_values);
-                        }}
-                        disabled={disabled || entry.locked}
-                        type={entry.hidden ? "password" : "text"}
-                        spellCheck={false}
-                        override={isKeyOverriding(entry.key)}
-
-                      />)
-                  ) : (
-                    entry.value?.includes("PORTERSECRET") ? (
-                      <Input
-                        placeholder="ex: value"
-                        width="270px"
-                        value={entry.value}
-                        disabled
-                        type={"password"}
-                        spellCheck={false}
-                        override={isKeyOverriding(entry.key)}
-                      />) : (
-                      <MultiLineInputer
-                        placeholder="ex: value"
-                        width="270px"
-                        value={entry.value}
-                        onChange={(e: any) => {
-                          const _values = [...values];
-                          _values[i].value = e.target.value;
-                          setValues(_values);
-                        }}
-                        rows={entry.value?.split("\n").length}
-                        disabled={disabled || entry.locked}
-                        spellCheck={false}
-                        override={isKeyOverriding(entry.key)}
-                      />
-                    ))
-                  }
-                  {(
-                    <HideButton
-                      onClick={() => {
-                        if (!entry.locked) {
-                          const values1 = [...values];
-                          values1[i].hidden = !values1[i].hidden;
-                          setValues(values1);
-                        }
-                      }}
-                      disabled={entry.locked}
-                    >
-                      {entry.hidden ? (
-                        <i className="material-icons">lock</i>
-                      ) : (
-                        <i className="material-icons">lock_open</i>
-                      )}
-                    </HideButton>
-                  )}
-
-                  {!disabled && (
-                    <DeleteButton
-                      onClick={() => {
-                        setValues(values.filter((val, index) => index !== i));
-                      }}
-                    >
-                      <i className="material-icons">cancel</i>
-                    </DeleteButton>
-                  )}
-
-                  {isKeyOverriding(entry.key) && <><Spacer x={1} inline /> <Text color={'#6b74d6'} >Key is overriding value in a environment group</Text></>}
-                </InputWrapper>
-              );
-            }
-          })}
-        {!disabled && (
-          <InputWrapper>
-            <AddRowButton
-              onClick={() => {
-                const _values = [
-                  ...values,
-                  {
-                    key: "",
-                    value: "",
-                    hidden: false,
-                    locked: false,
-                    deleted: false,
-                  },
-                ];
-                setValues(_values);
-              }}
-            >
-              <i className="material-icons">add</i> Add Row
-            </AddRowButton>
-            <Spacer x={.5} inline />
-            {fileUpload && (
-              <UploadButton
-                onClick={() => {
-                  setShowEditorModal(true);
-                }}
-              >
-                <img src={upload} /> Copy from File
-              </UploadButton>
-            )}
-          </InputWrapper>
-        )}
-      </StyledInputArray>
-      {showEditorModal && (
-        <Modal
-          onRequestClose={() => setShowEditorModal(false)}
-          width="60%"
-          height="650px"
-        >
-          <EnvEditorModal
-            closeModal={() => setShowEditorModal(false)}
-            setEnvVariables={(envFile: string) => readFile(envFile)}
-          />
-        </Modal>
-      )}
-    </>
-  );
-};
-
-export default EnvGroupArrayV2;
-
-
-const AddRowButton = styled.div`
-  display: flex;
-  align-items: center;
-  width: 270px;
-  font-size: 13px;
-  color: #aaaabb;
-  height: 32px;
-  border-radius: 3px;
-  cursor: pointer;
-  background: #ffffff11;
-  :hover {
-    background: #ffffff22;
-  }
-
-  > i {
-    color: #ffffff44;
-    font-size: 16px;
-    margin-left: 8px;
-    margin-right: 10px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-  }
-`;
-
-const UploadButton = styled(AddRowButton)`
-  background: none;
-  position: relative;
-  border: 1px solid #ffffff55;
-  > i {
-    color: #ffffff44;
-    font-size: 16px;
-    margin-left: 8px;
-    margin-right: 10px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-  }
-  > img {
-    width: 14px;
-    margin-left: 10px;
-    margin-right: 12px;
-  }
-`;
-
-const DeleteButton = styled.div`
-  width: 15px;
-  height: 15px;
-  display: flex;
-  align-items: center;
-  margin-left: 8px;
-  margin-top: -3px;
-  justify-content: center;
-
-  > i {
-    font-size: 17px;
-    color: #ffffff44;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
-    :hover {
-      color: #ffffff88;
-    }
-  }
-`;
-
-const HideButton = styled(DeleteButton)`
-  margin-top: -5px;
-  > i {
-    font-size: 19px;
-    cursor: ${(props: { disabled: boolean }) =>
-    props.disabled ? "default" : "pointer"};
-    :hover {
-      color: ${(props: { disabled: boolean }) =>
-    props.disabled ? "#ffffff44" : "#ffffff88"};
-    }
-  }
-`;
-
-const InputWrapper = styled.div`
-  display: flex;
-  align-items: center;
-  margin-top: 5px;
-
-`;
-
-type InputProps = {
-  disabled?: boolean;
-  width: string;
-  override?: boolean;
-};
-
-const Input = styled.input<InputProps>`
-  outline: none;
-  border: none;
-  margin-bottom: 5px;
-  font-size: 13px;
-  background: #ffffff11;
-  border: ${(props) => (props.override ? '2px solid #6b74d6' : ' 1px solid #ffffff55')};
-  border-radius: 3px;
-  width: ${(props) => props.width ? props.width : "270px"};
-  color: ${(props) => props.disabled ? "#ffffff44" : "white"};
-  padding: 5px 10px;
-  height: 35px;
-`;
-const Label = styled.div`
-  color: #ffffff;
-  margin-bottom: 10px;
-`;
-
-const StyledInputArray = styled.div`
-  margin-bottom: 15px;
-  margin-top: 22px;
-`;
-
-export const MultiLineInputer = styled.textarea<InputProps>`
-  outline: none;
-  border: none;
-  margin-bottom: 5px;
-  font-size: 13px;
-  background: #ffffff11;
-  border: ${(props) => (props.override ? '2px solid #6b74d6' : ' 1px solid #ffffff55')};
-  border-radius: 3px;
-  min-width: ${(props) => (props.width ? props.width : "270px")};
-  max-width: ${(props) => (props.width ? props.width : "270px")};
-  color: ${(props) => (props.disabled ? "#ffffff44" : "white")};
-  padding: 8px 10px 5px 10px;
-  min-height: 35px;
-  max-height: 100px;
-  white-space: nowrap;
-
-  ::-webkit-scrollbar {
-    width: 8px;
-    :horizontal {
-      height: 8px;
-    }
-  }
-
-  ::-webkit-scrollbar-corner {
-    width: 10px;
-    background: #ffffff11;
-    color: white;
-  }
-
-  ::-webkit-scrollbar-track {
-    width: 10px;
-    -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
-    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
-  }
-
-  ::-webkit-scrollbar-thumb {
-    background-color: darkgrey;
-    outline: 1px solid slategrey;
-  }
-`;