mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 19:26:19 +00:00
Merge pull request #1783 from akhilmhdh:feat/dashboard-slug-fix
feat: debounced main page search and rolled back to old input component
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
export const debounce = <F extends (...args: any[]) => any>(
|
||||||
|
func: F,
|
||||||
|
delay: number
|
||||||
|
): ((...args: Parameters<F>) => void) => {
|
||||||
|
let timeoutId: ReturnType<typeof setTimeout> | null;
|
||||||
|
return function debounced(...args: Parameters<F>) {
|
||||||
|
if (timeoutId) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
timeoutId = setTimeout(() => {
|
||||||
|
func(...args);
|
||||||
|
timeoutId = null;
|
||||||
|
}, delay);
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
|
||||||
import Head from "next/head";
|
|
||||||
|
|
||||||
import { SecretMainPage } from "@app/views/SecretMainPage";
|
|
||||||
|
|
||||||
const Dashboard = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Head>
|
|
||||||
<title>{t("common.head-title", { title: t("dashboard.title") })}</title>
|
|
||||||
<link rel="icon" href="/infisical.ico" />
|
|
||||||
<meta property="og:image" content="/images/message.png" />
|
|
||||||
<meta property="og:title" content={String(t("dashboard.og-title"))} />
|
|
||||||
<meta name="og:description" content={String(t("dashboard.og-description"))} />
|
|
||||||
</Head>
|
|
||||||
<div className="h-full">
|
|
||||||
<SecretMainPage />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Dashboard;
|
|
||||||
|
|
||||||
Dashboard.requireAuth = true;
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useState } from "react";
|
||||||
import { subject } from "@casl/ability";
|
import { subject } from "@casl/ability";
|
||||||
import {
|
import {
|
||||||
faAngleDown,
|
faAngleDown,
|
||||||
@@ -45,6 +46,7 @@ import { ProjectPermissionActions, ProjectPermissionSub, useSubscription } from
|
|||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useCreateFolder, useDeleteSecretBatch } from "@app/hooks/api";
|
import { useCreateFolder, useDeleteSecretBatch } from "@app/hooks/api";
|
||||||
import { DecryptedSecret, TImportedSecrets, WsTag } from "@app/hooks/api/types";
|
import { DecryptedSecret, TImportedSecrets, WsTag } from "@app/hooks/api/types";
|
||||||
|
import { debounce } from "@app/lib/fn/debounce";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PopUpNames,
|
PopUpNames,
|
||||||
@@ -106,6 +108,7 @@ export const ActionBar = ({
|
|||||||
] as const);
|
] as const);
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
const { openPopUp } = usePopUpAction();
|
const { openPopUp } = usePopUpAction();
|
||||||
|
const [search, setSearch] = useState(filter.searchFilter);
|
||||||
|
|
||||||
const { mutateAsync: createFolder } = useCreateFolder();
|
const { mutateAsync: createFolder } = useCreateFolder();
|
||||||
const { mutateAsync: deleteBatchSecretV3 } = useDeleteSecretBatch();
|
const { mutateAsync: deleteBatchSecretV3 } = useDeleteSecretBatch();
|
||||||
@@ -114,6 +117,8 @@ export const ActionBar = ({
|
|||||||
const { reset: resetSelectedSecret } = useSelectedSecretActions();
|
const { reset: resetSelectedSecret } = useSelectedSecretActions();
|
||||||
const isMultiSelectActive = Boolean(Object.keys(selectedSecrets).length);
|
const isMultiSelectActive = Boolean(Object.keys(selectedSecrets).length);
|
||||||
|
|
||||||
|
const debouncedOnSearch = debounce(onSearchChange, 500);
|
||||||
|
|
||||||
const handleFolderCreate = async (folderName: string) => {
|
const handleFolderCreate = async (folderName: string) => {
|
||||||
try {
|
try {
|
||||||
await createFolder({
|
await createFolder({
|
||||||
@@ -199,8 +204,11 @@ export const ActionBar = ({
|
|||||||
className="bg-mineshaft-800 placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
className="bg-mineshaft-800 placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
||||||
placeholder="Search by folder name, key name, comment..."
|
placeholder="Search by folder name, key name, comment..."
|
||||||
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
leftIcon={<FontAwesomeIcon icon={faMagnifyingGlass} />}
|
||||||
value={filter.searchFilter}
|
value={search}
|
||||||
onChange={(evt) => onSearchChange(evt.target.value)}
|
onChange={(evt) => {
|
||||||
|
setSearch(evt.target.value);
|
||||||
|
debouncedOnSearch(evt.target.value);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
Popover,
|
Popover,
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
|
SecretInput,
|
||||||
Spinner,
|
Spinner,
|
||||||
TextArea,
|
TextArea,
|
||||||
Tooltip
|
Tooltip
|
||||||
@@ -48,7 +49,6 @@ import { memo, useEffect } from "react";
|
|||||||
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
|
|
||||||
import { InfisicalSecretInput } from "@app/components/v2/InfisicalSecretInput";
|
|
||||||
import { CreateReminderForm } from "./CreateReminderForm";
|
import { CreateReminderForm } from "./CreateReminderForm";
|
||||||
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
||||||
|
|
||||||
@@ -263,12 +263,10 @@ export const SecretItem = memo(
|
|||||||
key="value-overriden"
|
key="value-overriden"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<InfisicalSecretInput
|
<SecretInput
|
||||||
key="value-overriden"
|
key="value-overriden"
|
||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
environment={environment}
|
|
||||||
secretPath={secretPath}
|
|
||||||
{...field}
|
{...field}
|
||||||
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
||||||
/>
|
/>
|
||||||
@@ -280,12 +278,10 @@ export const SecretItem = memo(
|
|||||||
key="secret-value"
|
key="secret-value"
|
||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<InfisicalSecretInput
|
<SecretInput
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
key="secret-value"
|
key="secret-value"
|
||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
environment={environment}
|
|
||||||
secretPath={secretPath}
|
|
||||||
{...field}
|
{...field}
|
||||||
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
containerClassName="py-1.5 rounded-md transition-all group-hover:mr-2"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user