Skip to content

Commit e08ec5d

Browse files
authored
feat(entities-plugins): datakit load data, simplify node select (#2332)
1 parent ba2079b commit e08ec5d

File tree

14 files changed

+229
-269
lines changed

14 files changed

+229
-269
lines changed

packages/entities/entities-plugins/src/components/free-form/Datakit/CodeEditor.vue

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,56 @@
11
<template>
2-
<div
3-
ref="editor-root"
4-
class="dk-editor"
5-
/>
2+
<div class="dk-code-editor">
3+
<KAlert class="examples">
4+
<div class="examples-content">
5+
{{ t('plugins.free-form.datakit.description_example') }}
6+
7+
<KButton
8+
v-for="(_, key) in examples"
9+
:key="key"
10+
appearance="secondary"
11+
size="small"
12+
@click="setExampleCode(key)"
13+
>
14+
{{ t(`plugins.free-form.datakit.examples.${key}`) }}
15+
</KButton>
16+
</div>
17+
18+
<template #icon>
19+
<SparklesIcon />
20+
</template>
21+
</KAlert>
22+
<div
23+
ref="editor-root"
24+
class="editor"
25+
/>
26+
</div>
627
</template>
728

829
<script setup lang="ts">
930
import { useTemplateRef, onMounted, onBeforeUnmount, shallowRef, toRaw } from 'vue'
1031
import * as monaco from 'monaco-editor'
11-
import type { YAMLException } from 'js-yaml'
32+
import { createI18n } from '@kong-ui-public/i18n'
33+
import { KAlert, KButton } from '@kong/kongponents'
34+
import { SparklesIcon } from '@kong/icons'
35+
import english from '../../../locales/en.json'
1236
import yaml, { JSON_SCHEMA } from 'js-yaml'
1337
import * as examples from './examples'
1438
39+
import type { YAMLException } from 'js-yaml'
40+
import type { DatakitConfig } from './types'
41+
42+
const { t } = createI18n<typeof english>('en-us', english)
43+
1544
const {
1645
editing,
1746
config,
1847
} = defineProps<{
1948
editing: boolean
20-
config: any
49+
config?: DatakitConfig
2150
}>()
2251
2352
const emit = defineEmits<{
24-
change: [config: any]
53+
change: [config: unknown]
2554
error: [msg: string]
2655
}>()
2756
@@ -127,8 +156,19 @@ defineExpose({
127156
</script>
128157

129158
<style lang="scss" scoped>
130-
.dk-editor {
131-
height: 320px;
132-
width: 100%;
159+
.dk-code-editor {
160+
.examples {
161+
margin-bottom: $kui-space-70;
162+
}
163+
164+
.examples-content {
165+
display: flex;
166+
gap: $kui-space-40;
167+
}
168+
169+
.editor {
170+
height: 684px;
171+
width: 100%;
172+
}
133173
}
134174
</style>

packages/entities/entities-plugins/src/components/free-form/Datakit/DatakitForm.vue

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -21,42 +21,24 @@
2121
<template #default="formProps">
2222
<Form
2323
v-bind="formProps"
24+
:data="{ config }"
2425
tag="div"
26+
@change="handleFormChange"
2527
>
2628
<div v-if="finalEditorMode === 'flow'">
2729
<FlowEditor
28-
:config="props.model.config"
30+
:config="config"
2931
:editing="props.isEditing"
32+
@change="handleConfigChange"
3033
/>
3134
</div>
3235

3336
<div v-else-if="finalEditorMode === 'code'">
34-
<KAlert class="examples">
35-
<div class="examples-content">
36-
{{ t('plugins.free-form.datakit.description_example') }}
37-
38-
<KButton
39-
v-for="(_, key) in examples"
40-
:key="key"
41-
appearance="secondary"
42-
size="small"
43-
@click="handleExampleClick(key)"
44-
>
45-
{{ t(`plugins.free-form.datakit.examples.${key}`) }}
46-
</KButton>
47-
</div>
48-
49-
<template #icon>
50-
<SparklesIcon />
51-
</template>
52-
</KAlert>
53-
5437
<CodeEditor
55-
ref="code-editor"
5638
class="code-editor"
57-
:config="props.model.config"
39+
:config="config"
5840
:editing="props.isEditing"
59-
@change="handleCodeChange"
41+
@change="handleConfigChange"
6042
@error="handleCodeError"
6143
/>
6244
</div>
@@ -71,17 +53,16 @@
7153
</template>
7254

7355
<script setup lang="ts">
74-
import { computed, useTemplateRef, inject } from 'vue'
75-
import { KAlert, KSegmentedControl } from '@kong/kongponents'
76-
import { SparklesIcon, DesignIcon, CodeblockIcon } from '@kong/icons'
56+
import { computed, inject, ref } from 'vue'
57+
import { KSegmentedControl } from '@kong/kongponents'
58+
import { DesignIcon, CodeblockIcon } from '@kong/icons'
7759
import { createI18n } from '@kong-ui-public/i18n'
7860
import english from '../../../locales/en.json'
7961
import StandardLayout from '../shared/layout/StandardLayout.vue'
8062
import Form from '../shared/Form.vue'
8163
import FlowEditor from './flow-editor/FlowEditor.vue'
8264
import CodeEditor from './CodeEditor.vue'
8365
import { usePreferences } from './composables'
84-
import * as examples from './examples'
8566
import { FEATURE_FLAGS } from '../../../constants'
8667
8768
import type { Component } from 'vue'
@@ -94,8 +75,6 @@ const { t } = createI18n<typeof english>('en-us', english)
9475
const props = defineProps<Props<any>>()
9576
9677
// provided by consumer apps
97-
// TODO: make the default value to `false` to make it opt-in
98-
// It's currently set to `true` for testing purposes
9978
const enableFlowEditor = inject<boolean>(FEATURE_FLAGS.DATAKIT_ENABLE_FLOW_EDITOR, false)
10079
10180
// Editor mode selection
@@ -132,24 +111,37 @@ const description = computed(() => {
132111
}
133112
})
134113
135-
// Code editor
114+
// Shared
136115
137-
const codeEditor = useTemplateRef('code-editor')
116+
const config = ref({ ...props.model.config })
138117
139-
function handleExampleClick(example: keyof typeof examples) {
140-
codeEditor.value?.setExampleCode(example)
118+
// This change comes from freeform fields
119+
function handleFormChange(data: any) {
120+
for (const key in data.config) {
121+
// updating nodes can lead to re`load`ing the flow editor state
122+
if (key !== 'nodes') {
123+
config.value[key] = data.config[key]
124+
}
125+
}
141126
}
142127
143-
function handleCodeChange(config: any) {
128+
function handleConfigChange(newConfig: unknown) {
129+
// update the external form state
144130
props.onFormChange({
145-
config,
131+
config: newConfig,
146132
})
147133
props.onValidityChange?.({
148134
model: 'config',
149135
valid: true,
150136
})
137+
138+
// update the local config as the external form state isn't
139+
// flowing back down to the component
140+
config.value = newConfig
151141
}
152142
143+
// Code editor
144+
153145
function handleCodeError(msg: string) {
154146
props.onValidityChange?.({
155147
model: 'config',
@@ -158,20 +150,3 @@ function handleCodeError(msg: string) {
158150
})
159151
}
160152
</script>
161-
162-
<style lang="scss" scoped>
163-
.dk-form {
164-
.code-editor {
165-
height: 684px;
166-
}
167-
168-
.examples {
169-
margin-bottom: $kui-space-70;
170-
}
171-
172-
.examples-content {
173-
display: flex;
174-
gap: $kui-space-40;
175-
}
176-
}
177-
</style>
Lines changed: 39 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,64 @@
11
<template>
22
<div class="dk-flow-editor">
3-
<div>Nothing here yet.</div>
43
<KButton
54
appearance="secondary"
65
@click="modalOpen = true"
76
>
87
{{ t('plugins.free-form.datakit.flow_editor.cta') }}
98
</KButton>
109
<EditorModal v-model:open="modalOpen" />
10+
<div class="field">
11+
<BooleanField
12+
name="config.debug"
13+
/>
14+
</div>
1115
</div>
1216
</template>
1317

1418
<script setup lang="ts">
19+
import { watch } from 'vue'
1520
import { createI18n } from '@kong-ui-public/i18n'
1621
import english from '../../../../locales/en.json'
1722
import { provideEditorStore } from '../composables'
18-
import type { ConfigNodeName, FieldName, NameConnection, NodeName } from '../types'
23+
import BooleanField from '../../shared/BooleanField.vue'
1924
import EditorModal from './modal/EditorModal.vue'
2025
26+
import type { DatakitConfig } from '../types'
27+
2128
const { t } = createI18n<typeof english>('en-us', english)
2229
23-
defineProps<{
30+
const { config } = defineProps<{
2431
editing: boolean
25-
config: any
32+
config?: DatakitConfig
33+
}>()
34+
35+
const emit = defineEmits<{
36+
change: [config: DatakitConfig]
37+
error: [msg: string]
2638
}>()
2739
28-
// todo(zehao): mock data, remove later
29-
// provideEditorStore(MockData.configNodes, MockData.uiNodes)
40+
function onChange(newConfig: DatakitConfig) {
41+
emit('change', {
42+
...config,
43+
...newConfig,
44+
})
45+
}
3046
31-
const { modalOpen } = provideEditorStore([
32-
{
33-
name: 'CAT_FACT' as ConfigNodeName,
34-
type: 'call',
35-
url: 'https://catfact.ninja/fact',
36-
input: 'request.body' as NameConnection,
37-
},
38-
{
39-
name: 'DOG_FACT' as ConfigNodeName,
40-
type: 'call',
41-
url: 'https://dogapi.dog/api/v1/facts',
42-
},
43-
{
44-
name: 'JOIN' as ConfigNodeName,
45-
type: 'jq',
46-
inputs: {
47-
cat: 'CAT_FACT.body',
48-
dog: 'DOG_FACT.body',
49-
} as Record<FieldName, NameConnection>,
50-
jq: '{\n cat_fact: .cat.fact,\n dog_fact: .dog.facts[0],\n}\n',
51-
},
52-
{
53-
name: 'EXIT' as ConfigNodeName,
54-
type: 'exit',
55-
inputs: {
56-
body: 'JOIN',
57-
} as Record<FieldName, NameConnection>,
58-
status: 200,
59-
},
60-
{
61-
name: 'DANGLING_CALL' as ConfigNodeName,
62-
type: 'call',
63-
url: 'https://dogapi.dog/api/v1/facts',
64-
},
65-
{
66-
name: 'READ_UPSTREAM' as ConfigNodeName,
67-
type: 'jq',
68-
input: 'service_response',
69-
jq: '.',
70-
},
71-
{
72-
name: 'VALUE' as ConfigNodeName,
73-
type: 'static',
74-
values: {
75-
foo: 'bar',
76-
baz: null,
77-
nested: {
78-
key: 'value',
79-
array: [1, 2, 3],
80-
},
81-
},
82-
outputs: {
83-
foo: 'MY_CALL.body',
84-
baz: 'MY_CALL.headers',
85-
} as Record<FieldName, NameConnection>,
86-
},
87-
{
88-
name: 'MY_CALL' as ConfigNodeName,
89-
type: 'call',
90-
url: 'https://example.com/api',
91-
},
92-
], [
93-
{
94-
name: 'VALUE' as NodeName,
95-
phase: 'response',
96-
position: { x: 0, y: 0 },
97-
fields: {
98-
output: ['foo', 'baz', 'nested', 'unknown'] as FieldName[],
99-
},
100-
expanded: {
101-
output: true,
102-
},
103-
},
104-
])
47+
const { modalOpen, load } = provideEditorStore(config?.nodes ?? [], [], { onChange })
48+
49+
watch(() => config?.nodes, (newNodes) => {
50+
// Only load if the modal is not open
51+
if (modalOpen.value) {
52+
return
53+
}
54+
load(newNodes ?? [], [])
55+
})
10556
</script>
57+
58+
<style lang="scss" scoped>
59+
.dk-flow-editor {
60+
.field {
61+
margin-top: $kui-space-80;
62+
}
63+
}
64+
</style>

0 commit comments

Comments
 (0)