Skip to content

Commit

Permalink
Merge pull request Infisical#304 from Infisical/secret-tagging
Browse files Browse the repository at this point in the history
Revamped the dashboard look
  • Loading branch information
vmatsiiako authored Feb 6, 2023
2 parents 56a1492 + 086dd62 commit 56da34d
Show file tree
Hide file tree
Showing 18 changed files with 388 additions and 148 deletions.
39 changes: 39 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@radix-ui/react-checkbox": "^1.0.1",
"@radix-ui/react-dialog": "^1.0.2",
"@radix-ui/react-dropdown-menu": "^2.0.2",
"@radix-ui/react-hover-card": "^1.0.3",
"@radix-ui/react-label": "^2.0.0",
"@radix-ui/react-popover": "^1.0.3",
"@radix-ui/react-progress": "^1.0.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"save-changes": "Save Changes",
"saved": "Saved",
"drop-zone": "Drag and drop a .env or .yml file here.",
"drop-zone-keys": "Drag and drop a .env or .yml file here to add more keys.",
"drop-zone-keys": "Drag and drop a .env or .yml file here to add more secrets.",
"role": "Role",
"role_admin": "admin",
"display-name": "Display Name",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/basic/Listbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const ListBox = ({
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="border border-mineshaft-700 z-50 p-2 absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-bunker text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
<Listbox.Options className="border border-mineshaft-700 z-[70] p-2 absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-bunker text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm no-scrollbar no-scrollbar::-webkit-scrollbar">
{data.map((person, personIdx) => (
<Listbox.Option
key={`${person}.${personIdx + 1}`}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/basic/dialog/DeleteEnvVar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const DeleteEnvVar = ({ isOpen, onClose, onSubmit }: Props) => {
return (
<div>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={() => {}}>
<Dialog as="div" className="relative z-[80]" onClose={() => {}}>
<div className="fixed inset-0 overflow-y-auto">
<Transition.Child
as={Fragment}
Expand Down
126 changes: 97 additions & 29 deletions frontend/src/components/dashboard/DashboardInputField.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { memo, SyntheticEvent, useRef } from 'react';
import { faCircle } from '@fortawesome/free-solid-svg-icons';
import { faCircle, faExclamationCircle, faEye, faLayerGroup } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import guidGenerator from '../utilities/randomId';
import { Button } from '../v2';
import { HoverObject } from '../v2/HoverCard';

const REGEX = /([$]{.*?})/g;

interface DashboardInputFieldProps {
position: number;
onChangeHandler: (value: string, position: number) => void;
value: string | undefined;
type: 'varName' | 'value';
type: 'varName' | 'value' | 'comment';
blurred?: boolean;
isDuplicate?: boolean;
override?: boolean;
overrideEnabled?: boolean;
modifyValueOverride?: (value: string | undefined, position: number) => void;
isSideBarOpen?: boolean;
}

/**
Expand All @@ -26,6 +30,8 @@ interface DashboardInputFieldProps {
* @param {boolean} obj.blurred - whether the input field should be blurred (behind the gray dots) or not; this can be turned on/off in the dashboard
* @param {boolean} obj.isDuplicate - if the key name is duplicated
* @param {boolean} obj.override - whether a secret/row should be displalyed as overriden
*
*
* @returns
*/

Expand All @@ -36,7 +42,9 @@ const DashboardInputField = ({
value,
blurred,
isDuplicate,
override
overrideEnabled,
modifyValueOverride,
isSideBarOpen
}: DashboardInputFieldProps) => {
const ref = useRef<HTMLDivElement | null>(null);
const syncScroll = (e: SyntheticEvent<HTMLDivElement>) => {
Expand All @@ -51,41 +59,97 @@ const DashboardInputField = ({
const error = startsWithNumber || isDuplicate;

return (
<div className="flex-col w-full">
<div className={`relative flex-col w-full h-10 ${
error && value !== '' ? 'bg-red/[0.15]' : ''
} ${
isSideBarOpen && 'bg-mineshaft-700 duration-200'
}`}>
<div
className={`group relative flex flex-col justify-center w-full border ${
error ? 'border-red' : 'border-mineshaft-500'
} rounded-md`}
className={`group relative flex flex-col justify-center items-center h-full ${
error ? 'w-max' : 'w-full'
}`}
>
<input
onChange={(e) => onChangeHandler(e.target.value.toUpperCase(), position)}
type={type}
value={value}
className={`z-10 peer font-mono ph-no-capture bg-bunker-800 rounded-md caret-white text-gray-400 text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 ${
error ? 'focus:ring-red/50' : 'focus:ring-primary/50'
className={`z-10 peer font-mono ph-no-capture bg-transparent h-full caret-bunker-200 text-sm px-2 w-full min-w-16 outline-none ${
error ? 'text-red-600 focus:text-red-500' : 'text-bunker-300 focus:text-bunker-100'
} duration-200`}
spellCheck="false"
/>
</div>
{startsWithNumber && (
<p className="text-red text-xs mt-0.5 mx-1 mb-2 max-w-xs">
Should not start with a number
</p>
<div className='absolute right-2 top-2 text-red z-50'>
<HoverObject
text="Secret names should not start with a number"
icon={faExclamationCircle}
color="red"
/>
</div>
)}
{isDuplicate && !startsWithNumber && (
<p className="text-red text-xs mt-0.5 mx-1 mb-2 max-w-xs">
Secret names should be unique
</p>
{isDuplicate && value !== '' && !startsWithNumber && (
<div className='absolute right-2 top-2 text-red z-50'>
<HoverObject
text="Secret names should be unique"
icon={faExclamationCircle}
color="red"
/>
</div>
)}
{!error && <div className={`absolute right-0 top-0 text-red z-50 ${
overrideEnabled ? 'visible group-hover:bg-mineshaft-700' : 'invisible group-hover:visible bg-mineshaft-700'
} cursor-pointer duration-0`}>
<Button variant="plain" onClick={() => {
if (modifyValueOverride) {
if (overrideEnabled === false) {
modifyValueOverride('', position);
} else {
modifyValueOverride(undefined, position);
}
}
}}>
<HoverObject
text={overrideEnabled ? 'This secret is overriden with your personal value' : 'You can override this secret with a personal value'}
icon={faLayerGroup}
color={overrideEnabled ? 'primary' : 'bunker-400'}
/>
</Button>
</div>}
</div>
);
}
if (type === 'comment') {
const startsWithNumber = !Number.isNaN(Number(value?.charAt(0))) && value !== '';
const error = startsWithNumber || isDuplicate;

return (
<div className={`relative flex-col w-full h-10 ${
isSideBarOpen && 'bg-mineshaft-700 duration-200'
}`}>
<div
className={`group relative flex flex-col justify-center items-center ${
error ? 'w-max' : 'w-full'
}`}
>
<input
onChange={(e) => onChangeHandler(e.target.value, position)}
type={type}
value={value}
className='z-10 peer font-mono ph-no-capture bg-transparent py-2.5 caret-bunker-200 text-sm px-2 w-full min-w-16 outline-none text-bunker-300 focus:text-bunker-100 placeholder:text-bunker-400 placeholder:focus:text-transparent placeholder duration-200'
spellCheck="false"
placeholder='–'
/>
</div>
</div>
);
}
if (type === 'value') {
return (
<div className="flex-col w-full">
<div className="group relative whitespace-pre flex flex-col justify-center w-full border border-mineshaft-500 rounded-md">
{override === true && (
<div className="bg-primary-300 absolute top-[0.1rem] right-[0.1rem] z-10 w-min text-xxs px-1 text-black opacity-80 rounded-md">
<div className="group relative whitespace-pre flex flex-col justify-center w-full">
{overrideEnabled === true && (
<div className="bg-primary-500 rounded-sm absolute top-[0.1rem] right-[0.1rem] z-0 w-min text-xxs px-1 text-black opacity-80">
Override enabled
</div>
)}
Expand All @@ -95,19 +159,19 @@ const DashboardInputField = ({
onScroll={syncScroll}
className={`${
blurred
? 'text-transparent group-hover:text-transparent focus:text-transparent active:text-transparent'
? 'text-transparent focus:text-transparent active:text-transparent'
: ''
} z-10 peer font-mono ph-no-capture bg-transparent rounded-md caret-white text-transparent text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 focus:ring-primary/50 duration-200 no-scrollbar no-scrollbar::-webkit-scrollbar`}
} z-10 peer font-mono ph-no-capture bg-transparent caret-white text-transparent text-sm px-2 py-2 w-full min-w-16 outline-none duration-200 no-scrollbar no-scrollbar::-webkit-scrollbar`}
spellCheck="false"
/>
<div
ref={ref}
className={`${
blurred && !override
? 'text-bunker-800 group-hover:text-gray-400 peer-focus:text-gray-400 peer-active:text-gray-400'
blurred && !overrideEnabled
? 'text-bunker-800 group-hover:text-gray-400 peer-focus:text-gray-100 peer-active:text-gray-400 duration-200'
: ''
} ${override ? 'text-primary-300' : 'text-gray-400'}
absolute flex flex-row whitespace-pre font-mono z-0 ph-no-capture overflow-x-scroll bg-bunker-800 h-9 rounded-md text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 focus:ring-primary/50 duration-100 no-scrollbar no-scrollbar::-webkit-scrollbar`}
} ${overrideEnabled ? 'text-primary-300' : 'text-gray-400'}
absolute flex flex-row whitespace-pre font-mono z-0 ${blurred ? '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`}
>
{value?.split(REGEX).map((word, id) => {
if (word.match(REGEX) !== null) {
Expand Down Expand Up @@ -137,7 +201,9 @@ const DashboardInputField = ({
})}
</div>
{blurred && (
<div className="absolute flex flex-row items-center z-20 peer pr-2 bg-bunker-800 group-hover:hidden peer-hover:hidden peer-focus:hidden peer-active:invisible h-9 w-full rounded-md text-gray-400/50 text-clip">
<div className={`absolute flex flex-row justify-between items-center z-0 peer pr-2 ${
isSideBarOpen ? 'bg-mineshaft-700 duration-200' : 'bg-mineshaft-800'
} 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">
{value?.split('').map(() => (
<FontAwesomeIcon
Expand All @@ -146,7 +212,9 @@ const DashboardInputField = ({
icon={faCircle}
/>
))}
{value?.split('').length === 0 && <span className='text-bunker-400/80'>EMPTY</span>}
</div>
<div className='invisible group-hover:visible cursor-pointer'><FontAwesomeIcon icon={faEye} /></div>
</div>
)}
</div>
Expand All @@ -163,8 +231,8 @@ function inputPropsAreEqual(prev: DashboardInputFieldProps, next: DashboardInput
prev.type === next.type &&
prev.position === next.position &&
prev.blurred === next.blurred &&
prev.override === next.override &&
prev.isDuplicate === next.isDuplicate
prev.overrideEnabled === next.overrideEnabled &&
prev.isDuplicate === next.isDuplicate
);
}

Expand Down
26 changes: 21 additions & 5 deletions frontend/src/components/dashboard/DeleteActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next';
import { faXmark } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import Button from '../basic/buttons/Button';
import { DeleteEnvVar } from '../basic/dialog/DeleteEnvVar';

type Props = {
onSubmit: () => void
onSubmit: () => void;
isPlain?: boolean;
}

export const DeleteActionButton = ({ onSubmit }: Props) => {
export const DeleteActionButton = ({ onSubmit, isPlain }: Props) => {
const { t } = useTranslation();
const [open, setOpen] = useState(false)

return (
<div className="bg-[#9B3535] opacity-70 hover:opacity-100 w-[4.5rem] h-[2.5rem] rounded-md duration-200 ml-2">
<Button
<div className={`${
!isPlain
? 'bg-[#9B3535] opacity-70 hover:opacity-100 w-[4.5rem] h-[2.5rem] rounded-md duration-200 ml-2'
: 'cursor-pointer w-[2.35rem] h-[2.35rem] flex items-center justfy-center'}`}>
{isPlain
? <div
onKeyDown={() => null}
role="button"
tabIndex={0}
onClick={() => setOpen(true)}
className="invisible group-hover:visible"
>
<FontAwesomeIcon className="text-bunker-300 hover:text-red pl-2 pr-6 text-lg mt-0.5" icon={faXmark} />
</div>
: <Button
text={String(t("Delete"))}
// onButtonPressed={onSubmit}
color="red"
size="md"
onButtonPressed={() => setOpen(true)}
/>
/>}
<DeleteEnvVar
isOpen={open}
onClose={() => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/dashboard/DownloadSecretsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const DownloadSecretMenu = ({ data, env }: { data: SecretDataProps[]; env: strin
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute z-50 drop-shadow-xl right-0 mt-0.5 w-[12rem] origin-top-right rounded-md bg-bunker border border-mineshaft-500 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none p-2 space-y-2">
<Menu.Items className="absolute z-[90] drop-shadow-xl right-0 mt-0.5 w-[12rem] origin-top-right rounded-md bg-bunker border border-mineshaft-500 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none p-2 space-y-2">
<Menu.Item>
<Button
color="mineshaft"
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/dashboard/DropZone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ const DropZone = ({
</div>
) : keysExist ? (
<div
className="opacity-60 hover:opacity-100 duration-200 relative bg-mineshaft-900 max-w-[calc(100%-1rem)] w-full outline-dashed outline-chicago-600 rounded-md outline-2 flex flex-col items-center justify-center mb-16 mx-auto mt-1 py-8 px-2"
className="opacity-60 hover:opacity-100 duration-200 relative bg-mineshaft-900 max-w-[calc(100%-1rem)] w-full outline-dashed outline-chicago-600 rounded-md outline-2 flex flex-col items-center justify-center mb-4 mx-auto mt-1 py-8 px-2"
onDragEnter={handleDragEnter}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
Expand Down
Loading

0 comments on commit 56da34d

Please sign in to comment.