Skip to content

Commit 49185df

Browse files
start Adding deploy form
1 parent 456c86f commit 49185df

13 files changed

Lines changed: 358 additions & 6 deletions

File tree

frontend/kubecloud-v2/components/WorkflowDialogCard.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,6 @@ defineEmits<{ (e: "cancel"): void }>()
141141
142142
const color = useStatusColor(() => props.workflow?.status ?? "")
143143
const createdAt = useDateFormat(() => props.workflow?.created_at, "DD/MM/YYYY, HH:mm")
144-
const metadata = computed(() => marked.parse(`\`\`\`json\n${JSON.stringify(props.workflow?.metadata, null, 2)}\n\`\`\``, { renderer }))
145-
const state = computed(() => marked.parse(`\`\`\`json\n${JSON.stringify(props.workflow?.state, null, 2)}\n\`\`\``, { renderer }))
144+
const metadata = computed(() => marked.parse(`\`\`\`json\n${JSON.stringify(props.workflow?.metadata ?? "", null, 2)}\n\`\`\``, { renderer }))
145+
const state = computed(() => marked.parse(`\`\`\`json\n${JSON.stringify(props.workflow?.state ?? "", null, 2)}\n\`\`\``, { renderer }))
146146
</script>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<template>
2+
<v-row>
3+
<v-col cols="12" class="pb-0">
4+
<v-text-field v-model="$props.node.name" variant="outlined" label="Node Name" />
5+
</v-col>
6+
7+
<v-col cols="12">
8+
<div class="d-flex justify-space-between align-center">
9+
<div>
10+
<p class="text-subtitle-1 font-weight-bold">
11+
Use Full Node Capabilities
12+
</p>
13+
<p class="text-caption opacity-70">
14+
Include all available resources within placed node
15+
</p>
16+
</div>
17+
18+
<v-switch v-model="$props.node.useFullNodeCapabilities" color="primary" inset hide-details />
19+
</div>
20+
</v-col>
21+
22+
<v-expand-transition>
23+
<div v-if="!node.useFullNodeCapabilities" class="w-100">
24+
<v-col cols="12" class="pb-0">
25+
<v-row>
26+
<v-col cols="4" class="pb-0">
27+
<v-text-field v-model="$props.node.cpu" variant="outlined" label="CPU (vCores)" />
28+
</v-col>
29+
30+
<v-col cols="4" class="pb-0">
31+
<v-text-field v-model="$props.node.memory" variant="outlined" label="RAM (GB)" />
32+
</v-col>
33+
34+
<v-col cols="4" class="pb-0">
35+
<v-text-field v-model="$props.node.disk" variant="outlined" label="Disk Size (GB)" />
36+
</v-col>
37+
</v-row>
38+
</v-col>
39+
</div>
40+
</v-expand-transition>
41+
42+
<v-col cols="12" class="pb-0 d-flex align-start ga-3">
43+
<label class="text-body-2 text-no-wrap mt-2">
44+
SSH Keys:
45+
</label>
46+
47+
<v-chip-group v-model="$props.node.sshKeys" multiple selected-class="text-primary">
48+
<v-chip
49+
v-for="(key, index) in sshKeys"
50+
:key="key.id"
51+
filter
52+
:value="index"
53+
class="rounded"
54+
size="small"
55+
>
56+
{{ key.name }}
57+
</v-chip>
58+
</v-chip-group>
59+
</v-col>
60+
<p v-if="node.sshKeys.length === 0" class="text-error text-caption">
61+
<v-icon icon="mdi-alert-circle" size="small" color="error" />
62+
Please select at least one SSH key
63+
</p>
64+
</v-row>
65+
</template>
66+
67+
<script setup lang="ts">
68+
import type { ModelsSSHKey } from "~/generated/api"
69+
70+
defineProps<{ sshKeys: ModelsSSHKey[], node: ClusterNode }>()
71+
</script>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<template>
2+
<v-card>
3+
<h3 class="text-h6 font-weight-bold mb-6">
4+
Cluster Configuration
5+
</h3>
6+
7+
<v-text-field
8+
:model-value="modelValue"
9+
variant="outlined"
10+
label="Cluster Name"
11+
placeholder="Enter cluster name"
12+
hint="Cluster name must be at least 3 characters and contain only letters and numbers"
13+
persistent-hint
14+
:rules="[
15+
(v) => !!v || 'Cluster name is required', (v) => v.length >= 3 || 'Cluster name must be at least 3 characters',
16+
(v) => v.length <= 255 || 'Cluster name must be less than 255 characters',
17+
(v) => /^[a-zA-Z0-9]+$/.test(v) || 'Cluster name must contain only letters and numbers',
18+
]"
19+
@update:model-value="$emit('update:modelValue', $event)"
20+
>
21+
<template #append-inner>
22+
<v-icon icon="mdi-refresh" tabindex="-1" @click="console.log($event)" />
23+
</template>
24+
</v-text-field>
25+
</v-card>
26+
</template>
27+
28+
<script setup lang="ts">
29+
defineProps<{ modelValue: string }>()
30+
defineEmits<{ (e: "update:modelValue", value: string): void }>()
31+
</script>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<template>
2+
<v-row>
3+
<v-col cols="12">
4+
<DefineVMsClusterName v-model="$props.modelValue.name" />
5+
</v-col>
6+
7+
<v-col cols="6">
8+
<DefineVMsNodes
9+
icon="mdi-server"
10+
node-type="Master"
11+
:ssh-keys="sshKeys"
12+
:nodes="$props.modelValue.masters"
13+
@add-node="$props.modelValue.masters.push(createClusterNode())"
14+
@remove-node="$props.modelValue.masters = $props.modelValue.masters.filter(master => master.id !== $event)"
15+
/>
16+
</v-col>
17+
18+
<v-col cols="6">
19+
<DefineVMsNodes
20+
icon="mdi-console"
21+
node-type="Worker"
22+
:ssh-keys="sshKeys"
23+
:nodes="$props.modelValue.workers"
24+
@add-node="$props.modelValue.workers.push(createClusterNode())"
25+
@remove-node="$props.modelValue.workers = $props.modelValue.workers.filter(worker => worker.id !== $event)"
26+
/>
27+
</v-col>
28+
</v-row>
29+
</template>
30+
31+
<script setup lang="ts">
32+
defineProps<{ modelValue: ClusterForm }>()
33+
34+
const api = useApi()
35+
const { state: sshKeys } = useAsyncState(async () => {
36+
const { data } = await api.users.listSshKeys()
37+
return data.data ?? []
38+
}, [])
39+
</script>
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<template>
2+
<v-card>
3+
<div class="d-flex align-center justify-space-between mb-8">
4+
<h3 class="d-flex align-center ga-2">
5+
<v-icon :icon="icon" size="x-small" color="primary" />
6+
{{ nodeType }} Nodes
7+
</h3>
8+
9+
<v-btn
10+
variant="text"
11+
:text="`Add ${nodeType}`"
12+
color="primary"
13+
prepend-icon="mdi-plus"
14+
border
15+
@click="$emit('addNode')"
16+
/>
17+
</div>
18+
19+
<div v-if="nodes.length === 0" cols="12" class="border border-dashed rounded-lg d-flex justify-center align-center">
20+
<div class="text-center my-12" :style="{ color: 'rgba(var(--v-border-color), 0.5)' }">
21+
<v-icon icon="mdi-sitemap-outline" size="50" class="mb-4" />
22+
<p class="text-body-1">
23+
No {{ nodeType }} nodes configured
24+
</p>
25+
</div>
26+
</div>
27+
28+
<div v-else>
29+
<v-tabs
30+
v-model="tab"
31+
align-tabs="center"
32+
color="primary"
33+
class="mb-8"
34+
>
35+
<v-tab v-for="node in nodes" :key="node.id" :value="node.id" :class="{ 'text-error': !isValidClusterNode(node) }">
36+
{{ node.name || '*Unnamed' }}
37+
38+
<template v-if="!node.permanent" #append>
39+
<v-btn
40+
icon
41+
size="x-small"
42+
variant="plain"
43+
color="error"
44+
:style="{ borderRadius: '50% !important' }"
45+
@click.stop="onRemoveNode(node.id)"
46+
>
47+
<v-icon icon="mdi-close" size="small" />
48+
</v-btn>
49+
</template>
50+
</v-tab>
51+
</v-tabs>
52+
53+
<DefineVMNodeForm v-if="activeNode" :ssh-keys="sshKeys" :node="activeNode" />
54+
</div>
55+
</v-card>
56+
</template>
57+
58+
<script setup lang="ts">
59+
import type { ModelsSSHKey } from "~/generated/api"
60+
61+
const props = defineProps<{
62+
icon: string
63+
nodeType: string
64+
sshKeys: ModelsSSHKey[]
65+
nodes: ClusterNode[]
66+
}>()
67+
68+
const emit = defineEmits<{
69+
(e: "addNode"): void
70+
(e: "removeNode", id: string): void
71+
}>()
72+
73+
const tab = ref<string>()
74+
const activeNode = computed(() => props.nodes.find(node => node.id === tab.value))
75+
76+
function onRemoveNode(id: string) {
77+
if (tab.value === id) {
78+
const nodes = props.nodes.filter(node => node.id !== id)
79+
tab.value = nodes[0]?.id
80+
}
81+
82+
emit("removeNode", id)
83+
}
84+
</script>

