mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-05-24 08:22:10 -04:00
fix: volumes dropdown
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Listbox as ListboxPrimitive, Transition } from '@headlessui/react';
|
||||
import { Listbox as ListboxPrimitive } from '@headlessui/react';
|
||||
import { CheckIcon, SelectorIcon } from '@heroicons/react/solid';
|
||||
import clsx from 'clsx';
|
||||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
interface ListboxOption {
|
||||
option: string;
|
||||
@@ -21,79 +21,72 @@ export default function Listbox(props: { options: ListboxOption[]; className?: s
|
||||
return (
|
||||
<>
|
||||
<ListboxPrimitive value={selected} onChange={setSelected}>
|
||||
<div className="relative w-full">
|
||||
<div className='relative w-full'>
|
||||
<ListboxPrimitive.Button
|
||||
className={clsx(
|
||||
`relative w-full py-2 pl-3 pr-10 text-left bg-white dark:bg-gray-500
|
||||
rounded-lg shadow-md cursor-default focus:outline-none focus-visible:ring-2
|
||||
focus-visible:ring-opacity-75 focus-visible:ring-white focus-visible:ring-offset-orange-300
|
||||
focus-visible:ring-offset-2 focus-visible:border-indigo-500 sm:text-sm`,
|
||||
rounded-lg shadow-md cursor-default focus:outline-none focus-visible:ring-2
|
||||
focus-visible:ring-opacity-75 focus-visible:ring-white focus-visible:ring-offset-orange-300
|
||||
focus-visible:ring-offset-2 focus-visible:border-indigo-500 sm:text-sm`,
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
{selected?.option ? (
|
||||
<span className="block truncate">{selected?.option}</span>
|
||||
<span className='block truncate'>{selected?.option}</span>
|
||||
) : (
|
||||
<span className="block truncate opacity-70">Nothing selected...</span>
|
||||
<span className='block truncate opacity-70'>Nothing selected...</span>
|
||||
)}
|
||||
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<SelectorIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
|
||||
|
||||
<span className='absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none'>
|
||||
<SelectorIcon className='w-5 h-5 text-gray-400' aria-hidden='true' />
|
||||
</span>
|
||||
</ListboxPrimitive.Button>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<ListboxPrimitive.Options
|
||||
className={`
|
||||
absolute w-full mt-1 overflow-auto rounded-md sm:text-sm
|
||||
text-base bg-white dark:bg-gray-500 shadow-lg max-h-60
|
||||
ring-1 ring-black ring-opacity-5 focus:outline-none
|
||||
`}
|
||||
>
|
||||
{props.options.map((person, personIdx) => (
|
||||
<ListboxPrimitive.Option
|
||||
key={personIdx}
|
||||
className={({ active }) =>
|
||||
`cursor-default select-none relative rounded m-1 py-2 pl-8 pr-4 dark:text-white focus:outline-none ${
|
||||
active
|
||||
? 'text-primary-900 bg-primary-600'
|
||||
: 'text-gray-900 dark:hover:bg-gray-600 dark:hover:bg-opacity-20'
|
||||
}`
|
||||
}
|
||||
value={person}
|
||||
>
|
||||
{({ selected }) => (
|
||||
<>
|
||||
<span
|
||||
className={`block truncate ${selected ? 'font-medium' : 'font-normal'}`}
|
||||
>
|
||||
{person.option}
|
||||
{person.description && (
|
||||
<span
|
||||
className={clsx(
|
||||
'text-gray-300 leading-5 ml-3 text-xs',
|
||||
selected && 'text-white'
|
||||
)}
|
||||
>
|
||||
{person.description}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
|
||||
{selected ? (
|
||||
<span className="absolute inset-y-0 left-0 flex items-center pl-2 text-white">
|
||||
<CheckIcon className="w-5 h-5" aria-hidden="true" />
|
||||
<ListboxPrimitive.Options
|
||||
className={`
|
||||
absolute w-full mt-1 overflow-auto rounded-md sm:text-sm
|
||||
text-base bg-white dark:bg-gray-500 shadow-lg max-h-60
|
||||
ring-1 ring-black ring-opacity-5 focus:outline-none
|
||||
`}
|
||||
>
|
||||
{props.options.map((option, index) => (
|
||||
<ListboxPrimitive.Option
|
||||
key={option.key}
|
||||
className={({ active }) =>
|
||||
`cursor-default select-none relative rounded m-1 py-2 pl-8 pr-4 dark:text-white focus:outline-none ${
|
||||
active
|
||||
? 'text-primary-900 bg-primary-600'
|
||||
: 'text-gray-900 dark:hover:bg-gray-600 dark:hover:bg-opacity-20'
|
||||
}`
|
||||
}
|
||||
value={option}
|
||||
>
|
||||
{({ selected }) => (
|
||||
<>
|
||||
<span className={`block truncate ${selected ? 'font-medium' : 'font-normal'}`}>
|
||||
{option.option}
|
||||
{option.description && (
|
||||
<span
|
||||
className={clsx(
|
||||
'text-gray-300 leading-5 ml-3 text-xs',
|
||||
selected && 'text-white'
|
||||
)}
|
||||
>
|
||||
{option.description}
|
||||
</span>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</ListboxPrimitive.Option>
|
||||
))}
|
||||
</ListboxPrimitive.Options>
|
||||
</Transition>
|
||||
)}
|
||||
</span>
|
||||
|
||||
{selected ? (
|
||||
<span className='absolute inset-y-0 left-0 flex items-center pl-2 text-white'>
|
||||
<CheckIcon className='w-5 h-5' aria-hidden='true' />
|
||||
</span>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
</ListboxPrimitive.Option>
|
||||
))}
|
||||
</ListboxPrimitive.Options>
|
||||
</div>
|
||||
</ListboxPrimitive>
|
||||
</>
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
import { useBridgeCommand, useBridgeQuery } from '@sd/client';
|
||||
import { Button } from '@sd/ui';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Input } from '../../components/primitive';
|
||||
import { useBridgeQuery } from '@sd/client';
|
||||
import React from 'react';
|
||||
import { InputContainer } from '../../components/primitive/InputContainer';
|
||||
import Listbox from '../../components/primitive/Listbox';
|
||||
import Slider from '../../components/primitive/Slider';
|
||||
|
||||
export default function GeneralSettings() {
|
||||
const { data: volumes } = useBridgeQuery('SysGetVolumes');
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-grow max-w-4xl space-y-4">
|
||||
<div className="mt-3 mb-3">
|
||||
<h1 className="text-2xl font-bold">General Settings</h1>
|
||||
<p className="mt-1 text-sm text-gray-400">Basic settings related to this client</p>
|
||||
<div className='flex flex-col flex-grow max-w-4xl space-y-4'>
|
||||
<div className='mt-3 mb-3'>
|
||||
<h1 className='text-2xl font-bold'>General Settings</h1>
|
||||
<p className='mt-1 text-sm text-gray-400'>Basic settings related to this client</p>
|
||||
{/* <hr className="mt-4 border-gray-550" /> */}
|
||||
</div>
|
||||
<p className="px-5 py-3 mb-3 text-sm text-gray-400 rounded-md bg-gray-50 dark:text-gray-400 dark:bg-gray-600">
|
||||
<p className='px-5 py-3 mb-3 text-sm text-gray-400 rounded-md bg-gray-50 dark:text-gray-400 dark:bg-gray-600'>
|
||||
<b>Note: </b>This is a pre-alpha build of Spacedrive, many features are yet to be
|
||||
functional.
|
||||
</p>
|
||||
@@ -47,16 +43,19 @@ export default function GeneralSettings() {
|
||||
</div>
|
||||
</InputContainer> */}
|
||||
|
||||
<InputContainer title="Volumes" description="A list of volumes running on this device.">
|
||||
<div className="flex flex-row space-x-2">
|
||||
<div className="flex flex-grow">
|
||||
<InputContainer title='Volumes' description='A list of volumes running on this device.'>
|
||||
<div className='flex flex-row space-x-2'>
|
||||
<div className='flex flex-grow'>
|
||||
<Listbox
|
||||
options={
|
||||
volumes?.map((volume) => ({
|
||||
key: volume.name,
|
||||
option: volume.name,
|
||||
description: volume.mount_point
|
||||
})) ?? []
|
||||
volumes?.map((volume) => {
|
||||
const name = volume.name && volume.name.length ? volume.name : volume.mount_point;
|
||||
return {
|
||||
key: name,
|
||||
option: name,
|
||||
description: volume.mount_point
|
||||
};
|
||||
}) ?? []
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user