Skip to content

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
kunish committed Apr 25, 2024
1 parent d14fa63 commit 41137d8
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 174 deletions.
138 changes: 138 additions & 0 deletions components/ConfigFormModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<script setup lang="ts">
import type { ResultOf } from 'gql.tada'
import { z } from 'zod'
import type * as queries from '~/queries'
const props = defineProps<{
config?: ResultOf<typeof queries.configs>['configs'][number]
}>()
const visible = defineModel('visible', {
type: Boolean,
default: false
})
const { handleSubmit } = useForm({
validationSchema: toTypedSchema(
z.object({
name: z.string().min(1),
tproxyPort: z.number()
})
),
initialValues: {
name: props.config?.name || '',
tproxyPort: props.config?.global.tproxyPort || 0
}
})
const onSubmit = handleSubmit(async () => {})
</script>

<template>
<Dialog
v-model:visible="visible"
modal
:draggable="false"
header="Create Config"
>
<div>
<Field #="{ componentField }" name="name">
<FormItem class="w-full">
<FormLabel>Name</FormLabel>

<FormControl>
<InputText class="w-full" v-bind="componentField" />
</FormControl>

<FormDescription>The name of the configuration.</FormDescription>

<FormMessage />
</FormItem>
</Field>

<Accordion class="py-4" multiple>
<AccordionTab header="Software Options">
<Field
#="{ componentField: { onInput, ...componentField } }"
name="tproxyPort"
>
<FormItem class="w-full">
<FormLabel>tproxyPort</FormLabel>

<FormControl>
<InputNumber
class="w-full"
v-bind="componentField"
:format="false"
@input="({ value }) => onInput(value)"
/>
</FormControl>

<FormDescription>
Transparent Proxy Port to listen on. Valid range is 0 - 65535.
It is NOT a HTTP/SOCKS port, and is just used by eBPF program.
In normal case, you do not need to use it.
</FormDescription>

<FormMessage />
</FormItem>
</Field>
</AccordionTab>

<AccordionTab header="Interface and Kernel Options">
<Field #="{ componentField }" name="name">
<FormItem class="w-full">
<FormLabel>Name</FormLabel>

<FormControl>
<InputText class="w-full" v-bind="componentField" />
</FormControl>

<FormDescription>The name of the configuration.</FormDescription>

<FormMessage />
</FormItem>
</Field>
</AccordionTab>

<AccordionTab header="Node Connectivity Check">
<Field #="{ componentField }" name="name">
<FormItem class="w-full">
<FormLabel>Name</FormLabel>

<FormControl>
<InputText class="w-full" v-bind="componentField" />
</FormControl>

<FormDescription>The name of the configuration.</FormDescription>

<FormMessage />
</FormItem>
</Field>
</AccordionTab>

<AccordionTab header="Connecting Options">
<Field #="{ componentField }" name="name">
<FormItem class="w-full">
<FormLabel>Name</FormLabel>

<FormControl>
<InputText class="w-full" v-bind="componentField" />
</FormControl>

<FormDescription>The name of the configuration.</FormDescription>

<FormMessage />
</FormItem>
</Field>
</AccordionTab>
</Accordion>
</div>

<template #footer>
<Button text>Reset</Button>

<Button @click="onSubmit">Save</Button>
</template>
</Dialog>
</template>
129 changes: 10 additions & 119 deletions components/ResourceConfig.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
<script setup lang="ts">
import type { ConfigFormModal } from '#components'
import * as mutations from '~/mutations'
<script setup lang="tsx">
import * as queries from '~/queries'
const apiStore = useAPIStore()
const { data: defaults } = useAsyncData(() => apiStore.getDefaults())
const isCreateConfigModalOpen = ref(false)
const createConfigFormModalRef = ref<InstanceType<typeof ConfigFormModal>>()
const isUpdateConfigFormModalOpen = ref(false)
const updateConfigFormModalRef = ref<InstanceType<typeof ConfigFormModal>>()
const { data: configs, execute: reloadConfigs } = useAsyncData(
'configs',
Expand All @@ -19,126 +13,23 @@ const { data: configs, execute: reloadConfigs } = useAsyncData(
return data?.data?.configs
}
)
const isRemovingConfig = ref(false)
const removeConfig = async (id: string) => {
isRemovingConfig.value = true
try {
await apiStore.apiClient?.mutation(mutations.removeConfig, { id })
await reloadConfigs()
} finally {
isRemovingConfig.value = false
}
}
const isSelectingConfig = ref(false)
const selectConfig = async (id: string) => {
isSelectingConfig.value = true
try {
await apiStore.apiClient?.mutation(mutations.selectConfig, { id })
await reloadConfigs()
} finally {
isSelectingConfig.value = false
}
}
</script>