frontend/kubecloud-v2/components/home/HomeExperienceSection.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
>
1010
<v-container class="mt-16">
1111
<div>
12-
<h1 class="text-h1 font-weight-bold text-center mb-8">
12+
<h1 class="text-h3 font-weight-bold text-center mb-8 mx-auto" :style="{ maxWidth: '900px' }">
1313
Ready to Transform Your Kubernetes Experience?
1414
</h1>
1515
<p class="text-body-1 text-center mx-auto pa-2 rounded-lg" :style="{ maxWidth: '600px', backgroundColor: 'rgba(var(--v-theme-background), 0.8)' }">

frontend/kubecloud-v2/composables/docs.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import fm from "front-matter"
12
import hljs from "highlight.js"
23
import yaml from "js-yaml"
34
import { Marked } from "marked"
@@ -13,6 +14,7 @@ export interface Doc {
1314
md: {
1415
html: string
1516
tableOfContent: { id: string, content: string }[]
17+
attributes: Record<string, string>
1618
}
1719
}
1820

@@ -131,7 +133,7 @@ renderer.link = function ({ href, tokens }) {
131133

132134
renderer.strong = function ({ tokens }) {
133135
const content = this.parser.parseInline(tokens)
134-
return `<strong class="text-white text-body-1 font-weight-bold">${content}</strong>`
136+
return `<strong class="text-white text-body-1">${content}</strong>`
135137
}
136138

137139
renderer.codespan = function ({ text }) {
@@ -158,13 +160,15 @@ export const useDocs = createGlobalState(() => {
158160

159161
return docs.map((doc, index) => {
160162
tableOfContent = []
161-
const content = contents[index] ?? ""
163+
const { attributes, body } = fm(contents[index] ?? "") as { attributes: Record<string, string>, body: string }
164+
const content = body
162165
return {
163166
...doc,
164167
content,
165168
md: {
166169
html: marked.parse(content, { renderer }),
167170
tableOfContent,
171+
attributes,
168172
},
169173
}
170174
})

frontend/kubecloud-v2/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"nuxt-toast": "^1.4.0",
3232
"quill": "^2.0.3",
3333
"three": "^0.182.0",
34+
"uuid": "^13.0.0",
3435
"validator": "^13.15.26",
3536
"vue": "^3.5.25",
3637
"vue-router": "^4.6.3",

frontend/kubecloud-v2/pages/dashboard/clusters/deploy.vue

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,65 @@
11
<template>
2-
<div>Deploy cluster</div>
2+
<v-container class="py-16">
3+
<div class="mb-16">
4+
<h1 class="text-h2 font-weight-bold text-center mb-4">
5+
Deploy New Cluster
6+
</h1>
7+
<p class="text-body-1 text-center text-primary mx-auto" :style="{ maxWidth: '600px' }">
8+
Create and configure your Kubernetes cluster in just a few steps
9+
</p>
10+
</div>
11+
12+
{{ cluster }}
13+
14+
<v-stepper
15+
v-model="step"
16+
flat
17+
bg-color="transparent"
18+
#="{ next, prev }"
19+
>
20+
<v-stepper-header class="elevation-0">
21+
<v-stepper-item :value="1" title="Define VMs" />
22+
<v-divider />
23+
<v-stepper-item :value="2" title="Place VMs" />
24+
<v-divider />
25+
<v-stepper-item :value="3" title="Review" />
26+
</v-stepper-header>
27+
28+
<v-stepper-window>
29+
<v-stepper-window-item :value="1">
30+
<DefineVMsForm v-model="cluster" />
31+
</v-stepper-window-item>
32+
33+
<v-stepper-window-item :value="2">
34+
Place VMs
35+
</v-stepper-window-item>
36+
37+
<v-stepper-window-item :value="3">
38+
Review
39+
</v-stepper-window-item>
40+
</v-stepper-window>
41+
42+
<v-divider class="mt-12 mb-6" />
43+
44+
<div class="d-flex justify-end ">
45+
<v-btn
46+
prepend-icon="mdi-arrow-left"
47+
text="Back"
48+
variant="plain"
49+
:disabled="step === 1"
50+
@click="prev"
51+
/>
52+
53+
<v-btn
54+
append-icon="mdi-arrow-right"
55+
text="Next"
56+
variant="tonal"
57+
color="primary"
58+
@click="next"
59+
/>
60+
</div>
61+
</v-stepper>
62+
</v-container>
363
</template>
464

565
<script setup lang="ts">
@@ -10,4 +70,12 @@ onUnmounted(drawer.open)
1070
1171
onMounted(container.fluidize)
1272
onUnmounted(container.containerize)
73+
74+
const step = ref(1)
75+
76+
const cluster = ref<ClusterForm>({
77+
name: "engine789",
78+
masters: [createClusterNode({ name: "Leader", permanent: true })],
79+
workers: [],
80+
})
1381
</script>

frontend/kubecloud-v2/pages/docs/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
</div> -->
55

66
<v-card>
7+
<!-- {{ page?.md?.attributes }} -->
78
<div v-html="page?.md?.html" />
89
</v-card>
910
</template>

0 commit comments

Comments
 (0)