Skip to content

Commit 40f73b0

Browse files
committed
wip
1 parent 8f72af8 commit 40f73b0

File tree

9 files changed

+184
-35
lines changed

9 files changed

+184
-35
lines changed

packages/entities/entities-redis-configurations/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"devDependencies": {
4242
"@kong/design-tokens": "1.17.2",
4343
"@kong/kongponents": "9.14.8",
44+
"@types/uuid": "^10.0.0",
4445
"vue": "^3.5.12",
4546
"vue-router": "^4.4.5"
4647
},
@@ -65,5 +66,8 @@
6566
"@kong/kongponents": "9.14.8",
6667
"vue": "^3.5.12",
6768
"vue-router": "^4.4.5"
69+
},
70+
"dependencies": {
71+
"uuid": "^10.0.0"
6872
}
6973
}

packages/entities/entities-redis-configurations/src/components/ClusterNodes.vue

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@
88
</KLabel>
99
<div>
1010
<FieldArrayCardContainer
11-
v-for="(item, index) of items"
11+
v-for="(node, index) of nodes"
1212
:key="`${index}`"
13-
@remove-item="items.splice(index, 1)"
13+
@remove-item="removeItem(index)"
1414
>
15-
<div
16-
class="cluster-node-items"
17-
>
15+
<div class="cluster-node-items">
1816
<KInput
17+
v-model.trim="node.ip"
1918
:label="t('form.fields.cluster_node_ip.label')"
2019
:label-attributes="{
2120
info: t('form.fields.cluster_node_ip.tooltip'),
@@ -24,6 +23,7 @@
2423
required
2524
/>
2625
<KInput
26+
v-model="node.port"
2727
:label="t('form.fields.cluster_node_port.label')"
2828
:label-attributes="{
2929
info: t('form.fields.cluster_node_port.tooltip'),
@@ -45,20 +45,23 @@
4545
</template>
4646

4747
<script lang="ts" setup>
48-
import { ref } from 'vue'
4948
import { AddCircleIcon } from '@kong/icons'
5049
5150
import FieldArrayCardContainer from './FieldArrayCardContainer.vue'
5251
import composables from '../composables'
52+
import type { ClusterNode, Identifiable } from '../types'
53+
import { genDefaultClusterNode } from '../helpers'
54+
55+
const nodes = defineModel<Identifiable<ClusterNode>[]>({ required: true })
5356
5457
const { i18n: { t } } = composables.useI18n()
55-
type Item = {
56-
ip: string
57-
port: number
58-
}
59-
const items = ref<Item[]>([{ ip: '', port: 0 }])
58+
6059
const addItem = () => {
61-
items.value.push({ ip: '', port: 0 })
60+
nodes.value.push(genDefaultClusterNode())
61+
}
62+
63+
const removeItem = (index: number) => {
64+
nodes.value.splice(index, 1)
6265
}
6366
</script>
6467

packages/entities/entities-redis-configurations/src/components/RedisConfigurationForm.vue

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<template>
22
<div class="kong-ui-entities-redis-configurations-form">
33
<EntityBaseForm
4-
:can-submit="false"
4+
:can-submit="canSubmit"
55
:config="config"
66
:edit-id="partialId"
77
:entity-type="SupportedEntityType.RedisConfiguration"
88
:error-message="undefined"
99
:fetch-url="undefined"
10-
:form-fields="{}"
11-
:is-readonly="false"
10+
:form-fields="payload"
11+
:is-readonly="form.readonly"
1212
@cancel="noop"
1313
@fetch:error="noop"
1414
@fetch:success="noop"
@@ -65,7 +65,7 @@
6565
tooltipAttributes: { maxWidth: '400' },
6666
}"
6767
/>
68-
<SentinelNodes />
68+
<SentinelNodes v-model="form.fields.sentinel_nodes" />
6969
<KInput
7070
v-model.trim="form.fields.sentinel_username"
7171
:label="t('form.fields.sentinel_username.label')"
@@ -102,7 +102,7 @@
102102
:description="t('form.sections.cluster.description')"
103103
:title="t('form.sections.cluster.title')"
104104
>
105-
<ClusterNodes />
105+
<ClusterNodes v-model="form.fields.cluster_nodes" />
106106
<KInput
107107
v-model="form.fields.cluster_max_redirections"
108108
:label="t('form.fields.cluster_max_redirections.label')"
@@ -353,7 +353,11 @@ const getSelectedText = (item: any) => {
353353
return `${item.label}${suffix}`
354354
}
355355
356-
const { form } = useRedisConfigurationForm()
356+
const {
357+
form,
358+
canSubmit,
359+
payload,
360+
} = useRedisConfigurationForm()
357361
</script>
358362