<template>
<div class="space-y-2">
<div class="flex justify-end">
<Button size="icon" @click="isCreateConfigModalOpen = true">
<Icon name="i-heroicons:plus" />
<Button @click="isCreateConfigModalOpen = true">
<template #icon>
<Icon name="i-heroicons:plus" />
</template>
</Button>
</div>

<UCard v-for="config in configs" :key="config.id">
<template #header>
{{ config.name }}
</template>

<template #footer>
<div class="flex justify-end gap-2">
<Button
size="icon"
@click="
() => {
// const {
// checkInterval,
// sniffingTimeout,
// checkTolerance,
// ...global
// } = config.global
// updateConfigFormModalRef?.setValues({
// name: config.name,
// checkIntervalSeconds: deriveTime(
// checkInterval as string,
// 's'
// ),
// sniffingTimeoutMS: deriveTime(
// sniffingTimeout as string,
// 'ms'
// ),
// checkToleranceMS: deriveTime(checkTolerance as string, 'ms'),
// ...global
// })
// isUpdateConfigFormModalOpen = true
}
"
>
<Icon name="i-heroicons:pencil" />
</Button>

<Button
:loading="isRemovingConfig"
:disabled="
config.id === defaults?.defaultConfigID || config.selected
"
size="icon"
@click="removeConfig(config.id)"
>
<Icon name="i-heroicons:minus" />
</Button>

<Button
:loading="isSelectingConfig"
:disabled="config.selected"
size="icon"
@click="selectConfig(config.id)"
>
<Icon name="i-heroicons:map-pin" />
</Button>
</div>
</template>
</UCard>

<ConfigFormModal
ref="createConfigFormModalRef"
v-model:open="isCreateConfigModalOpen"
@submit="
async () => {
await reloadConfigs()
isCreateConfigModalOpen = false
}
"
/>

<ConfigFormModal
ref="updateConfigFormModalRef"
v-model:open="isUpdateConfigFormModalOpen"
@submit="
async () => {
await reloadConfigs()
isUpdateConfigFormModalOpen = false
}
"
<ResourceConfigCard
v-for="config in configs"
:key="config.id"
:config="config"
@reload-configs="reloadConfigs"
/>
</div>
</template>
95 changes: 95 additions & 0 deletions components/ResourceConfigCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<script setup lang="ts">
import type { ResultOf } from 'gql.tada'
import * as mutations from '~/mutations'
import type * as queries from '~/queries'
defineProps<{ config: ResultOf<typeof queries.configs>['configs'][number] }>()
const emit = defineEmits<{
(event: 'reloadConfigs'): void
}>()
const apiStore = useAPIStore()
const { data: defaults } = useAsyncData('defaults', () =>
apiStore.getDefaults()
)
const isEditModalVisible = ref(false)
const isRemovingConfig = ref(false)
const removeConfig = async (id: string) => {
isRemovingConfig.value = true
try {
await apiStore.apiClient?.mutation(mutations.removeConfig, { id })
emit('reloadConfigs')
} finally {
isRemovingConfig.value = false
}
}
const isSelectingConfig = ref(false)
const selectConfig = async (id: string) => {
isSelectingConfig.value = true
try {
await apiStore.apiClient?.mutation(mutations.selectConfig, { id })
emit('reloadConfigs')
} finally {
isSelectingConfig.value = false
}
}
</script>

<template>
<Card>
<template #title>
{{ config.name }}
</template>

<template #footer>
<div class="flex justify-end gap-2">
<Button
class="space-x-1"
label="Edit"
size="small"
@click="isEditModalVisible = true"
>
<template #icon>
<Icon name="i-heroicons:pencil" />
</template>
</Button>

<Button
class="space-x-1"
label="Remove"
size="small"
severity="danger"
:loading="isRemovingConfig"
:disabled="config.id === defaults?.defaultConfigID || config.selected"
@click="removeConfig(config.id)"
>
<template #icon>
<Icon name="i-heroicons:trash" />
</template>
</Button>

<Button
size="small"
:loading="isSelectingConfig"
:disabled="config.selected"
@click="selectConfig(config.id)"
>
<template #icon>
<Icon name="i-heroicons:map-pin" />
</template>
</Button>
</div>
</template>
</Card>

<ConfigFormModal v-model:visible="isEditModalVisible" :config="config" />
</template>
Loading

0 comments on commit 41137d8

Please sign in to comment.