From 82d7fa1c5393afcc9a1937f7273183e1d7098ddd Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Thu, 9 Jul 2020 21:00:03 -0700 Subject: [PATCH] Support setting notes on allocations; closes #561 --- resources/scripts/api/getServers.ts | 2 +- .../scripts/components/elements/Input.tsx | 7 ++-- .../server/network/NetworkContainer.tsx | 41 +++++++++++++++---- 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/resources/scripts/api/getServers.ts b/resources/scripts/api/getServers.ts index 1be6fe9ff..8dd8ed22a 100644 --- a/resources/scripts/api/getServers.ts +++ b/resources/scripts/api/getServers.ts @@ -11,7 +11,7 @@ export default (query?: string, includeAdmin?: boolean): Promise resolve({ - items: (data.data || []).map((datum: any) => rawDataToServerObject(datum.attributes)), + items: (data.data || []).map((datum: any) => rawDataToServerObject(datum)), pagination: getPaginationSet(data.meta.pagination), })) .catch(reject); diff --git a/resources/scripts/components/elements/Input.tsx b/resources/scripts/components/elements/Input.tsx index c548aad3e..e29eaf6e9 100644 --- a/resources/scripts/components/elements/Input.tsx +++ b/resources/scripts/components/elements/Input.tsx @@ -36,7 +36,8 @@ const checkboxStyle = css` const inputStyle = css` // Reset to normal styling. - ${tw`appearance-none w-full min-w-0`}; + resize: none; + ${tw`appearance-none outline-none w-full min-w-0`}; ${tw`p-3 border rounded text-sm transition-all duration-150`}; ${tw`bg-neutral-600 border-neutral-500 hover:border-neutral-400 text-neutral-200 shadow-none`}; @@ -49,8 +50,8 @@ const inputStyle = css` ${tw`shadow-none`}; } - &:focus { - ${tw`shadow-md border-neutral-400`}; + &:not(:disabled):not(:read-only):focus { + ${tw`shadow-md border-primary-400`}; } &:disabled { diff --git a/resources/scripts/components/server/network/NetworkContainer.tsx b/resources/scripts/components/server/network/NetworkContainer.tsx index dcf92ef88..75ff4d418 100644 --- a/resources/scripts/components/server/network/NetworkContainer.tsx +++ b/resources/scripts/components/server/network/NetworkContainer.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import tw from 'twin.macro'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faNetworkWired } from '@fortawesome/free-solid-svg-icons'; @@ -14,14 +14,19 @@ import { Allocation } from '@/api/server/getServer'; import Spinner from '@/components/elements/Spinner'; import setPrimaryServerAllocation from '@/api/server/network/setPrimaryServerAllocation'; import useFlash from '@/plugins/useFlash'; +import { Textarea } from '@/components/elements/Input'; +import setServerAllocationNotes from '@/api/server/network/setServerAllocationNotes'; +import { debounce } from 'debounce'; +import InputSpinner from '@/components/elements/InputSpinner'; const Code = styled.code`${tw`font-mono py-1 px-2 bg-neutral-900 rounded text-sm block`}`; const Label = styled.label`${tw`uppercase text-xs mt-1 text-neutral-400 block px-1 select-none transition-colors duration-150`}`; const NetworkContainer = () => { - const server = useServer(); + const { uuid, allocations } = useServer(); const { clearFlashes, clearAndAddHttpError } = useFlash(); - const { data, error, mutate } = useSWR(server.uuid, key => getServerAllocations(key), { initialData: server.allocations }); + const [ loading, setLoading ] = useState(false); + const { data, error, mutate } = useSWR(uuid, key => getServerAllocations(key), { initialData: allocations }); const setPrimaryAllocation = (id: number) => { clearFlashes('server:network'); @@ -29,13 +34,25 @@ const NetworkContainer = () => { const initial = data; mutate(data?.map(a => a.id === id ? { ...a, isDefault: true } : { ...a, isDefault: false }), false); - setPrimaryServerAllocation(server.uuid, id) + setPrimaryServerAllocation(uuid, id) .catch(error => { clearAndAddHttpError({ key: 'server:network', error }); mutate(initial, false); }); }; + const setAllocationNotes = debounce((id: number, notes: string) => { + setLoading(id); + clearFlashes('server:network'); + + setServerAllocationNotes(uuid, id, notes) + .then(() => mutate(data?.map(a => a.id === id ? { ...a, notes } : a), false)) + .catch(error => { + clearAndAddHttpError({ key: 'server:network', error }); + }) + .then(() => setLoading(false)); + }, 750); + useEffect(() => { if (error) { clearAndAddHttpError({ key: 'server:network', error }); @@ -47,8 +64,8 @@ const NetworkContainer = () => { {!data ? : - data.map(({ id, ip, port, alias, isDefault }, index) => ( - 0 ? tw`mt-2` : undefined}> + data.map(({ id, ip, port, alias, notes, isDefault }, index) => ( + 0 ? tw`mt-2` : undefined} $hoverable={false}>
@@ -60,7 +77,17 @@ const NetworkContainer = () => { :{port} -
+
+ +