359363
<style lang="scss" scoped>

packages/entities/entities-redis-configurations/src/components/SentinelNodes.vue

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@
88
</KLabel>
99
<div>
1010
<FieldArrayCardContainer
11-
v-for="(item, index) of items"
12-
:key="`${index}`"
13-
@remove-item="items.splice(index, 1)"
11+
v-for="(node, index) of nodes"
12+
:key="node.id"
13+
@remove-item="removeItem(index)"
1414
>
15-
<div
16-
class="cluster-node-items"
17-
>
15+
<div class="sentinel-node-items">
1816
<KInput
17+
v-model.trim="node.host"
1918
:label="t('form.fields.sentinel_node_host.label')"
2019
:label-attributes="{
2120
info: t('form.fields.sentinel_node_host.tooltip'),
@@ -24,6 +23,7 @@
2423
required
2524
/>
2625
<KInput
26+
v-model="node.port"
2727
:label="t('form.fields.sentinel_node_port.label')"
2828
:label-attributes="{
2929
info: t('form.fields.sentinel_node_port.tooltip'),
@@ -45,25 +45,28 @@
4545
</template>
4646

4747
<script lang="ts" setup>
48-
import { ref } from 'vue'
4948
import { AddCircleIcon } from '@kong/icons'
5049
5150
import FieldArrayCardContainer from './FieldArrayCardContainer.vue'
5251
import composables from '../composables'
52+
import type { Identifiable, SentinelNode } from '../types'
53+
import { genDefaultSentinelNode } from '../helpers'
54+
55+
const nodes = defineModel<Identifiable<SentinelNode>[]>({ required: true })
5356
5457
const { i18n: { t } } = composables.useI18n()
55-
type Item = {
56-
ip: string
57-
port: number
58-
}
59-
const items = ref<Item[]>([{ ip: '', port: 0 }])
58+
6059
const addItem = () => {
61-
items.value.push({ ip: '', port: 0 })
60+
nodes.value.push(genDefaultSentinelNode())
61+
}
62+
63+
const removeItem = (index: number) => {
64+
nodes.value.splice(index, 1)
6265
}
6366
</script>
6467

