)?.slug
+ );
+ handlePopUpClose('deleteEnv');
+ } catch (error) {
+ console.error(error);
+ }
+ };
+
+ return (
+ <>
+
+
+
Project Environments
+
+ Choose which environments will show up in your dashboard like
+ development, staging, production
+
+
+ Note: the text in slugs shows how these environmant should be
+ accessed in CLI.
+
+
+
+
+
+
+
+
+
+
+ Name |
+ Slug |
+ |
+
+
+
+ {data?.length > 0 ? (
+ data.map(({ name, slug }) => {
+ return (
+
+
+ {name}
+ |
+
+ {slug}
+ |
+
+
+
+
+
+ |
+
+ );
+ })
+ ) : (
+
+
+ No environmants found
+ |
+
+ )}
+
+
+
handlePopUpClose('deleteEnv')}
+ onSubmit={onEnvDeleteCB}
+ />
+ handlePopUpClose('createUpdateEnv')}
+ onCreateSubmit={onEnvCreateCB}
+ onEditSubmit={onEnvUpdateCB}
+ />
+
+ >
+ );
+};
+
+export default EnvironmentTable;
diff --git a/frontend/components/basic/table/ServiceTokenTable.tsx b/frontend/components/basic/table/ServiceTokenTable.tsx
index 412a0dbfbc..4d30b30139 100644
--- a/frontend/components/basic/table/ServiceTokenTable.tsx
+++ b/frontend/components/basic/table/ServiceTokenTable.tsx
@@ -3,7 +3,6 @@ import { faX } from '@fortawesome/free-solid-svg-icons';
import { useNotificationContext } from '~/components/context/Notifications/NotificationProvider';
import deleteServiceToken from "../../../pages/api/serviceToken/deleteServiceToken";
-import { reverseEnvMapping } from '../../../public/data/frequentConstants';
import guidGenerator from '../../utilities/randomId';
import Button from '../buttons/Button';
@@ -60,7 +59,7 @@ const ServiceTokenTable = ({ data, workspaceName, setServiceTokens }: ServiceTok
{workspaceName}
- {reverseEnvMapping[row.environment]}
+ {row.environment}
|
{new Date(row.expiresAt).toUTCString()}
diff --git a/frontend/components/dashboard/DashboardInputField.tsx b/frontend/components/dashboard/DashboardInputField.tsx
index a667c39d0f..c19f6f4f95 100644
--- a/frontend/components/dashboard/DashboardInputField.tsx
+++ b/frontend/components/dashboard/DashboardInputField.tsx
@@ -9,7 +9,7 @@ const REGEX = /([$]{.*?})/g;
interface DashboardInputFieldProps {
position: number;
onChangeHandler: (value: string, position: number) => void;
- value: string;
+ value: string | undefined;
type: 'varName' | 'value';
blurred?: boolean;
isDuplicate?: boolean;
@@ -47,7 +47,7 @@ const DashboardInputField = ({
};
if (type === 'varName') {
- const startsWithNumber = !isNaN(Number(value.charAt(0))) && value != '';
+ const startsWithNumber = !isNaN(Number(value?.charAt(0))) && value != '';
const error = startsWithNumber || isDuplicate;
return (
@@ -141,7 +141,7 @@ const DashboardInputField = ({
{blurred && (
- {value.split('').map(() => (
+ {value?.split('').map(() => (
void;
modifyValue: (value: string, position: number) => void;
+ modifyValueOverride: (value: string, position: number) => void;
isBlurred: boolean;
isDuplicate: boolean;
toggleSidebar: (id: string) => void;
@@ -30,6 +23,7 @@ interface KeyPairProps {
* @param {String[]} obj.keyPair - data related to the environment variable (id, pos, key, value, public/private)
* @param {function} obj.modifyKey - modify the key of a certain environment variable
* @param {function} obj.modifyValue - modify the value of a certain environment variable
+ * @param {function} obj.modifyValueOverride - modify the value of a certain environment variable if it is overriden
* @param {boolean} obj.isBlurred - if the blurring setting is turned on
* @param {boolean} obj.isDuplicate - list of all the duplicates secret names on the dashboard
* @param {function} obj.toggleSidebar - open/close/switch sidebar
@@ -41,6 +35,7 @@ const KeyPair = ({
keyPair,
modifyKey,
modifyValue,
+ modifyValueOverride,
isBlurred,
isDuplicate,
toggleSidebar,
@@ -50,7 +45,7 @@ const KeyPair = ({
return (
- {keyPair.type == "personal" &&
+ {keyPair.valueOverride &&
This secret is overriden
@@ -70,12 +65,12 @@ const KeyPair = ({
diff --git a/frontend/components/dashboard/SideBar.tsx b/frontend/components/dashboard/SideBar.tsx
index 33b936f521..32cdf7341d 100644
--- a/frontend/components/dashboard/SideBar.tsx
+++ b/frontend/components/dashboard/SideBar.tsx
@@ -16,18 +16,15 @@ import GenerateSecretMenu from './GenerateSecretMenu';
interface SecretProps {
key: string;
value: string;
+ valueOverride: string | undefined;
pos: number;
- type: string;
id: string;
comment: string;
}
interface OverrideProps {
id: string;
- keyName: string;
- value: string;
- pos: number;
- comment: string;
+ valueOverride: string;
}
export interface DeleteRowFunctionProps {
ids: string[];
@@ -39,9 +36,8 @@ interface SideBarProps {
data: SecretProps[];
modifyKey: (value: string, position: number) => void;
modifyValue: (value: string, position: number) => void;
+ modifyValueOverride: (value: string | undefined, position: number) => void;
modifyComment: (value: string, position: number) => void;
- addOverride: (value: OverrideProps) => void;
- deleteOverride: (id: string) => void;
buttonReady: boolean;
savePush: () => void;
sharedToHide: string[];
@@ -55,12 +51,9 @@ interface SideBarProps {
* @param {SecretProps[]} obj.data - data of a certain key valeu pair
* @param {function} obj.modifyKey - function that modifies the secret key
* @param {function} obj.modifyValue - function that modifies the secret value
- * @param {function} obj.addOverride - override a certain secret
- * @param {function} obj.deleteOverride - delete the personal override for a certain secret
+ * @param {function} obj.modifyValueOverride - function that modifies the secret value if it is an override
* @param {boolean} obj.buttonReady - is the button for saving chagnes active
* @param {function} obj.savePush - save changes andp ush secrets
- * @param {string[]} obj.sharedToHide - an array of shared secrets that we want to hide visually because they are overriden.
- * @param {function} obj.setSharedToHide - a function that updates the array of secrets that we want to hide visually
* @param {function} obj.deleteRow - a function to delete a certain keyPair
* @returns the sidebar with 'secret's settings'
*/
@@ -69,17 +62,14 @@ const SideBar = ({
data,
modifyKey,
modifyValue,
+ modifyValueOverride,
modifyComment,
- addOverride,
- deleteOverride,
buttonReady,
savePush,
- sharedToHide,
- setSharedToHide,
deleteRow
}: SideBarProps) => {
const [isLoading, setIsLoading] = useState(false);
- const [overrideEnabled, setOverrideEnabled] = useState(data.map(secret => secret.type).includes("personal"));
+ const [overrideEnabled, setOverrideEnabled] = useState(data[0].valueOverride != undefined);
const { t } = useTranslation();
return
@@ -111,19 +101,19 @@ const SideBar = ({
blurred={false}
/>
- {data.filter(secret => secret.type == "shared")[0]?.value
+ {data[0]?.value
?
{t("dashboard:sidebar.value")}
secret.type == "shared")[0]?.pos}
- value={data.filter(secret => secret.type == "shared")[0]?.value}
+ position={data[0].pos}
+ value={data[0]?.value}
isDuplicate={false}
blurred={true}
/>
- secret.type == "shared")[0]?.pos} />
+
:
@@ -131,39 +121,32 @@ const SideBar = ({
{t("dashboard:sidebar.personal-explanation")}
}
- {data.filter(secret => secret.type == "shared")[0]?.value &&
+ {data[0]?.value &&
{t("dashboard:sidebar.override")}
}
secret.type == "personal")[0]?.pos : data[0]?.pos}
- value={overrideEnabled ? data.filter(secret => secret.type == "personal")[0]?.value : data[0]?.value}
+ position={data[0]?.pos}
+ value={overrideEnabled ? data[0]?.valueOverride : data[0]?.value}
isDuplicate={false}
blurred={true}
/>
- secret.type == "personal")[0]?.pos : data[0]?.pos} />
+
- secret.type == "shared")[0]?.comment} modifyComment={modifyComment} position={data.filter(secret => secret.type == "shared")[0]?.pos} />
+
)}
@@ -176,7 +159,7 @@ const SideBar = ({
textDisabled="Saved"
/>
deleteRow({ ids: overrideEnabled ? data.map(secret => secret.id) : [data.filter(secret => secret.type == "shared")[0]?.id], secretName: data[0]?.key })}
+ onSubmit={() => deleteRow({ ids: data.map(secret => secret.id), secretName: data[0]?.key })}
/>
diff --git a/frontend/components/integrations/CloudIntegration.tsx b/frontend/components/integrations/CloudIntegration.tsx
index 75a8019a5e..dd1b13f47e 100644
--- a/frontend/components/integrations/CloudIntegration.tsx
+++ b/frontend/components/integrations/CloudIntegration.tsx
@@ -74,7 +74,7 @@ const CloudIntegration = ({
integrationAuths
.map((authorization) => authorization.integration)
.includes(cloudIntegrationOption.name.toLowerCase()) && (
-
+
{
event.stopPropagation();
diff --git a/frontend/components/integrations/Integration.tsx b/frontend/components/integrations/Integration.tsx
index 11edf7cb70..bbc8861dc6 100644
--- a/frontend/components/integrations/Integration.tsx
+++ b/frontend/components/integrations/Integration.tsx
@@ -15,9 +15,7 @@ import getIntegrationApps from "../../pages/api/integrations/GetIntegrationApps"
import updateIntegration from "../../pages/api/integrations/updateIntegration"
import {
contextNetlifyMapping,
- envMapping,
reverseContextNetlifyMapping,
- reverseEnvMapping,
} from "../../public/data/frequentConstants";
interface Integration {
@@ -36,13 +34,23 @@ interface IntegrationApp {
siteId: string;
}
-const Integration = ({
- integration
-}: {
+type Props = {
integration: Integration;
-}) => {
- const [integrationEnvironment, setIntegrationEnvironment] = useState(
- reverseEnvMapping[integration.environment]
+ environments: Array<{ name: string; slug: string }>;
+};
+
+const Integration = ({
+ integration,
+ environments = []
+}:Props ) => {
+ // set initial environment. This find will only execute when component is mounting
+ const [integrationEnvironment, setIntegrationEnvironment] = useState<
+ Props['environments'][0]
+ >(
+ environments.find(({ slug }) => slug === integration.environment) || {
+ name: '',
+ slug: '',
+ }
);
const [fileState, setFileState] = useState([]);
const router = useRouter();
@@ -93,7 +101,7 @@ const Integration = ({
case "vercel":
return (
-
);
@@ -136,42 +145,47 @@ const Integration = ({
if (!integrationApp || apps.length === 0) return
return (
-
-
+
+
- ENVIRONMENT
- {
- setIntegrationEnvironment(environment);
- }}
+
+ ENVIRONMENT
+
+ name)
+ : null
+ }
+ selected={integrationEnvironment.name}
+ onChange={(envName) =>
+ setIntegrationEnvironment(
+ environments.find(({ name }) => envName === name) || {
+ name: 'unknown',
+ slug: 'unknown',
+ }
+ )
+ }
isFull={true}
/>
-
+
+ className='mx-4 text-gray-400 mt-8'
+ />
-
-
+
+
INTEGRATION
-
+
{integration.integration.charAt(0).toUpperCase() +
integration.integration.slice(1)}
-
-
- APP
-
+
+ APP
app.name) : null}
selected={integrationApp}
@@ -182,52 +196,55 @@ const Integration = ({
{renderIntegrationSpecificParams(integration)}
-
- {integration.isActive ? (
-
- ) : (
- |