mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-07 06:43:29 +00:00
parent
a73b6f325e
commit
7198775ea7
|
@ -9,27 +9,37 @@ use super::{locations::ExplorerItem, utils::library, Ctx, R};
|
|||
|
||||
pub(crate) fn mount() -> AlphaRouter<Ctx> {
|
||||
R.router()
|
||||
.procedure("changeNodeName", {
|
||||
.procedure("edit", {
|
||||
#[derive(Deserialize, Type)]
|
||||
pub struct ChangeNodeNameArgs {
|
||||
pub name: String,
|
||||
pub name: Option<String>,
|
||||
}
|
||||
// TODO: validate name isn't empty or too long
|
||||
|
||||
R.mutation(|ctx, args: ChangeNodeNameArgs| async move {
|
||||
ctx.config
|
||||
.write(|mut config| {
|
||||
config.name = args.name;
|
||||
})
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to write config: {}", err);
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
"error updating config".into(),
|
||||
)
|
||||
})
|
||||
.map(|_| ())
|
||||
if let Some(name) = args.name {
|
||||
if name.is_empty() || name.len() > 32 {
|
||||
return Err(rspc::Error::new(
|
||||
ErrorCode::BadRequest,
|
||||
"invalid node name".into(),
|
||||
));
|
||||
}
|
||||
|
||||
ctx.config
|
||||
.write(|mut config| {
|
||||
config.name = name;
|
||||
})
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to write config: {}", err);
|
||||
rspc::Error::new(
|
||||
ErrorCode::InternalServerError,
|
||||
"error updating config".into(),
|
||||
)
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
// TODO: add pagination!! and maybe ordering etc
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Laptop, Node } from '@sd/assets/icons';
|
||||
import { Database } from 'phosphor-react';
|
||||
import { getDebugState, useBridgeQuery, useDebugState } from '@sd/client';
|
||||
import { Button, Card, Input, Label, Switch, tw } from '@sd/ui';
|
||||
import { Node } from '@sd/assets/icons';
|
||||
import { getDebugState, useBridgeMutation, useBridgeQuery, useDebugState } from '@sd/client';
|
||||
import { Card, Input, Switch, tw } from '@sd/ui';
|
||||
import { useZodForm, z } from '@sd/ui/src/forms';
|
||||
import { useDebouncedFormWatch } from '~/hooks';
|
||||
import { usePlatform } from '~/util/Platform';
|
||||
import { Heading } from '../Layout';
|
||||
import Setting from '../Setting';
|
||||
|
@ -13,6 +14,24 @@ export const Component = () => {
|
|||
const node = useBridgeQuery(['nodeState']);
|
||||
const platform = usePlatform();
|
||||
const debugState = useDebugState();
|
||||
const editNode = useBridgeMutation('nodes.edit');
|
||||
|
||||
const form = useZodForm({
|
||||
schema: z.object({
|
||||
name: z.string().min(1)
|
||||
}),
|
||||
defaultValues: {
|
||||
name: node.data?.name || ''
|
||||
}
|
||||
});
|
||||
|
||||
useDebouncedFormWatch(form, async (value) => {
|
||||
await editNode.mutateAsync({
|
||||
name: value.name || null
|
||||
});
|
||||
|
||||
node.refetch();
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -37,22 +56,20 @@ export const Component = () => {
|
|||
<div className="flex flex-col">
|
||||
<NodeSettingLabel>Node Name</NodeSettingLabel>
|
||||
<Input
|
||||
value={node.data?.name}
|
||||
onChange={() => {
|
||||
/* TODO */
|
||||
}}
|
||||
{...form.register('name', { required: true })}
|
||||
defaultValue={node.data?.name}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
{/* <div className="flex flex-col">
|
||||
<NodeSettingLabel>Node Port</NodeSettingLabel>
|
||||
<Input
|
||||
contentEditable={false}
|
||||
value={node.data?.p2p_port || 5795}
|
||||
onChange={() => {
|
||||
/* TODO */
|
||||
alert('TODO');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
<div className="mt-6 gap-2">
|
||||
|
@ -74,9 +91,9 @@ export const Component = () => {
|
|||
<NodeSettingLabel>Data Folder</NodeSettingLabel>
|
||||
<div className="mt-2 flex w-full flex-row gap-2">
|
||||
<Input className="grow" value={node.data?.data_path} />
|
||||
<Button size="sm" variant="outline">
|
||||
{/* <Button size="sm" variant="outline">
|
||||
Change
|
||||
</Button>
|
||||
</Button> */}
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className='mb-1'>
|
||||
|
@ -86,12 +103,12 @@ export const Component = () => {
|
|||
<Input value={node.data?.data_path + '/logs'} />
|
||||
</div> */}
|
||||
</div>
|
||||
<div className="pointer-events-none mt-5 flex items-center space-x-3 opacity-50">
|
||||
{/* <div className="pointer-events-none mt-5 flex items-center space-x-3 opacity-50">
|
||||
<Switch size="sm" />
|
||||
<span className="text-sm font-medium text-ink-dull">
|
||||
Run Spacedrive in the background when app closed
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</Card>
|
||||
{isDev && (
|
||||
|
|
|
@ -56,7 +56,7 @@ export type Procedures = {
|
|||
{ key: "locations.indexer_rules.delete", input: LibraryArgs<number>, result: null } |
|
||||
{ key: "locations.relink", input: LibraryArgs<string>, result: null } |
|
||||
{ key: "locations.update", input: LibraryArgs<LocationUpdateArgs>, result: null } |
|
||||
{ key: "nodes.changeNodeName", input: ChangeNodeNameArgs, result: null } |
|
||||
{ key: "nodes.edit", input: ChangeNodeNameArgs, result: null } |
|
||||
{ key: "p2p.acceptSpacedrop", input: [string, string | null], result: null } |
|
||||
{ key: "p2p.pair", input: LibraryArgs<PeerId>, result: number } |
|
||||
{ key: "p2p.spacedrop", input: SpacedropArgs, result: string | null } |
|
||||
|
@ -86,7 +86,7 @@ export type CRDTOperationType = SharedOperation | RelationOperation
|
|||
*/
|
||||
export type Category = "Recents" | "Favorites" | "Photos" | "Videos" | "Movies" | "Music" | "Documents" | "Downloads" | "Encrypted" | "Projects" | "Applications" | "Archives" | "Databases" | "Games" | "Books" | "Contacts" | "Trash"
|
||||
|
||||
export type ChangeNodeNameArgs = { name: string }
|
||||
export type ChangeNodeNameArgs = { name: string | null }
|
||||
|
||||
export type CreateLibraryArgs = { name: string }
|
||||
|
||||
|
|
Loading…
Reference in a new issue