✨ Improved dashboard of drive
This commit is contained in:
		
							
								
								
									
										198
									
								
								DysonNetwork.Drive/Client/src/components/FilePoolSelect.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								DysonNetwork.Drive/Client/src/components/FilePoolSelect.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,198 @@ | ||||
| <template> | ||||
|   <n-select | ||||
|     :value="modelValue" | ||||
|     @update:value="onUpdate" | ||||
|     :options="pools ?? []" | ||||
|     :render-label="renderPoolSelectLabel" | ||||
|     :render-tag="renderSingleSelectTag" | ||||
|     value-field="id" | ||||
|     label-field="name" | ||||
|     :placeholder="props.placeholder || 'Select a file pool to upload'" | ||||
|     clearable | ||||
|     size="large" | ||||
|   /> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { | ||||
|   NSelect, | ||||
|   NTag, | ||||
|   NDivider, | ||||
|   NTooltip, | ||||
|   type SelectOption, | ||||
|   type SelectRenderTag, | ||||
| } from 'naive-ui' | ||||
| import { h, onMounted, ref, watch } from 'vue' | ||||
| import type { SnFilePool } from '@/types/pool' | ||||
| import { formatBytes } from '@/views/format' | ||||
|  | ||||
| const props = defineProps<{ | ||||
|   modelValue: string | null | ||||
|   placeholder: string | undefined | ||||
| }>() | ||||
|  | ||||
| const emit = defineEmits(['update:modelValue', 'update:pool']) | ||||
|  | ||||
| type SnFilePoolOption = SnFilePool & any | ||||
|  | ||||
| const pools = ref<SnFilePoolOption[] | undefined>() | ||||
| async function fetchPools() { | ||||
|   const resp = await fetch('/api/pools') | ||||
|   pools.value = await resp.json() | ||||
| } | ||||
| onMounted(() => fetchPools()) | ||||
|  | ||||
| function onUpdate(value: string | null) { | ||||
|   emit('update:modelValue', value) | ||||
|   if (value === null) { | ||||
|     emit('update:pool', null) | ||||
|     return | ||||
|   } | ||||
|   if (pools.value) { | ||||
|     const pool = pools.value.find((p) => p.id === value) ?? null | ||||
|     emit('update:pool', pool) | ||||
|   } | ||||
| } | ||||
|  | ||||
| watch(pools, (newPools) => { | ||||
|   if (props.modelValue && newPools) { | ||||
|     const pool = newPools.find((p) => p.id === props.modelValue) ?? null | ||||
|     emit('update:pool', pool) | ||||
|   } | ||||
| }) | ||||
|  | ||||
| const renderSingleSelectTag: SelectRenderTag = ({ option }) => { | ||||
|   return h( | ||||
|     'div', | ||||
|     { | ||||
|       style: { | ||||
|         display: 'flex', | ||||
|         alignItems: 'center', | ||||
|       }, | ||||
|     }, | ||||
|     [option.name as string], | ||||
|   ) | ||||
| } | ||||
|  | ||||
| const perkPrivilegeList = ['Stellar', 'Nova', 'Supernova'] | ||||
|  | ||||
| function renderPoolSelectLabel(option: SelectOption & SnFilePool) { | ||||
|   const policy: any = option.policy_config | ||||
|   return h( | ||||
|     'div', | ||||
|     { | ||||
|       style: { | ||||
|         padding: '8px 2px', | ||||
|       }, | ||||
|     }, | ||||
|     [ | ||||
|       h('div', null, [option.name as string]), | ||||
|       option.description && | ||||
|         h( | ||||
|           'div', | ||||
|           { | ||||
|             style: { | ||||
|               fontSize: '0.875rem', | ||||
|               opacity: '0.75', | ||||
|             }, | ||||
|           }, | ||||
|           option.description, | ||||
|         ), | ||||
|       h( | ||||
|         'div', | ||||
|         { | ||||
|           style: { | ||||
|             display: 'flex', | ||||
|             marginBottom: '4px', | ||||
|             fontSize: '0.75rem', | ||||
|             opacity: '0.75', | ||||
|           }, | ||||
|         }, | ||||
|         [ | ||||
|           policy.max_file_size && h('span', `Max ${formatBytes(policy.max_file_size)}`), | ||||
|           policy.accept_types && | ||||
|             h( | ||||
|               NTooltip, | ||||
|               {}, | ||||
|               { | ||||
|                 trigger: () => h('span', `Accept limited types`), | ||||
|                 default: () => h('span', policy.accept_types.join(', ')), | ||||
|               }, | ||||
|             ), | ||||
|           policy.require_privilege && | ||||
|             h('span', `Require ${perkPrivilegeList[policy.require_privilege - 1]} Program`), | ||||
|           h('span', `Cost x${option.billing_config.cost_multiplier.toFixed(1)} NSD`), | ||||
|         ] | ||||
|           .filter((el) => el) | ||||
|           .flatMap((el, idx, arr) => | ||||
|             idx < arr.length - 1 ? [el, h(NDivider, { vertical: true })] : [el], | ||||
|           ), | ||||
|       ), | ||||
|       h( | ||||
|         'div', | ||||
|         { | ||||
|           style: { | ||||
|             display: 'flex', | ||||
|             gap: '0.25rem', | ||||
|             marginTop: '2px', | ||||
|             marginLeft: '-2px', | ||||
|             marginRight: '-2px', | ||||
|           }, | ||||
|         }, | ||||
|         [ | ||||
|           policy.public_usable && | ||||
|             h( | ||||
|               NTag, | ||||
|               { | ||||
|                 type: 'info', | ||||
|                 size: 'small', | ||||
|                 round: true, | ||||
|               }, | ||||
|               { default: () => 'Public Shared' }, | ||||
|             ), | ||||
|           policy.public_indexable && | ||||
|             h( | ||||
|               NTag, | ||||
|               { | ||||
|                 type: 'success', | ||||
|                 size: 'small', | ||||
|                 round: true, | ||||
|               }, | ||||
|               { default: () => 'Public Indexable' }, | ||||
|             ), | ||||
|           policy.allow_encryption && | ||||
|             h( | ||||
|               NTag, | ||||
|               { | ||||
|                 type: 'warning', | ||||
|                 size: 'small', | ||||
|                 round: true, | ||||
|               }, | ||||
|               { default: () => 'Allow Encryption' }, | ||||
|             ), | ||||
|           policy.allow_anonymous && | ||||
|             h( | ||||
|               NTag, | ||||
|               { | ||||
|                 type: 'info', | ||||
|                 size: 'small', | ||||
|                 round: true, | ||||
|               }, | ||||
|               { default: () => 'Allow Anonymous' }, | ||||
|             ), | ||||
|           policy.enable_recycle && | ||||
|             h( | ||||
|               NTag, | ||||
|               { | ||||
|                 type: 'info', | ||||
|                 size: 'small', | ||||
|                 round: true, | ||||
|               }, | ||||
|               { default: () => 'Recycle Enabled' }, | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|     ], | ||||
|   ) | ||||
| } | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user