From 6210eb234cb8ce418bd5c89e6135aab9addfba24 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 5 Dec 2024 23:51:53 +0100 Subject: [PATCH] feat: add UI to stop device sharing Closes https://github.com/hello-nrfcloud/map/discussions/351 --- src/base.css | 3 +- src/dashboard/Card.tsx | 18 ++--- src/dashboard/ShowDevice.css | 10 +++ src/dashboard/ShowDevice.tsx | 107 ++++++++++++++++++++++++++++- src/resources/stopDeviceSharing.ts | 19 +++++ 5 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 src/dashboard/ShowDevice.css create mode 100644 src/resources/stopDeviceSharing.ts diff --git a/src/base.css b/src/base.css index 61c0fd2e..e0bd5e95 100644 --- a/src/base.css +++ b/src/base.css @@ -319,12 +319,11 @@ input:-webkit-autofill:active { border-radius: calc(var(--border-radius) / 2); border-color: var(--color-form-border-default); background-color: var(--color-form-bg); - height: 32px; + min-height: 32px; padding: 0 var(--gap-medium); color: var(--color-form-text); font-weight: 300; display: inline-block; - height: 32px; font-family: var(--condensed-font-family); } diff --git a/src/dashboard/Card.tsx b/src/dashboard/Card.tsx index f769c646..f3ee73a1 100644 --- a/src/dashboard/Card.tsx +++ b/src/dashboard/Card.tsx @@ -2,16 +2,18 @@ import type { ParentProps } from 'solid-js' import './Card.css' -export const Card = (props: ParentProps) => ( -
{props.children}
+export const Card = (props: ParentProps<{ class?: string }>) => ( +
+ {props.children} +
) -export const CardHeader = (props: ParentProps) => ( -
{props.children}
+export const CardHeader = (props: ParentProps<{ class?: string }>) => ( +
{props.children}
) -export const CardBody = (props: ParentProps) => ( -
{props.children}
+export const CardBody = (props: ParentProps<{ class?: string }>) => ( +
{props.children}
) -export const CardFooter = (props: ParentProps) => ( - +export const CardFooter = (props: ParentProps<{ class?: string }>) => ( + ) diff --git a/src/dashboard/ShowDevice.css b/src/dashboard/ShowDevice.css new file mode 100644 index 00000000..2cf71570 --- /dev/null +++ b/src/dashboard/ShowDevice.css @@ -0,0 +1,10 @@ +.stop-sharing { + display: flex; + flex-direction: column; +} + +.stop-sharing .confirm { + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/src/dashboard/ShowDevice.tsx b/src/dashboard/ShowDevice.tsx index 47d26d4e..888c7b9c 100644 --- a/src/dashboard/ShowDevice.tsx +++ b/src/dashboard/ShowDevice.tsx @@ -6,6 +6,7 @@ import { useUser } from '#context/User.tsx' import { useViteEnv } from '#context/ViteEnv.tsx' import { extendDeviceSharing } from '#resources/extendDeviceSharing.ts' import { listUserDevices } from '#resources/listUserDevices.ts' +import { stopDeviceSharing } from '#resources/stopDeviceSharing.ts' import { type ModelID, models } from '@hello.nrfcloud.com/proto-map/models' import { createEffect, @@ -15,7 +16,7 @@ import { Show, Switch, } from 'solid-js' -import { Card, CardBody, CardHeader } from './Card.tsx' +import { Card, CardBody, CardFooter, CardHeader } from './Card.tsx' import { CopyableProp } from './CopyableProp.tsx' const f = new Intl.DateTimeFormat(undefined, { @@ -25,6 +26,10 @@ const f = new Intl.DateTimeFormat(undefined, { const formatAsDate = (d: Date) => f.format(d) +import { Success } from '#component/notifications/Success.tsx' +import { Checked, Unchecked } from '#icons/LucideIcon.tsx' +import './ShowDevice.css' + export const ShowDevice = () => { const { protoVersion } = useViteEnv() const deviceId = new URLSearchParams( @@ -98,7 +103,26 @@ export const ShowDevice = () => { > + + + + + + + + ) } @@ -157,3 +181,84 @@ const ExtendSharing = (props: { id: string; expires: Date }) => { ) } + +const StopSharing = (props: { id: string }) => { + const [stop, setStopped] = createSignal(false) + const [unlocked, setUnlocked] = createSignal(false) + const { jwt } = useUser() + const { apiURL } = useParameters() + const [stopRequest] = createResource(() => { + if (!stop()) return undefined + return { + id: props.id, + jwt: jwt()!, + } + }, stopDeviceSharing(apiURL)) + + createEffect(() => { + if (stopRequest.loading) return + if (stopRequest.state !== 'ready') return + setStopped(true) + }) + + return ( + <> +

+ You can stop the publication of this device at any time. If you stop the + publication, the device will no longer be visible on the map. You can + start the publication again at any time. It may take a few minutes for + the device to disappear from the map. +

+

+ + + stopping ... + + } + > + + + } + > + + +

+ + + + + + The publication of this device has been stopped. + + + + ) +} diff --git a/src/resources/stopDeviceSharing.ts b/src/resources/stopDeviceSharing.ts new file mode 100644 index 00000000..7477fa80 --- /dev/null +++ b/src/resources/stopDeviceSharing.ts @@ -0,0 +1,19 @@ +import { ProblemDetailError } from '#component/notifications/Problem.tsx' +import { typedFetch } from '@hello.nrfcloud.com/proto/hello' +import { Type } from '@sinclair/typebox' + +export const stopDeviceSharing = + (apiURL: URL) => + async ({ id, jwt }: { id: string; jwt: string }): Promise => { + const res = await typedFetch({ + responseBodySchema: Type.Undefined(), + })(new URL(`./user/device/${id}`, apiURL), undefined, { + method: 'DELETE', + headers: { Authorization: `Bearer ${jwt}` }, + }) + if ('error' in res) { + console.error(res.error) + throw new ProblemDetailError(res.error) + } + return res.result + }