mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 07:35:09 +00:00
refactor(ui): changed frontend to normal i18n without SSR
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { faXmark } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
@@ -129,10 +129,10 @@ const ActivitySideBar = ({ toggleSidebar, currentAction }: SideBarProps) => {
|
||||
<div
|
||||
className={`absolute border-l border-mineshaft-500 ${
|
||||
isLoading ? 'bg-bunker-800' : 'bg-bunker'
|
||||
} fixed h-[calc(100vh-56px)] w-96 top-14 right-0 z-40 shadow-xl flex flex-col justify-between`}
|
||||
} fixed top-14 right-0 z-40 flex h-[calc(100vh-56px)] w-96 flex-col justify-between shadow-xl`}
|
||||
>
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center h-full mb-8">
|
||||
<div className="mb-8 flex h-full items-center justify-center">
|
||||
<Image
|
||||
src="/images/loading/loading.gif"
|
||||
height={60}
|
||||
@@ -142,9 +142,9 @@ const ActivitySideBar = ({ toggleSidebar, currentAction }: SideBarProps) => {
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-min">
|
||||
<div className="flex flex-row px-4 py-3 border-b border-mineshaft-500 justify-between items-center">
|
||||
<p className="font-semibold text-lg text-bunker-200">
|
||||
{t(`activity:event.${actionMetaData?.name}`)}
|
||||
<div className="flex flex-row items-center justify-between border-b border-mineshaft-500 px-4 py-3">
|
||||
<p className="text-lg font-semibold text-bunker-200">
|
||||
{t(`activity.event.${actionMetaData?.name}`)}
|
||||
</p>
|
||||
<div
|
||||
className="p-1"
|
||||
@@ -153,31 +153,35 @@ const ActivitySideBar = ({ toggleSidebar, currentAction }: SideBarProps) => {
|
||||
tabIndex={0}
|
||||
onClick={() => toggleSidebar('')}
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} className="w-4 h-4 text-bunker-300 cursor-pointer" />
|
||||
<FontAwesomeIcon icon={faXmark} className="h-4 w-4 cursor-pointer text-bunker-300" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col px-4 overflow-y-auto h-[calc(100vh-120px)] overflow-y-autp">
|
||||
<div className="overflow-y-autp flex h-[calc(100vh-120px)] flex-col overflow-y-auto px-4">
|
||||
{(actionMetaData?.name === 'readSecrets' ||
|
||||
actionMetaData?.name === 'addSecrets' ||
|
||||
actionMetaData?.name === 'deleteSecrets') &&
|
||||
actionData?.map((item, id) => (
|
||||
<div key={`secret.${id + 1}`}>
|
||||
<div className="text-xs text-bunker-200 mt-4 pl-1 ph-no-capture">
|
||||
<div className="ph-no-capture mt-4 pl-1 text-xs text-bunker-200">
|
||||
{item.newSecretVersion.key}
|
||||
</div>
|
||||
<div className='w-full font-mono text-sm break-all bg-mineshaft-600 px-2 py-0.5 rounded-md border border-mineshaft-500 text-bunker-200'>
|
||||
{item.newSecretVersion.value ? <span> {item.newSecretVersion.value} </span> : <span className='text-bunker-400'> EMPTY </span>}
|
||||
<div className="w-full break-all rounded-md border border-mineshaft-500 bg-mineshaft-600 px-2 py-0.5 font-mono text-sm text-bunker-200">
|
||||
{item.newSecretVersion.value ? (
|
||||
<span> {item.newSecretVersion.value} </span>
|
||||
) : (
|
||||
<span className="text-bunker-400"> EMPTY </span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{actionMetaData?.name === 'updateSecrets' &&
|
||||
actionData?.map((item, id) => (
|
||||
<>
|
||||
<div className="text-xs text-bunker-200 mt-4 pl-1">
|
||||
<div className="mt-4 pl-1 text-xs text-bunker-200">
|
||||
{item.newSecretVersion.key}
|
||||
</div>
|
||||
<div className="break-all text-bunker-200 font-mono rounded-md overflow-hidden border border-mineshaft-500">
|
||||
<div className="bg-red/40 px-2 ph-no-capture">
|
||||
<div className="overflow-hidden break-all rounded-md border border-mineshaft-500 font-mono text-bunker-200">
|
||||
<div className="ph-no-capture bg-red/40 px-2">
|
||||
-{' '}
|
||||
{patienceDiff(
|
||||
item.oldSecretVersion.value.split(''),
|
||||
@@ -188,14 +192,16 @@ const ActivitySideBar = ({ toggleSidebar, currentAction }: SideBarProps) => {
|
||||
character.bIndex !== -1 && (
|
||||
<span
|
||||
key={`actionData.${id + 1}.line.${lineId + 1}`}
|
||||
className={`${character.aIndex === -1 && 'text-bunker-100 bg-red-700/80'}`}
|
||||
className={`${
|
||||
character.aIndex === -1 && 'bg-red-700/80 text-bunker-100'
|
||||
}`}
|
||||
>
|
||||
{character.line}
|
||||
</span>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
<div className="break-all bg-green-500/40 px-2 ph-no-capture">
|
||||
<div className="ph-no-capture break-all bg-green-500/40 px-2">
|
||||
+{' '}
|
||||
{patienceDiff(
|
||||
item.oldSecretVersion.value.split(''),
|
||||
@@ -206,7 +212,9 @@ const ActivitySideBar = ({ toggleSidebar, currentAction }: SideBarProps) => {
|
||||
character.aIndex !== -1 && (
|
||||
<span
|
||||
key={`actionData.${id + 1}.linev2.${lineId + 1}`}
|
||||
className={`${character.bIndex === -1 && 'text-bunker-100 bg-green-700/80'}`}
|
||||
className={`${
|
||||
character.bIndex === -1 && 'bg-green-700/80 text-bunker-100'
|
||||
}`}
|
||||
>
|
||||
{character.line}
|
||||
</span>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Image from 'next/image';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { faAngleDown, faAngleRight, faUpRightFromSquare } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
@@ -51,43 +51,42 @@ const ActivityLogsRow = ({
|
||||
if (row?.user) return `User: ${row.user}`;
|
||||
if (row?.serviceAccount) return `Service Account: ${row.serviceAccount.name}`;
|
||||
if (row?.serviceTokenData.name) return `Service Token: ${row.serviceTokenData.name}`;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<tr key={guidGenerator()} className="bg-bunker-800 duration-100 w-full text-sm">
|
||||
<tr key={guidGenerator()} className="w-full bg-bunker-800 text-sm duration-100">
|
||||
<td
|
||||
onKeyDown={() => null}
|
||||
onClick={() => setPayloadOpened(!payloadOpened)}
|
||||
className="border-mineshaft-700 border-t text-gray-300 flex items-center cursor-pointer"
|
||||
className="flex cursor-pointer items-center border-t border-mineshaft-700 text-gray-300"
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={payloadOpened ? faAngleDown : faAngleRight}
|
||||
className={`mt-2.5 ml-6 text-bunker-100 hover:bg-mineshaft-700 ${
|
||||
payloadOpened && 'bg-mineshaft-500'
|
||||
} p-1 duration-100 h-4 w-4 rounded-md`}
|
||||
} h-4 w-4 rounded-md p-1 duration-100`}
|
||||
/>
|
||||
</td>
|
||||
<td className="py-3 border-mineshaft-700 border-t text-gray-300">
|
||||
<td className="border-t border-mineshaft-700 py-3 text-gray-300">
|
||||
{row.payload
|
||||
?.map(
|
||||
(action) =>
|
||||
`${String(action.secretVersions.length)} ${t(`activity:event.${action.name}`)}`
|
||||
`${String(action.secretVersions.length)} ${t(`activity.event.${action.name}`)}`
|
||||
)
|
||||
.join(' and ')}
|
||||
</td>
|
||||
<td className="pl-6 py-3 border-mineshaft-700 border-t text-gray-300">{renderUser()}</td>
|
||||
<td className="pl-6 py-3 border-mineshaft-700 border-t text-gray-300">{row.channel}</td>
|
||||
<td className="pl-6 py-3 border-mineshaft-700 border-t text-gray-300">
|
||||
<td className="border-t border-mineshaft-700 py-3 pl-6 text-gray-300">{renderUser()}</td>
|
||||
<td className="border-t border-mineshaft-700 py-3 pl-6 text-gray-300">{row.channel}</td>
|
||||
<td className="border-t border-mineshaft-700 py-3 pl-6 text-gray-300">
|
||||
{timeSince(new Date(row.createdAt))}
|
||||
</td>
|
||||
</tr>
|
||||
{payloadOpened && (
|
||||
<tr className="h-9 text-bunker-200 border-mineshaft-700 border-t text-sm">
|
||||
<tr className="h-9 border-t border-mineshaft-700 text-sm text-bunker-200">
|
||||
<td />
|
||||
<td>{String(t('common:timestamp'))}</td>
|
||||
<td>{String(t('common.timestamp'))}</td>
|
||||
<td>{row.createdAt}</td>
|
||||
</tr>
|
||||
)}
|
||||
@@ -97,29 +96,29 @@ const ActivityLogsRow = ({
|
||||
action.secretVersions.length > 0 && (
|
||||
<tr
|
||||
key={action._id}
|
||||
className="h-9 text-bunker-200 border-mineshaft-700 border-t text-sm"
|
||||
className="h-9 border-t border-mineshaft-700 text-sm text-bunker-200"
|
||||
>
|
||||
<td />
|
||||
<td className="">{t(`activity:event.${action.name}`)}</td>
|
||||
<td className="">{t(`activity.event.${action.name}`)}</td>
|
||||
<td
|
||||
onKeyDown={() => null}
|
||||
className="text-primary-300 cursor-pointer hover:text-primary duration-200"
|
||||
className="cursor-pointer text-primary-300 duration-200 hover:text-primary"
|
||||
onClick={() => toggleSidebar(action._id)}
|
||||
>
|
||||
{action.secretVersions.length +
|
||||
(action.secretVersions.length !== 1 ? ' secrets' : ' secret')}
|
||||
<FontAwesomeIcon
|
||||
icon={faUpRightFromSquare}
|
||||
className="ml-2 mb-0.5 font-light w-3 h-3"
|
||||
className="ml-2 mb-0.5 h-3 w-3 font-light"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
)}
|
||||
{payloadOpened && (
|
||||
<tr className="h-9 text-bunker-200 border-mineshaft-700 border-t text-sm">
|
||||
<tr className="h-9 border-t border-mineshaft-700 text-sm text-bunker-200">
|
||||
<td />
|
||||
<td>{String(t('activity:ip-address'))}</td>
|
||||
<td>{String(t('activity.ip-address'))}</td>
|
||||
<td>{row.ipAddress}</td>
|
||||
</tr>
|
||||
)}
|
||||
@@ -147,24 +146,24 @@ const ActivityTable = ({
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="w-full px-6 mt-8">
|
||||
<div className="table-container w-full bg-bunker rounded-md mb-6 border border-mineshaft-700 relative">
|
||||
<div className="absolute rounded-t-md w-full h-[3rem] bg-white/5" />
|
||||
<table className="w-full my-1">
|
||||
<div className="mt-8 w-full px-6">
|
||||
<div className="table-container relative mb-6 w-full rounded-md border border-mineshaft-700 bg-bunker">
|
||||
<div className="absolute h-[3rem] w-full rounded-t-md bg-white/5" />
|
||||
<table className="my-1 w-full">
|
||||
<thead className="text-bunker-300">
|
||||
<tr className="text-sm">
|
||||
<th aria-label="actions" className="text-left pl-6 pt-2.5 pb-3" />
|
||||
<th className="text-left font-semibold pt-2.5 pb-3">
|
||||
{String(t('common:event')).toUpperCase()}
|
||||
<th aria-label="actions" className="pl-6 pt-2.5 pb-3 text-left" />
|
||||
<th className="pt-2.5 pb-3 text-left font-semibold">
|
||||
{String(t('common.event')).toUpperCase()}
|
||||
</th>
|
||||
<th className="text-left font-semibold pl-6 pt-2.5 pb-3">
|
||||
{String(t('common:user')).toUpperCase()}
|
||||
<th className="pl-6 pt-2.5 pb-3 text-left font-semibold">
|
||||
{String(t('common.user')).toUpperCase()}
|
||||
</th>
|
||||
<th className="text-left font-semibold pl-6 pt-2.5 pb-3">
|
||||
{String(t('common:source')).toUpperCase()}
|
||||
<th className="pl-6 pt-2.5 pb-3 text-left font-semibold">
|
||||
{String(t('common.source')).toUpperCase()}
|
||||
</th>
|
||||
<th className="text-left font-semibold pl-6 pt-2.5 pb-3">
|
||||
{String(t('common:time')).toUpperCase()}
|
||||
<th className="pl-6 pt-2.5 pb-3 text-left font-semibold">
|
||||
{String(t('common.time')).toUpperCase()}
|
||||
</th>
|
||||
<th aria-label="action" />
|
||||
</tr>
|
||||
@@ -181,7 +180,7 @@ const ActivityTable = ({
|
||||
</table>
|
||||
</div>
|
||||
{isLoading && (
|
||||
<div className="w-full flex justify-center mb-8 mt-4">
|
||||
<div className="mb-8 mt-4 flex w-full justify-center">
|
||||
<Image
|
||||
src="/images/loading/loading.gif"
|
||||
height={60}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { faXmark } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { Tag } from 'public/data/frequentInterfaces';
|
||||
@@ -60,7 +59,6 @@ interface EncrypetedSecretVersionListProps {
|
||||
* @returns the sidebar with the options for point-in-time recovery (commits)
|
||||
*/
|
||||
const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }: SideBarProps) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [secretSnapshotsMetadata, setSecretSnapshotsMetadata] = useState<SnaphotProps[]>([]);
|
||||
@@ -102,10 +100,12 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
});
|
||||
}
|
||||
|
||||
const decryptedSecretVersions = secretSnapshotData.secretVersions.filter(
|
||||
(sv: EncrypetedSecretVersionListProps) => (sv.type !== undefined && sv.environment !== undefined)
|
||||
).map(
|
||||
(encryptedSecretVersion: EncrypetedSecretVersionListProps, pos: number) => ({
|
||||
const decryptedSecretVersions = secretSnapshotData.secretVersions
|
||||
.filter(
|
||||
(sv: EncrypetedSecretVersionListProps) =>
|
||||
sv.type !== undefined && sv.environment !== undefined
|
||||
)
|
||||
.map((encryptedSecretVersion: EncrypetedSecretVersionListProps, pos: number) => ({
|
||||
id: encryptedSecretVersion._id,
|
||||
pos,
|
||||
type: encryptedSecretVersion.type,
|
||||
@@ -123,53 +123,59 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
tag: encryptedSecretVersion.secretValueTag,
|
||||
key: decryptedLatestKey
|
||||
})
|
||||
})
|
||||
);
|
||||
}));
|
||||
|
||||
const secretKeys = [
|
||||
...new Set(decryptedSecretVersions.filter((dsv: any) => dsv.type !== undefined || dsv.environemnt !== undefined)
|
||||
.map((secret: SecretDataProps) => secret.key))
|
||||
...new Set(
|
||||
decryptedSecretVersions
|
||||
.filter((dsv: any) => dsv.type !== undefined || dsv.environemnt !== undefined)
|
||||
.map((secret: SecretDataProps) => secret.key)
|
||||
)
|
||||
];
|
||||
|
||||
const result = secretKeys.map((key, index) => (decryptedSecretVersions.filter(
|
||||
const result = secretKeys.map((key, index) =>
|
||||
decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0]?.id ? {
|
||||
id: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0].id,
|
||||
pos: index,
|
||||
key,
|
||||
environment: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0].environment,
|
||||
tags: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0].tags,
|
||||
value: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0]?.value,
|
||||
valueOverride: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0]?.value
|
||||
} : {
|
||||
id: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0].id,
|
||||
pos: index,
|
||||
key,
|
||||
environment: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0].environment,
|
||||
tags: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0].tags,
|
||||
value: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0]?.value,
|
||||
valueOverride: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0]?.value
|
||||
}));
|
||||
)[0]?.id
|
||||
? {
|
||||
id: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0].id,
|
||||
pos: index,
|
||||
key,
|
||||
environment: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0].environment,
|
||||
tags: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0].tags,
|
||||
value: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0]?.value,
|
||||
valueOverride: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0]?.value
|
||||
}
|
||||
: {
|
||||
id: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0].id,
|
||||
pos: index,
|
||||
key,
|
||||
environment: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0].environment,
|
||||
tags: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0].tags,
|
||||
value: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'shared'
|
||||
)[0]?.value,
|
||||
valueOverride: decryptedSecretVersions.filter(
|
||||
(secret: SecretDataProps) => secret.key === key && secret.type === 'personal'
|
||||
)[0]?.value
|
||||
}
|
||||
);
|
||||
|
||||
setSnapshotData({
|
||||
id: secretSnapshotData._id,
|
||||
@@ -182,12 +188,12 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`absolute border-l border-mineshaft-500 w-full min-w-sm max-w-sm ${
|
||||
className={`min-w-sm absolute w-full max-w-sm border-l border-mineshaft-500 ${
|
||||
isLoading ? 'bg-bunker-800' : 'bg-bunker'
|
||||
} fixed h-full right-0 z-[40] shadow-xl flex flex-col justify-between sticky top-0`}
|
||||
} fixed sticky right-0 top-0 z-[40] flex h-full flex-col justify-between shadow-xl`}
|
||||
>
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center h-full mb-8">
|
||||
<div className="mb-8 flex h-full items-center justify-center">
|
||||
<Image
|
||||
src="/images/loading/loading.gif"
|
||||
height={60}
|
||||
@@ -197,8 +203,8 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-min">
|
||||
<div className="flex flex-row px-4 py-3 border-b border-mineshaft-500 justify-between items-center">
|
||||
<p className="font-semibold text-lg text-bunker-200">{t('Point-in-time Recovery')}</p>
|
||||
<div className="flex flex-row items-center justify-between border-b border-mineshaft-500 px-4 py-3">
|
||||
<p className="text-lg font-semibold text-bunker-200">Point In Recovery</p>
|
||||
<div
|
||||
onKeyDown={() => null}
|
||||
role="button"
|
||||
@@ -206,11 +212,13 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
className="p-1"
|
||||
onClick={() => toggleSidebar(false)}
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} className="w-4 h-4 text-bunker-300 cursor-pointer" />
|
||||
<FontAwesomeIcon icon={faXmark} className="h-4 w-4 cursor-pointer text-bunker-300" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col w-96 px-2 py-2 overflow-y-auto bg-bunker border-l border-mineshaft-600 h-[calc(100vh-115px)]">
|
||||
<span className='px-2 text-bunker-200 pb-2 text-sm'>Note: This will recover secrets for all enviroments in this project.</span>
|
||||
<div className="flex h-[calc(100vh-115px)] w-96 flex-col overflow-y-auto border-l border-mineshaft-600 bg-bunker px-2 py-2">
|
||||
<span className="px-2 pb-2 text-sm text-bunker-200">
|
||||
Note: This will recover secrets for all enviroments in this project.
|
||||
</span>
|
||||
{secretSnapshotsMetadata?.map((snapshot: SnaphotProps, id: number) => (
|
||||
<div
|
||||
onKeyDown={() => null}
|
||||
@@ -220,9 +228,9 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
onClick={() => exploreSnapshot({ snapshotId: snapshot._id })}
|
||||
className={`${
|
||||
chosenSnapshot === snapshot._id || (id === 0 && chosenSnapshot === '')
|
||||
? 'bg-primary text-black pointer-events-none'
|
||||
: 'bg-mineshaft-700 hover:bg-mineshaft-500 duration-200 cursor-pointer'
|
||||
} py-3 px-4 mb-2 rounded-md flex flex-row justify-between items-center`}
|
||||
? 'pointer-events-none bg-primary text-black'
|
||||
: 'cursor-pointer bg-mineshaft-700 duration-200 hover:bg-mineshaft-500'
|
||||
} mb-2 flex flex-row items-center justify-between rounded-md py-3 px-4`}
|
||||
>
|
||||
<div className="flex flex-row items-start">
|
||||
<div
|
||||
@@ -230,7 +238,7 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
chosenSnapshot === snapshot._id || (id === 0 && chosenSnapshot === '')
|
||||
? 'text-bunker-800'
|
||||
: 'text-bunker-200'
|
||||
} text-sm mr-1.5`}
|
||||
} mr-1.5 text-sm`}
|
||||
>
|
||||
{timeSince(new Date(snapshot.createdAt))}
|
||||
</div>
|
||||
@@ -245,8 +253,8 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
<div
|
||||
className={`${
|
||||
chosenSnapshot === snapshot._id || (id === 0 && chosenSnapshot === '')
|
||||
? 'text-bunker-800 pointer-events-none'
|
||||
: 'text-bunker-200 hover:text-primary duration-200 cursor-pointer'
|
||||
? 'pointer-events-none text-bunker-800'
|
||||
: 'cursor-pointer text-bunker-200 duration-200 hover:text-primary'
|
||||
} text-sm`}
|
||||
>
|
||||
{id === 0
|
||||
@@ -257,8 +265,8 @@ const PITRecoverySidebar = ({ toggleSidebar, setSnapshotData, chosenSnapshot }:
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="flex justify-center w-full mb-14">
|
||||
<div className="items-center w-40">
|
||||
<div className="mb-14 flex w-full justify-center">
|
||||
<div className="w-40 items-center">
|
||||
<Button
|
||||
text="View More"
|
||||
textDisabled="End of History"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { faCircle, faDotCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
@@ -76,11 +76,11 @@ const SecretVersionList = ({ secretId }: { secretId: string }) => {
|
||||
}, [secretId]);
|
||||
|
||||
return (
|
||||
<div className="w-full min-w-40 h-[12.4rem] px-4 mt-4 text-sm text-bunker-300 overflow-x-none dark">
|
||||
<p className="">{t('dashboard:sidebar.version-history')}</p>
|
||||
<div className="pl-1 py-0.5 rounded-md bg-bunker-800 border border-mineshaft-500 overflow-x-none h-full">
|
||||
<div className="min-w-40 overflow-x-none dark mt-4 h-[12.4rem] w-full px-4 text-sm text-bunker-300">
|
||||
<p className="">{t('dashboard.sidebar.version-history')}</p>
|
||||
<div className="overflow-x-none h-full rounded-md border border-mineshaft-500 bg-bunker-800 py-0.5 pl-1">
|
||||
{isLoading ? (
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<Image
|
||||
src="/images/loading/loading.gif"
|
||||
height={60}
|
||||
@@ -89,19 +89,19 @@ const SecretVersionList = ({ secretId }: { secretId: string }) => {
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div className="h-48 overflow-y-auto overflow-x-none dark:[color-scheme:dark]">
|
||||
<div className="overflow-x-none h-48 overflow-y-auto dark:[color-scheme:dark]">
|
||||
{secretVersions ? (
|
||||
secretVersions
|
||||
?.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
|
||||
.map((version: DecryptedSecretVersionListProps, index: number) => (
|
||||
<div key={`${version.createdAt}.${index + 1}`} className="flex flex-row">
|
||||
<div className="pr-1 flex flex-col items-center">
|
||||
<div className="flex flex-col items-center pr-1">
|
||||
<div className="p-1">
|
||||
<FontAwesomeIcon icon={index === 0 ? faDotCircle : faCircle} />
|
||||
</div>
|
||||
<div className="w-0 h-full border-l border-bunker-300 mt-1" />
|
||||
<div className="mt-1 h-full w-0 border-l border-bunker-300" />
|
||||
</div>
|
||||
<div className="flex flex-col w-full max-w-[calc(100%-2.3rem)]">
|
||||
<div className="flex w-full max-w-[calc(100%-2.3rem)] flex-col">
|
||||
<div className="pr-2 text-bunker-300/90">
|
||||
{new Date(version.createdAt).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
@@ -113,18 +113,18 @@ const SecretVersionList = ({ secretId }: { secretId: string }) => {
|
||||
})}
|
||||
</div>
|
||||
<div className="">
|
||||
<p className="break-words ph-no-capture">
|
||||
<span className="py-0.5 px-1 rounded-sm bg-primary-500/30 mr-1.5">
|
||||
<p className="ph-no-capture break-words">
|
||||
<span className="mr-1.5 rounded-sm bg-primary-500/30 py-0.5 px-1">
|
||||
Value:
|
||||
</span>
|
||||
<span className='font-mono'>{version.value}</span>
|
||||
<span className="font-mono">{version.value}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-bunker-400">
|
||||
<div className="flex h-full w-full items-center justify-center text-bunker-400">
|
||||
No version history yet.
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user