import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; import { Box, Button, Card, Divider, Grid, GridCol, Group, Popover, Select, Stack, Text, TextInput, } from '@mantine/core'; import { useDebouncedValue, useDisclosure } from '@mantine/hooks'; import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks'; import { useEffect, useState } from 'react'; import * as fa6 from 'react-icons/fa6'; import * as si from 'react-icons/si'; import * as vsc from 'react-icons/vsc'; import { selectClasses, textInputClasses } from 'styles'; import type { Application } from 'types'; import AddItemModal from '../Shared/AddItemModal'; import SettingsHeader from '../Shared/SettingsHeader'; import AppSettingsItem from './AppSettingsItem'; import DebouncedApplication from './DebouncedApplication'; const ApplicationSettings = () => { const allIcons: any = { ...fa6, ...vsc, ...si }; const defaultApplication: Application = { id: null, name: '', url: '', icon: '', baseUrl: '', filterName: '', index: 0, enabled: 1, }; const appsEndpoint = 'api/apps'; const appsOrderEndpoint = 'api/appsOrder'; const { data: apps, isFetching: isAppsFetching } = useQueryAPI({ endpoint: appsEndpoint, }); const [applicationData, setApplicationData] = useState([]); const [applicationList, setApplicationList] = useState([]); const { theme, isMobile } = useCommonHooks(); const [newApplication, setNewApplication] = useState(defaultApplication); const { mutateAsync } = useMutationAPI(); const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [dragging, setDragging] = useState(false); const [isOpen, setIsOpen] = useState(false); const reorder = (list: any, startIndex: any, endIndex: any) => { const result = Array.from(list); const [removed]: any = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); return result; }; function onDragEnd(result: any) { if (!result.destination) { return; } if (result.destination.index === result.source.index) { return; } const items = reorder(applicationData, result.source.index, result.destination.index); setApplicationList( items.map((item: any, index: number) => { return { ...item, index: index, }; }), ); } const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); const handleClose = () => { closeModal(); setNewApplication(defaultApplication); }; useEffect(() => { if (apps && !isAppsFetching) { setApplicationData( apps .filter((a: Application) => a.name.toLowerCase().includes(debouncedSearch.toLowerCase()), ) .sort((a: Application, b: Application) => (a.index > b.index ? 1 : -1)), ); } }, [apps, isAppsFetching, debouncedSearch]); useEffect(() => { if (applicationList.length > 0 && applicationList !== applicationData) { mutateAsync({ method: 'PATCH', endpoint: appsOrderEndpoint, body: applicationList, }); } }, [applicationList]); return ( { setNewApplication({ ...newApplication, name: event.target.value, }); }} /> { setNewApplication({ ...newApplication, baseUrl: event.target.value, }); }} /> { setNewApplication({ ...newApplication, url: event.target.value, }); }} />