Finished the env overview feature

This commit is contained in:
Vladyslav Matsiiako
2023-04-14 18:20:19 -07:00
parent 810554e13c
commit 903560a2d1
13 changed files with 222 additions and 255 deletions
@@ -1,22 +0,0 @@
export const EnvComparisonHeader = ({ userAvailableEnvs }: { userAvailableEnvs?: any[] }): JSX.Element => (
<thead>
<tr className="absolute flex flex-row sticky top-0 h-12">
<td className="w-10 px-4 flex items-center justify-center border-none">
<div className='text-center w-10 text-xs text-transparent'>{0}</div>
</td>
<td className="border-none">
<div className="min-w-[220px] lg:min-w-[240px] xl:min-w-[280px] relative flex items-center justify-end w-full">
<div className="text-sm font-medium text-transparent ">Secret</div>
</div>
</td>
{userAvailableEnvs?.map(env => {
return <>
<td className="w-10 px-4 flex items-center justify-center border-none">
<div className='text-center w-10 text-xs text-transparent'>{0}</div>
</td>
<th className="flex flex-row w-full bg-mineshaft-800 border border-mineshaft-600 rounded-t-md items-center"><div className="text-md font-medium w-full text-center">{env.name}</div></th>
</>
})}
</tr>
</thead>
);
@@ -1 +0,0 @@
export { EnvComparisonHeader } from './EnvComparison';
@@ -1,27 +1,25 @@
/* eslint-disable react/jsx-no-useless-fragment */
import { SyntheticEvent, useRef } from 'react';
import { SyntheticEvent, useRef, useState } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { faCircle } from '@fortawesome/free-solid-svg-icons';
import { faCircle, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import guidGenerator from '@app/components/utilities/randomId';
import { Input } from '@app/components/v2';
import { FormData, SecretActionType } from '../../DashboardPage.utils';
import { FormData } from '../../DashboardPage.utils';
type Props = {
index: number;
secrets: any[] | undefined;
// permission and external state's that decided to hide or show
isReadOnly?: boolean;
isAddOnly?: boolean;
isSecretValueHidden: boolean;
userAvailableEnvs?: any[];
};
const REGEX = /([$]{.*?})/g;
const DashboardInput = ({ isOverridden, isSecretValueHidden, isAddOnly, isReadOnly, secret, shouldBeBlockedInAddOnly, index }: { isOverridden: boolean, isSecretValueHidden: boolean, isAddOnly?: boolean, isReadOnly?: boolean, secret: any, shouldBeBlockedInAddOnly?: boolean, index: number } ): JSX.Element => {
const DashboardInput = ({ isOverridden, isSecretValueHidden, isReadOnly, secret, index }: { isOverridden: boolean, isSecretValueHidden: boolean, isReadOnly?: boolean, secret: any, index: number } ): JSX.Element => {
const ref = useRef<HTMLDivElement | null>(null);
const syncScroll = (e: SyntheticEvent<HTMLDivElement>) => {
if (ref.current === null) return;
@@ -29,20 +27,19 @@ const DashboardInput = ({ isOverridden, isSecretValueHidden, isAddOnly, isReadOn
ref.current.scrollTop = e.currentTarget.scrollTop;
ref.current.scrollLeft = e.currentTarget.scrollLeft;
};
console.log(33333333, secret)
return <td className="flex flex-row w-full justify-center h-10 items-center bg-mineshaft-900">
return <td key={`row-${secret?.key || ''}--`} className={`flex flex-row w-full min-w-[11rem] justify-center h-10 items-center ${!(secret?.value || secret?.value === '') ? "bg-red-400/10" : "bg-mineshaft-900/30"}`}>
<div className="group relative whitespace-pre flex flex-col justify-center w-full">
<input
// {...register(`secrets.${index}.valueOverride`)}
value={(isOverridden ? secret.valueOverride : secret?.value || '-')}
defaultValue={(isOverridden ? secret.valueOverride : secret?.value || '')}
onScroll={syncScroll}
readOnly={isReadOnly || (isOverridden ? isAddOnly : shouldBeBlockedInAddOnly)}
readOnly={isReadOnly}
className={`${
isSecretValueHidden
? 'text-transparent focus:text-transparent active:text-transparent'
: ''
} z-10 peer font-mono ph-no-capture bg-transparent caret-transparent text-transparent text-sm px-2 py-2 w-full min-w-16 outline-none duration-200 no-scrollbar no-scrollbar::-webkit-scrollbar`}
} z-10 peer font-mono ph-no-capture bg-transparent caret-transparent text-transparent text-sm px-2 py-2 w-full outline-none duration-200 no-scrollbar no-scrollbar::-webkit-scrollbar`}
spellCheck="false"
/>
<div
@@ -54,11 +51,11 @@ const DashboardInput = ({ isOverridden, isSecretValueHidden, isAddOnly, isReadOn
} ${!secret?.value && "text-bunker-400 justify-center"}
absolute flex flex-row whitespace-pre font-mono z-0 ${isSecretValueHidden && secret?.value ? 'invisible' : 'visible'} peer-focus:visible mt-0.5 ph-no-capture overflow-x-scroll bg-transparent h-10 text-sm px-2 py-2 w-full min-w-16 outline-none duration-100 no-scrollbar no-scrollbar::-webkit-scrollbar`}
>
{(isOverridden ? secret.valueOverride : secret?.value || '-')?.split('').length === 0 && <span className='text-bunker-400/80 font-sans'>EMPTY</span>}
{(isOverridden ? secret.valueOverride : secret?.value || '-')?.split(REGEX).map((word: string) => {
{(secret?.value || secret?.value === '') && (isOverridden ? secret.valueOverride : secret?.value)?.split('').length === 0 && <span className='text-bunker-400/80 font-sans w-full'>EMPTY</span>}
{(secret?.value || secret?.value === '') && (isOverridden ? secret.valueOverride : secret?.value)?.split(REGEX).map((word: string) => {
if (word.match(REGEX) !== null) {
return (
<span className="ph-no-capture text-yellow" key={index}>
<span className="ph-no-capture text-yellow" key={word}>
{word.slice(0, 2)}
<span className="ph-no-capture text-yellow-200/80">
{word.slice(2, word.length - 1)}
@@ -81,18 +78,19 @@ const DashboardInput = ({ isOverridden, isSecretValueHidden, isAddOnly, isReadOn
</span>
);
})}
{!(secret?.value || secret?.value === '') && <span className='text-red-500/80 font-sans text-xs italic'>missing</span>}
</div>
{(isSecretValueHidden && secret?.value) && (
<div className='absolute flex flex-row justify-between items-center z-0 peer pr-2 peer-active:hidden peer-focus:hidden group-hover:bg-white/[0.00] duration-100 h-10 w-full text-bunker-400 text-clip'>
<div className="px-2 flex flex-row items-center overflow-x-scroll no-scrollbar no-scrollbar::-webkit-scrollbar">
{(isOverridden ? secret.valueOverride : secret?.value || '-')?.split('').map(() => (
{(isOverridden ? secret.valueOverride : secret?.value || '')?.split('').map(() => (
<FontAwesomeIcon
key={guidGenerator()}
className="text-xxs mr-0.5"
icon={faCircle}
/>
))}
{(isOverridden ? secret.valueOverride : secret?.value || '-')?.split('').length === 0 && <span className='text-bunker-400/80 text-sm'>EMPTY</span>}
{(isOverridden ? secret.valueOverride : secret?.value || '')?.split('').length === 0 && <span className='text-bunker-400/80 text-sm'>EMPTY</span>}
</div>
</div>
)}
@@ -105,48 +103,28 @@ export const EnvComparisonRow = ({
secrets,
isSecretValueHidden,
isReadOnly,
isAddOnly,
userAvailableEnvs
}: Props): JSX.Element => {
const {
// register, setValue,
control } = useFormContext<FormData>();
console.log(1282828822, userAvailableEnvs)
console.log('index', index)
// to get details on a secret
const secret = useWatch({ name: `secrets.${index}`, control });
// when secret is override by personal values
const isOverridden =
secret.overrideAction === SecretActionType.Created ||
secret.overrideAction === SecretActionType.Modified;
const isCreatedSecret = !secret?._id;
const shouldBeBlockedInAddOnly = !isCreatedSecret && isAddOnly;
console.log(893892749827097, secrets)
const [areValuesHiddenThisRow, setAreValuesHiddenThisRow] = useState(true);
return (
<tr className="group min-w-full flex flex-row items-center">
<td className="w-10 h-10 px-4 flex items-center justify-center"><div className='text-center w-10 text-xs text-bunker-400'>{index + 1}</div></td>
<td className="border-none">
<div className="min-w-[220px] lg:min-w-[240px] xl:min-w-[280px] relative flex items-center justify-end w-full">
<Input
autoComplete="off"
variant="plain"
isDisabled={isReadOnly || shouldBeBlockedInAddOnly}
className="w-full focus:text-bunker-100 focus:ring-transparent"
value={secret.key}
/>
</div>
<tr className="group min-w-full flex flex-row items-center hover:bg-bunker-700">
<td className="w-10 h-10 px-4 flex items-center justify-center border-none"><div className='text-center w-10 text-xs text-bunker-400'>{index + 1}</div></td>
<td className="flex flex-row justify-between items-center h-full min-w-[200px] lg:min-w-[220px] xl:min-w-[250px]">
<div className="flex flex-row items-center h-8">{secret?.key || ''}</div>
<button type="button" className='mr-2 text-bunker-400 hover:text-bunker-300 invisible group-hover:visible' onClick={() => setAreValuesHiddenThisRow(!areValuesHiddenThisRow)}>
<FontAwesomeIcon icon={areValuesHiddenThisRow ? faEye : faEyeSlash} />
</button>
</td>
{userAvailableEnvs?.map(env => {
return <>
<td className="w-10 px-4 flex items-center justify-center h-10">
<div className='text-center w-10 text-xs text-transparent'>{0}</div>
</td>
<DashboardInput isOverridden={isOverridden} isSecretValueHidden={isSecretValueHidden} isAddOnly={isAddOnly} isReadOnly={isReadOnly} secret={secrets?.filter(sec => sec.env === env.slug)[0]} shouldBeBlockedInAddOnly={shouldBeBlockedInAddOnly} index={index} />
</>
return <DashboardInput key={`row-${secret?.key || ''}-${env.slug}`} isOverridden={false} isSecretValueHidden={areValuesHiddenThisRow && isSecretValueHidden} isReadOnly={isReadOnly} secret={secrets?.filter(sec => sec.env === env.slug)[0]} index={index} />
})}
</tr>
);
@@ -156,7 +156,7 @@ export const SecretInputRow = ({
}
return (
<tr className="group min-w-full flex flex-row items-center">
<tr className="group min-w-full flex flex-row items-center" key={index}>
<td className="w-10 h-10 px-4 flex items-center justify-center"><div className='text-center w-10 text-xs text-bunker-400'>{index + 1}</div></td>
<Controller
control={control}
@@ -279,7 +279,7 @@ export const SecretInputRow = ({
{(isOverridden ? secret.valueOverride : secret.value)?.split(REGEX).map((word) => {
if (word.match(REGEX) !== null) {
return (
<span className="ph-no-capture text-yellow" key={index}>
<span className="ph-no-capture text-yellow" key={guidGenerator()}>
{word.slice(0, 2)}
<span className="ph-no-capture text-yellow-200/80">
{word.slice(2, word.length - 1)}