Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: KM-235 redis form plugin adapation #1873

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
f1dbedc
feat: entities redis configuration base
2eha0 Jan 17, 2025
094f424
feat(redis): redis configuration form [KM-235]
2eha0 Nov 18, 2024
af0a2b1
feat: form model
2eha0 Nov 21, 2024
4f8bb0e
wip
2eha0 Nov 25, 2024
88324c4
wip
2eha0 Dec 27, 2024
de69921
feat: redis type
2eha0 Jan 10, 2025
c87740d
wip
2eha0 Jan 15, 2025
c966ac2
wip
2eha0 Jan 17, 2025
97e7cca
wip
2eha0 Jan 17, 2025
f7cee50
fix: build
2eha0 Jan 17, 2025
a22fa84
fix: build
2eha0 Jan 17, 2025
b127b64
feat(redis): list and detail components
2eha0 Feb 18, 2025
df1e26c
fix: build
2eha0 Jan 21, 2025
448c077
fix: build
2eha0 Jan 21, 2025
0ba4179
fix: entity base form support
2eha0 Jan 21, 2025
8940b0e
fix: dist size limiting
2eha0 Jan 21, 2025
e5fc586
feat(redis): export helpers and constants
2eha0 Jan 21, 2025
36e62b2
chore: dist size limit
2eha0 Jan 22, 2025
c54a57e
fix: modal demo
2eha0 Jan 22, 2025
ebf4526
feat: config card support
2eha0 Feb 5, 2025
e408719
docs: add readme files
2eha0 Feb 6, 2025
778c340
test: redis configuration form
2eha0 Feb 7, 2025
a835f21
test: redis configuration form 2
2eha0 Feb 13, 2025
2ef9f24
feat: ee type can be changed to other ee types
2eha0 Feb 13, 2025
f8eafe1
feat: linked plugins
2eha0 Feb 14, 2025
7ce816f
feat: use swrv to reqeust links
2eha0 Feb 17, 2025
53c24ff
fix: compat wrong data structure of links response
2eha0 Feb 17, 2025
76947de
fix: view plugin emit params
2eha0 Feb 18, 2025
237ceec
test: fields reset logic
2eha0 Feb 18, 2025
911d8ad
fix: form submit validation
2eha0 Feb 18, 2025
0ff95da
feat: entities redis configuration base
2eha0 Nov 13, 2024
36b5bd3
chore(deps): bump @kong/kongponents (#1786)
portikM Nov 13, 2024
a3f1f69
feat: entities redis configuration base
2eha0 Jan 17, 2025
5f07f7e
feat(redis): list and detail components
2eha0 Jan 21, 2025
fd2f5e7
feat(plugin-form): adaption of redis config in all plugins
TT1228 Dec 24, 2024
7757971
feat(plugin-form): data cache during partial toggle
TT1228 Dec 26, 2024
cdf1f0a
chore: add redis link in plugin config card
TT1228 Jan 15, 2025
6ba455b
chore: adaption for gateway preview image
TT1228 Jan 17, 2025
512bcde
chore: emit showNewPartialModal event
TT1228 Jan 20, 2025
ed35303
feat: enable custom plugin redis config
TT1228 Jan 22, 2025
40e8144
chore: prepare FF prop
TT1228 Jan 23, 2025
7471e3b
chore: filter by redis type
TT1228 Feb 5, 2025
b27ef6f
chore: emit showNewPartialModel from select component
TT1228 Feb 6, 2025
d014748
feat: ff support for oidc and rla
TT1228 Feb 6, 2025
c1a1cc1
chore: add test for vfg, rla form and oidc form
TT1228 Feb 13, 2025
9269847
fix: fix unintentioned passing of _customPlugin
TT1228 Feb 13, 2025
9778ebb
chore: remove dependencies of entities-redis-configurations
TT1228 Feb 17, 2025
782e2b5
chore: fix plugin partial type filter when editing
TT1228 Feb 18, 2025
44b5e8a
chore: add note
TT1228 Feb 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
888 changes: 888 additions & 0 deletions packages/core/forms/fixtures/mockData.ts

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions packages/core/forms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@
"lodash-es": "^4.17.21"
},
"peerDependencies": {
"@kong-ui-public/entities-shared": "workspace:^",
"@kong-ui-public/i18n": "workspace:^",
"@kong/kongponents": "^9.21.5",
"vue": "^3.5.12"
},
"devDependencies": {
"@kong-ui-public/entities-shared": "workspace:^",
"@kong-ui-public/i18n": "workspace:^",
"@kong/design-tokens": "1.17.2",
"@kong/kongponents": "9.21.5",
Expand Down
44 changes: 40 additions & 4 deletions packages/core/forms/src/components/FormGenerator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,21 @@
v-for="field in fields"
:key="field.model"
>
<form-redis
v-if="field.model === '__redis_partial' && enableRedisPartial"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why __redis_partial? It looks very wired. Is there any particular consideration?

:errors="errors"
:field="field"
:model="model"
:options="options"
:tag="tag"
:vfg="vfg"
@model-updated="onModelUpdated"
@partial-toggled="onPartialToggled"
@show-new-partial-modal="$emit('showNewPartialModal')"
@validated="onFieldValidated"
/>
<form-group
v-if="fieldVisible(field)"
v-else-if="fieldVisible(field)"
ref="children"
:errors="errors"
:field="field"
Expand Down Expand Up @@ -93,8 +106,21 @@
v-for="field in group.collapsible.nestedCollapsible.fields"
:key="field.model"
>
<form-redis
v-if="field.model === '__redis_partial' && enableRedisPartial"
:errors="errors"
:field="field"
:model="model"
:options="options"
:tag="tag"
:vfg="vfg"
@model-updated="onModelUpdated"
@partial-toggled="onPartialToggled"
@show-new-partial-modal="$emit('showNewPartialModal')"
@validated="onFieldValidated"
/>
<form-group
v-if="fieldVisible(field)"
v-else-if="fieldVisible(field)"
ref="children"
:errors="errors"
:field="field"
Expand Down Expand Up @@ -159,11 +185,12 @@ import isNil from 'lodash-es/isNil'
import { ref } from 'vue'
import { AUTOFILL_SLOT, AUTOFILL_SLOT_NAME } from '../const'
import formGroup from './FormGroup.vue'
import formRedis from './FormRedis.vue'
import formMixin from './FormMixin.vue'

export default {
name: 'FormGenerator',
components: { formGroup },
components: { formGroup, formRedis },
mixins: [formMixin],

inject: {
Expand Down Expand Up @@ -227,8 +254,13 @@ export default {
return value.length > 0
},
},

enableRedisPartial: {
type: Boolean,
default: false,
},
},
emits: ['validated', 'modelUpdated', 'refreshModel'],
emits: ['validated', 'modelUpdated', 'refreshModel', 'partialToggled', 'showNewPartialModal'],

data() {
return {
Expand Down Expand Up @@ -339,6 +371,10 @@ export default {
this.$emit('modelUpdated', newVal, schema)
},

onPartialToggled(field, model) {
this.$emit('partialToggled', field, model)
},

// Validating the model properties
validate(isAsync = null) {
if (isAsync === null) {
Expand Down
238 changes: 238 additions & 0 deletions packages/core/forms/src/components/FormRedis.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
<template>
<div>
<div v-if="isCustomPlugin">
<KAlert
data-testid="custom-plugin-redis-config-note"
:message="t('redis.custom_plugin.alert')"
/>
<RedisConfigSelect
:default-redis-config-item="selectedRedisConfigItem"
:plugin-redis-fields="field.fields"
:update-redis-model="updateRedisModel"
@show-new-partial-modal="$emit('showNewPartialModal')"
/>
</div>
<KCard
v-else
class="redis-config-card"
data-testid="redis-config-card"
:title="t('redis.title')"
>
<div
class="redis-config-radio-group"
data-testid="redis-config-radio-group"
>
<KRadio
v-model="usePartial"
card
card-orientation="horizontal"
data-testid="shared-redis-config-radio"
:description="t('redis.shared_configuration.description')"
:label="t('redis.shared_configuration.label')"
:selected-value="true"
>
<KBadge appearance="success">
{{ t('redis.shared_configuration.badge') }}
</KBadge>
</KRadio>
<KRadio
v-model="usePartial"
card
card-orientation="horizontal"
data-testid="dedicated-redis-config-radio"
:description="t('redis.dedicated_configuration.description')"
:label="t('redis.dedicated_configuration.label')"
:selected-value="false"
/>
</div>
<div
v-if="usePartial"
class="shared-redis-config"
>
<RedisConfigSelect
:default-redis-config-item="selectedRedisConfigItem"
:plugin-redis-fields="field.fields"
:redis-type="field.redisType"
:update-redis-model="updateRedisModel"
@show-new-partial-modal="$emit('showNewPartialModal')"
/>
</div>
<div
v-else
class="dedicated-redis-config"
>
<div class="dedicated-redis-config-title">
{{ t('redis.dedicated_configuration.title') }}
</div>
<component
:is="tag"
>
<template
v-for="field in field.fields"
:key="field.model"
>
<form-group
v-if="fieldVisible(field)"
ref="children"
:errors="errors"
:field="field"
:model="model"
:options="options"
:vfg="vfg"
@model-updated="onModelUpdated"
@refresh-model="onRefreshModel"
@validated="onFieldValidated"
/>
</template>
</component>
</div>
</KCard>
</div>
</template>

<script setup lang="ts">
import { computed, onBeforeMount, ref, watch } from 'vue'
import formGroup from './FormGroup.vue'
import RedisConfigSelect from './RedisConfigSelect.vue'

import isFunction from 'lodash-es/isFunction'
import isNil from 'lodash-es/isNil'
import { createI18n } from '@kong-ui-public/i18n'
import english from '../locales/en.json'

const props = defineProps({
tag: {
type: String,
default: 'fieldset',
validator: function(value: string): boolean {
return value.length > 0
},
},
model: {
type: Object,
default: () => undefined,
},
options: {
type: Object,
required: true,
},
field: {
type: Object,
required: true,
},
vfg: {
type: Object,
required: true,
},
errors: {
type: Array,
default() {
return []
},
},
redisPath: {
type: String,
default: undefined,
required: false,
},
})

const emits = defineEmits<{
(e: 'modelUpdated', payload: any, schema: any): void,
(e: 'partialToggled', field: string, model: any): void,
(e: 'showNewPartialModal'): void,
(e: 'refreshModel'): void,
(e: 'validated', res: boolean, errors: any[], field: any): void,
}>()

const { t } = createI18n<typeof english>('en-us', english)

// if the plugin is custom, show redis configuration selector instead of the whole card
const isCustomPlugin = computed(() => props.field.pluginType === 'custom')
const usePartial = ref(false)
const selectedRedisConfigItem = ref()

const redisFieldsSaved = ref([] as { model: any; schema: any }[])
const partialsSaved = ref()

const fieldVisible = (field: any) => {
if (isFunction(field.visible)) return field.visible.call(this, props.model, field, this)

if (isNil(field.visible)) return true

return field.visible
}

const updateRedisModel = async (val: string | number | undefined) => {
emits('modelUpdated', [{ id: val, path: props.redisPath }], 'partials')
partialsSaved.value = [{ id: val, path: props.redisPath }]
selectedRedisConfigItem.value = val
}

const onModelUpdated = (model: any, schema: any) => {
redisFieldsSaved.value = { ...redisFieldsSaved.value, [schema]: model }
emits('modelUpdated', model, schema)
}

const onRefreshModel = () => {
// This is for updating a deeply nested array element
// See `modelUpdated` in `FieldArray.vue`
emits('refreshModel')
}

// Child field executed validation
const onFieldValidated = (res: boolean, errors: any[], field: any) => {
emits('validated', res, errors, field)
}

watch(() => usePartial.value, (usePartial) => {
if (usePartial) {
emits('partialToggled', 'redis', { 'partials': partialsSaved.value })
} else {
emits('partialToggled', 'partials', redisFieldsSaved.value)
}
})

// fetch available redis configs under the control plane
onBeforeMount(async () => {
redisFieldsSaved.value = props.field.fields.reduce((acc: Record<string,any>, field: { model: string }) => {
if (Object.keys(props.model!).includes(field.model)) {
acc[field.model] = props.model![field.model]
}
return acc
}, {})
if (props?.model?.partials?.[0]?.id) {
const selectedPartialId = props.model.partials[0].id
usePartial.value = true
selectedRedisConfigItem.value = selectedPartialId
}
})

</script>

<style lang="scss" scoped>
.redis-config-card {
margin-bottom: $kui-space-60;

:deep(.form-group:last-child) {
margin-bottom: 0;
}
}

.dedicated-redis-config {
margin-top: $kui-space-60;

.dedicated-redis-config-title {
font-size: $kui-font-size-40;
font-weight: $kui-font-weight-bold;
line-height: $kui-line-height-30;
margin-bottom: $kui-space-60;
}
}

.redis-config-radio-group {
display: flex;
gap: $kui-space-40;
margin-bottom: $kui-space-40;
}
</style>
Loading
Loading