6568
<style lang="scss" scoped>
66-
.cluster-node-items {
69+
.sentinel-node-items {
6770
display: flex;
6871
flex-direction: column;
6972
gap: $kui-space-80;

packages/entities/entities-redis-configurations/src/composables/useRedisConfigurationForm.ts

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { computed, reactive } from 'vue'
22

33
import { Mode } from '../types'
4+
import { shallowCopyWithoutId } from '../helpers'
45

56
import type { RedisConfigurationFormState } from '../types'
67

@@ -36,11 +37,107 @@ export const useRedisConfigurationForm = () => {
3637
})
3738

3839
const canSubmit = computed(() => {
39-
return !!form.fields.name.length && !!form.fields.host
40+
if (!form.fields.name.length) {
41+
return false
42+
}
43+
44+
switch (form.fields.mode) {
45+
case Mode.HOST_PORT_OPEN_SOURCE:
46+
return !!form.fields.name.length
47+
case Mode.HOST_PORT_ENTERPRISE:
48+
return !!form.fields.name.length
49+
case Mode.CLUSTER:
50+
return !!form.fields.name.length
51+
case Mode.SENTINEL:
52+
return !!form.fields.name.length
53+
default:
54+
throw new Error('Invalid mode')
55+
}
56+
})
57+
58+
const payload = computed(() => {
59+
// todo: remove non-required and non-default values
60+
switch (form.fields.mode) {
61+
case Mode.HOST_PORT_OPEN_SOURCE:
62+
return {
63+
name: form.fields.name,
64+
mode: form.fields.mode,
65+
host: form.fields.host,
66+
port: form.fields.port,
67+
timeout: form.fields.timeout,
68+
username: form.fields.username,
69+
database: form.fields.database,
70+
password: form.fields.password,
71+
ssl: form.fields.ssl,
72+
ssl_verify: form.fields.ssl_verify,
73+
server_name: form.fields.server_name,
74+
}
75+
case Mode.HOST_PORT_ENTERPRISE:
76+
return {
77+
name: form.fields.name,
78+
mode: form.fields.mode,
79+
host: form.fields.host,
80+
port: form.fields.port,
81+
timeout: form.fields.timeout,
82+
username: form.fields.username,
83+
database: form.fields.database,
84+
password: form.fields.password,
85+
ssl: form.fields.ssl,
86+
ssl_verify: form.fields.ssl_verify,
87+
server_name: form.fields.server_name,
88+
connect_timeout: form.fields.connect_timeout,
89+
send_timeout: form.fields.send_timeout,
90+
read_timeout: form.fields.read_timeout,
91+
keepalive_pool_size: form.fields.keepalive_pool_size,
92+
keepalive_backlog: form.fields.keepalive_backlog,
93+
connection_is_proxied: form.fields.connection_is_proxied,
94+
}
95+
case Mode.CLUSTER:
96+
return {
97+
name: form.fields.name,
98+
mode: form.fields.mode,
99+
cluster_nodes: form.fields.cluster_nodes.map(shallowCopyWithoutId),
100+
cluster_max_redirections: form.fields.cluster_max_redirections,
101+
timeout: form.fields.timeout,
102+
username: form.fields.username,
103+
password: form.fields.password,
104+
ssl: form.fields.ssl,
105+
ssl_verify: form.fields.ssl_verify,
106+
server_name: form.fields.server_name,
107+
connect_timeout: form.fields.connect_timeout,
108+
send_timeout: form.fields.send_timeout,
109+
read_timeout: form.fields.read_timeout,
110+
keepalive_pool_size: form.fields.keepalive_pool_size,
111+
keepalive_backlog: form.fields.keepalive_backlog,
112+
connection_is_proxied: form.fields.connection_is_proxied,
113+
}
114+
case Mode.SENTINEL:
115+
return {
116+
name: form.fields.name,
117+
mode: form.fields.mode,
118+
sentinel_master: form.fields.sentinel_master,
119+
sentinel_nodes: form.fields.sentinel_nodes.map(shallowCopyWithoutId),
120+
timeout: form.fields.timeout,
121+
username: form.fields.username,
122+
password: form.fields.password,
123+
ssl: form.fields.ssl,
124+
ssl_verify: form.fields.ssl_verify,
125+
server_name: form.fields.server_name,
126+
connect_timeout: form.fields.connect_timeout,
127+
send_timeout: form.fields.send_timeout,
128+
read_timeout: form.fields.read_timeout,
129+
keepalive_pool_size: form.fields.keepalive_pool_size,
130+
keepalive_backlog: form.fields.keepalive_backlog,
131+
connection_is_proxied: form.fields.connection_is_proxied,
132+
}
133+
default:
134+
throw new Error('Invalid mode')
135+
}
40136
})
41137

42138
return {
43139
form,
44140
canSubmit,
141+
payload,
45142
}
46143
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { ClusterNode, SentinelNode } from './types'
2+
3+
export const DEFAULT_CLUSTER_NODE: ClusterNode = {
4+
ip: '127.0.0.1',
5+
port: 6379,
6+
}
7+
8+
export const DEFAULT_SENTINEL_NODE: SentinelNode = {
9+
host: '127.0.0.1',
10+
port: 6379,
11+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { v4 as uuidv4 } from 'uuid'
2+
3+
import { DEFAULT_CLUSTER_NODE, DEFAULT_SENTINEL_NODE } from './constants'
4+
import type { Identifiable } from './types'
5+
6+
export const shallowCopyWithId = <T extends Record<any, any>>(node: T): Identifiable<T> => {
7+
return { ...node, id: uuidv4() }
8+
}
9+
10+
export const shallowCopyWithoutId = <T extends { id: string }>(node: T): Omit<T, 'id'> => {
11+
const { id, ...rest } = node
12+
return rest
13+
}
14+
15+
export const genDefaultSentinelNode = () => shallowCopyWithId(DEFAULT_SENTINEL_NODE)
16+
17+
export const genDefaultClusterNode = () => shallowCopyWithId(DEFAULT_CLUSTER_NODE)

packages/entities/entities-redis-configurations/src/types/redis-configuration-form.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export interface SentinelNode {
1414
port: number
1515
}
1616

17+
export type Identifiable<T> = T & { id: string }
18+
1719
export interface ClusterNode {
1820
ip: string
1921
port: number
@@ -41,8 +43,8 @@ export interface RedisConfigurationFields {
4143
keepalive_backlog: number
4244
sentinel_master: string
4345
sentinel_role?: 'master' | 'slave' | 'any'
44-
sentinel_nodes: SentinelNode[]
45-
cluster_nodes: ClusterNode[]
46+
sentinel_nodes: Identifiable<SentinelNode>[]
47+
cluster_nodes: Identifiable<ClusterNode>[]
4648
cluster_max_redirections: number
4749
connection_is_proxied: boolean
4850
}

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)