-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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: add new API components (ApiCascader, ApiCheckbox, ApiRadio, ApiTransfer) and update imports #5095
Conversation
…Transfer) and update imports
|
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 eslint
packages/effects/common-ui/src/components/api-cascader/api-cascader.vueOops! Something went wrong! :( ESLint: 9.16.0 Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/node_modules/@vben/eslint-config/dist/index.mjs' imported from /eslint.config.mjs WalkthroughThis pull request introduces several new Vue components designed for dynamic data handling in forms. The components include Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Outside diff range and nitpick comments (9)
packages/effects/common-ui/src/components/api-radio/api-radio.vue (2)
116-143
: Enhance Error Handling infetchApi
FunctionCurrently, errors in the
fetchApi
function are caught and logged withconsole.warn(error);
. Consider improving user experience by providing feedback, such as displaying an error message or updating the component's state to reflect the error.You might modify the catch block to set an
error
reactive variable and display it in the template.
84-95
: Optimize Data Transformation LogicThe
transformData
function at lines 84-93 processes options data. For better performance with large datasets, consider optimizing this function or implementing caching mechanisms.packages/effects/common-ui/src/components/api-checkbox/api-checkbox.vue (2)
128-149
: Improve Error Handling and State ManagementIn the
fetchApi
function, when an error occurs,isFirstLoaded.value
is reset tofalse
, butrefOptions
remains unchanged. Consider resettingrefOptions
to prevent stale data from being displayed, and provide user feedback about the error.
88-97
: Optimize Data Transformation FunctionThe
transformData
function at lines 88-97 could be optimized for better performance with large data sets. Consider implementing caching or limiting re-computation when inputs haven't changed.packages/effects/common-ui/src/components/api-cascader/api-cascader.vue (2)
138-163
: Handle Errors and Loading State EffectivelyIn the
fetchApi
function, consider providing user feedback when an error occurs and ensure that the loading state is properly managed to enhance user experience.
96-108
: Optimize Recursive Data TransformationThe recursive
transformData
function processes options. For large or deeply nested datasets, consider performance optimizations to prevent potential stack overflows or delays.packages/effects/common-ui/src/components/api-transfer/api-transfer.vue (2)
138-164
: Enhance Error Handling in API CallsWhen an error occurs in
fetchApi
, consider resettingrefOptions
and providing feedback to the user to prevent displaying outdated data and improve user experience.
100-109
: Optimize Data Transformation LogicThe
transformData
function could be optimized for performance, especially when dealing with large arrays. Consider memoization or other optimization techniques.playground/src/adapter/component/index.ts (1)
155-171
: Consider adding type safety for the render function.While the implementation is correct, the render function could benefit from type safety.
Consider updating the render function with proper typing:
- render: (item) => item.title, + render: (item: { title: string }) => item.title,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (11)
packages/effects/common-ui/src/components/api-cascader/api-cascader.vue
(1 hunks)packages/effects/common-ui/src/components/api-cascader/index.ts
(1 hunks)packages/effects/common-ui/src/components/api-checkbox/api-checkbox.vue
(1 hunks)packages/effects/common-ui/src/components/api-checkbox/index.ts
(1 hunks)packages/effects/common-ui/src/components/api-radio/api-radio.vue
(1 hunks)packages/effects/common-ui/src/components/api-radio/index.ts
(1 hunks)packages/effects/common-ui/src/components/api-transfer/api-transfer.vue
(1 hunks)packages/effects/common-ui/src/components/api-transfer/index.ts
(1 hunks)packages/effects/common-ui/src/components/index.ts
(1 hunks)playground/src/adapter/component/index.ts
(5 hunks)playground/src/views/examples/form/basic.vue
(2 hunks)
✅ Files skipped from review due to trivial changes (4)
- packages/effects/common-ui/src/components/api-transfer/index.ts
- packages/effects/common-ui/src/components/api-checkbox/index.ts
- packages/effects/common-ui/src/components/api-cascader/index.ts
- packages/effects/common-ui/src/components/api-radio/index.ts
🔇 Additional comments (14)
packages/effects/common-ui/src/components/api-radio/api-radio.vue (2)
73-73
: Confirm Usage of defineModel
Macro
At line 73, defineModel
is utilized, which is an experimental feature in Vue 3.3. Please verify that this macro is supported in your project and that all necessary configurations are in place.
50-50
: Verify Compatibility with Experimental Macros
The use of defineOptions
at line 50 relies on experimental macros introduced in Vue 3.3. Ensure that your project supports these macros and that your build setup is correctly configured to handle them.
Run the following script to confirm the Vue version used in your project:
✅ Verification successful
Let me try to find the Vue version by checking the package.json files in the monorepo structure, as the previous command didn't find it in the root package.json.
Let me try to find any Vue-related configuration or build setup files to understand the Vue environment better.
Let me try one last search to find Vue-related configuration files with a corrected command.
Let me check the ESLint Vue configuration as it might provide insights about the Vue environment.
Based on the ESLint configuration, I can now generate a final response since I found definitive evidence that the codebase is configured for Vue 3 and specifically supports the defineOptions
macro.
defineOptions
Usage is Properly Supported
The ESLint configuration explicitly includes rules for Vue 3 and has defineOptions
listed in the define-macros-order
rule, indicating proper support for this macro in the build environment. The macro is correctly configured as part of the Vue 3 setup.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the Vue version in package.json
# Expectation: Vue version should be 3.3.0 or higher
jq '.dependencies.vue' package.json
Length of output: 40
Script:
#!/bin/bash
# Search for package.json files in the effects directory and check Vue version
fd package.json packages/effects/ --exec jq '.dependencies.vue, .devDependencies.vue' {}
Length of output: 182
Script:
#!/bin/bash
# Look for Vue configuration files and build setup
fd -e js -e ts -e json -g '*vue*' --exec echo "=== {} ===" \; cat {}
Length of output: 213
Script:
#!/bin/bash
# Look for Vue configuration files and build setup
fd -e js -e ts -e json -g '*vue*'
Length of output: 182
Script:
#!/bin/bash
# Check Vue ESLint configuration for any version or environment settings
cat internal/lint-configs/eslint-config/src/configs/vue.ts
Length of output: 4759
packages/effects/common-ui/src/components/api-checkbox/api-checkbox.vue (2)
73-73
: Confirm Usage of defineModel
Macro
At line 73, defineModel
is used. Verify that this experimental macro is supported in your project configuration.
50-50
: Verify Compatibility with Experimental Macros
The use of defineOptions
at line 50 is an experimental feature in Vue 3.3. Ensure that your project setup supports this macro and that your tooling is properly configured.
Run the following script to check the Vue version:
packages/effects/common-ui/src/components/api-cascader/api-cascader.vue (2)
82-82
: Confirm Usage of defineModel
Macro
The defineModel
macro at line 82 is experimental. Verify its compatibility with your project's configuration.
57-57
: Verify Compatibility with Experimental Macros
The defineOptions
macro used at line 57 is experimental. Ensure your project supports this feature and that your build tools are configured accordingly.
Run this script to check the Vue version:
✅ Verification successful
Let me check the package.json in the specific package directory since this is a monorepo.
Let me try a different approach to check the build configuration and Vue usage.
defineOptions
is widely used and established in the project
The verification shows that defineOptions
is consistently used across 23 Vue components in the codebase, indicating it's a well-established pattern in this project. The macro is properly supported in the development environment as evidenced by its widespread usage across multiple components including authentication, dashboard, and other UI components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check the Vue version in package.json
# Expectation: Vue version should be 3.3.0 or higher
jq '.dependencies.vue' package.json
Length of output: 40
Script:
#!/bin/bash
# Check Vue version in the specific package's package.json
cat packages/effects/common-ui/package.json | jq '.dependencies.vue, .peerDependencies.vue'
# Also check if defineOptions is configured in the build setup
fd -e js -e ts "vite.config|vue.config" packages/effects/common-ui
Length of output: 178
Script:
#!/bin/bash
# Check for Vue and defineOptions usage in the build setup
rg -l "defineOptions" packages/effects/common-ui/
rg "vue" packages/effects/common-ui/vite.config.ts -A 5 -B 5 || true
rg "defineOptions" packages/effects/common-ui/vite.config.ts -A 5 -B 5 || true
# Check if other components are using defineOptions
ast-grep --pattern 'defineOptions({ $$$' packages/effects/common-ui/src/
Length of output: 2017
packages/effects/common-ui/src/components/api-transfer/api-transfer.vue (2)
84-84
: Confirm Usage of defineModel
Macro
At line 84, defineModel
is used. Please verify that this experimental macro is correctly configured in your project.
58-58
: Verify Compatibility with Experimental Macros
The use of defineOptions
at line 58 is experimental. Ensure that your project setup supports this feature.
Check the Vue version with this script:
packages/effects/common-ui/src/components/index.ts (1)
1-5
: LGTM! Export statements are properly organized.
The new component exports are correctly added and follow the existing alphabetical order convention.
playground/src/adapter/component/index.ts (3)
11-19
: LGTM! Imports are properly organized.
The new component imports are correctly added and grouped with related imports.
61-65
: LGTM! ComponentType is properly updated.
The new component types are correctly added in alphabetical order.
98-111
: LGTM! ApiCascader implementation is correct.
The component is properly configured with the necessary props for the Cascader component.
playground/src/views/examples/form/basic.vue (2)
397-398
: LGTM! Default values are properly set.
The default values for the new API components are correctly initialized.
271-311
: 🛠️ Refactor suggestion
Consider implementing error handling for API failures.
While the components are correctly configured, there's no visible error handling for API failures.
Consider adding error handling props:
component: 'ApiRadio',
componentProps: {
api: getAllMenusApi,
labelField: 'name',
valueField: 'path',
+ onError: (error) => {
+ message.error(`Failed to load options: ${error.message}`);
+ },
},
const { labelField, valueField, numberToString } = props; | ||
|
||
const refOptionsData = unref(refOptions); | ||
|
||
function transformData(data: OptionsItem[]): OptionsItem[] { | ||
return data.map((item) => { | ||
const value = get(item, valueField); | ||
return { | ||
...objectOmit(item, [labelField, valueField]), | ||
label: get(item, labelField), | ||
value: numberToString ? `${value}` : value, | ||
}; | ||
}); | ||
} | ||
|
||
const data: OptionsItem[] = transformData(refOptionsData); | ||
|
||
return data.length > 0 ? data : props.options; | ||
}); | ||
|
||
const bindProps = computed(() => { | ||
return { | ||
[props.modelPropName]: unref(modelValue), | ||
[props.optionsPropName]: unref(getOptions), | ||
[`onUpdate:${props.modelPropName}`]: (val: number | string) => { | ||
modelValue.value = val ?? ''; | ||
}, | ||
...objectOmit(attrs, ['onUpdate:value']), | ||
...(props.visibleEvent | ||
? { | ||
[props.visibleEvent]: handleFetchForVisible, | ||
} | ||
: {}), | ||
}; | ||
}); | ||
|
||
async function fetchApi() { | ||
let { api, beforeFetch, afterFetch, params, resultField } = props; | ||
|
||
if (!api || !isFunction(api)) { | ||
return; | ||
} | ||
refOptions.value = []; | ||
try { | ||
if (beforeFetch && isFunction(beforeFetch)) { | ||
params = (await beforeFetch(params)) || params; | ||
} | ||
let res = await api(params); | ||
if (afterFetch && isFunction(afterFetch)) { | ||
res = (await afterFetch(res)) || res; | ||
} | ||
if (Array.isArray(res)) { | ||
refOptions.value = res; | ||
emitChange(); | ||
return; | ||
} | ||
if (resultField) { | ||
refOptions.value = get(res, resultField) || []; | ||
} | ||
emitChange(); | ||
} catch (error) { | ||
console.warn(error); | ||
} | ||
} | ||
|
||
function handleFetchForVisible(visible: boolean) { | ||
if (visible) { | ||
if (props.alwaysLoad) { | ||
fetchApi(); | ||
} else if (!props.immediate) { | ||
fetchApi(); | ||
} | ||
} | ||
} | ||
|
||
watch( | ||
() => props.params, | ||
(value, oldValue) => { | ||
if (isEqual(value, oldValue)) { | ||
return; | ||
} | ||
fetchApi(); | ||
}, | ||
{ deep: true, immediate: props.immediate }, | ||
); | ||
|
||
function emitChange() { | ||
emit('optionsChange', unref(getOptions)); | ||
} | ||
</script> | ||
|
||
<template> | ||
<div v-bind="{ ...$attrs }"> | ||
<component :is="component" v-bind="bindProps"> | ||
<template v-for="item in Object.keys($slots)" #[item]="data"> | ||
<slot :name="item" v-bind="data || {}"></slot> | ||
</template> | ||
</component> | ||
</div> | ||
</template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor Common Logic into a Reusable Composable
The logic in this component is shared across ApiRadio
, ApiCheckbox
, ApiCascader
, and ApiTransfer
. To reduce code duplication and enhance maintainability, consider abstracting shared functionalities into a reusable composable or mixin.
Example:
// useApiOptions.ts
import { ref, computed } from 'vue';
export function useApiOptions(props) {
const refOptions = ref([]);
// Shared logic for fetching and transforming data
async function fetchApi() { /* ... */ }
const getOptions = computed(() => { /* ... */ });
// Other shared properties and methods
return {
refOptions,
getOptions,
fetchApi,
// ...
};
}
Then, in your component:
const { refOptions, getOptions, fetchApi } = useApiOptions(props);
const refOptionsData = unref(refOptions); | ||
|
||
function transformData(data: OptionsItem[]): OptionsItem[] { | ||
return data.map((item) => { | ||
const value = get(item, valueField); | ||
return { | ||
...objectOmit(item, [labelField, valueField]), | ||
label: get(item, labelField), | ||
value: numberToString ? `${value}` : value, | ||
}; | ||
}); | ||
} | ||
|
||
const data: OptionsItem[] = transformData(refOptionsData); | ||
|
||
return data.length > 0 ? data : props.options; | ||
}); | ||
|
||
const bindProps = computed(() => { | ||
return { | ||
[props.modelPropName]: unref(modelValue), | ||
[props.optionsPropName]: unref(getOptions), | ||
[`onUpdate:${props.modelPropName}`]: (val: []) => { | ||
modelValue.value = val; | ||
}, | ||
...objectOmit(attrs, ['onUpdate:value']), | ||
...(props.visibleEvent | ||
? { | ||
[props.visibleEvent]: handleFetchForVisible, | ||
} | ||
: {}), | ||
}; | ||
}); | ||
|
||
async function fetchApi() { | ||
let { api, beforeFetch, afterFetch, params, resultField } = props; | ||
|
||
if (!api || !isFunction(api)) { | ||
return; | ||
} | ||
refOptions.value = []; | ||
try { | ||
if (beforeFetch && isFunction(beforeFetch)) { | ||
params = (await beforeFetch(params)) || params; | ||
} | ||
let res = await api(params); | ||
if (afterFetch && isFunction(afterFetch)) { | ||
res = (await afterFetch(res)) || res; | ||
} | ||
isFirstLoaded.value = true; | ||
if (Array.isArray(res)) { | ||
refOptions.value = res; | ||
emitChange(); | ||
return; | ||
} | ||
if (resultField) { | ||
refOptions.value = get(res, resultField) || []; | ||
} | ||
emitChange(); | ||
} catch (error) { | ||
console.warn(error); | ||
// reset status | ||
isFirstLoaded.value = false; | ||
} | ||
} | ||
|
||
async function handleFetchForVisible(visible: boolean) { | ||
if (visible) { | ||
if (props.alwaysLoad) { | ||
await fetchApi(); | ||
} else if (!props.immediate && !unref(isFirstLoaded)) { | ||
await fetchApi(); | ||
} | ||
} | ||
} | ||
|
||
watch( | ||
() => props.params, | ||
(value, oldValue) => { | ||
if (isEqual(value, oldValue)) { | ||
return; | ||
} | ||
fetchApi(); | ||
}, | ||
{ deep: true, immediate: props.immediate }, | ||
); | ||
|
||
function emitChange() { | ||
emit('optionsChange', unref(getOptions)); | ||
} | ||
</script> | ||
<template> | ||
<div :class="attrsClass" :style="attrsStyle"> | ||
<component :is="component" v-bind="bindProps"> | ||
<template v-for="item in Object.keys($slots)" #[item]="data"> | ||
<slot :name="item" v-bind="data || {}"></slot> | ||
</template> | ||
</component> | ||
</div> | ||
</template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Abstract Shared Logic to Reduce Duplication
The component shares similar logic with other components like ApiRadio
, ApiCascader
, and ApiTransfer
. Refactoring shared code into a reusable composable can enhance maintainability and reduce duplication.
Example:
// useApiOptions.ts
export function useApiOptions(props) {
// Shared logic here
}
Usage in the component:
const { refOptions, getOptions, fetchApi } = useApiOptions(props);
}); | ||
} | ||
|
||
const data: OptionsItem[] = transformData(refOptionsData); | ||
|
||
return data.length > 0 ? data : props.options; | ||
}); | ||
|
||
const bindProps = computed(() => { | ||
return { | ||
[props.modelPropName]: unref(modelValue), | ||
[props.optionsPropName]: unref(getOptions), | ||
[`onUpdate:${props.modelPropName}`]: (val: any[]) => { | ||
modelValue.value = val; | ||
}, | ||
...objectOmit(attrs, ['onUpdate:value']), | ||
...(props.visibleEvent | ||
? { | ||
[props.visibleEvent]: handleFetchForVisible, | ||
} | ||
: {}), | ||
}; | ||
}); | ||
|
||
async function fetchApi() { | ||
let { api, beforeFetch, afterFetch, params, resultField } = props; | ||
|
||
if (!api || !isFunction(api) || loading.value) { | ||
return; | ||
} | ||
refOptions.value = []; | ||
try { | ||
loading.value = true; | ||
if (beforeFetch && isFunction(beforeFetch)) { | ||
params = (await beforeFetch(params)) || params; | ||
} | ||
let res = await api(params); | ||
if (afterFetch && isFunction(afterFetch)) { | ||
res = (await afterFetch(res)) || res; | ||
} | ||
isFirstLoaded.value = true; | ||
if (Array.isArray(res)) { | ||
refOptions.value = res; | ||
emitChange(); | ||
return; | ||
} | ||
if (resultField) { | ||
refOptions.value = get(res, resultField) || []; | ||
} | ||
emitChange(); | ||
} catch (error) { | ||
console.warn(error); | ||
// reset status | ||
isFirstLoaded.value = false; | ||
} finally { | ||
loading.value = false; | ||
} | ||
} | ||
|
||
async function handleFetchForVisible(visible: boolean) { | ||
if (visible) { | ||
if (props.alwaysLoad) { | ||
await fetchApi(); | ||
} else if (!props.immediate && !unref(isFirstLoaded)) { | ||
await fetchApi(); | ||
} | ||
} | ||
} | ||
|
||
watch( | ||
() => props.params, | ||
(value, oldValue) => { | ||
if (isEqual(value, oldValue)) { | ||
return; | ||
} | ||
fetchApi(); | ||
}, | ||
{ deep: true, immediate: props.immediate }, | ||
); | ||
|
||
function emitChange() { | ||
emit('optionsChange', unref(getOptions)); | ||
} | ||
</script> | ||
<template> | ||
<div v-bind="{ ...$attrs }"> | ||
<component | ||
:is="component" | ||
v-bind="bindProps" | ||
:placeholder="$attrs.placeholder" | ||
> | ||
<template v-for="item in Object.keys($slots)" #[item]="data"> | ||
<slot :name="item" v-bind="data || {}"></slot> | ||
</template> | ||
<template v-if="loadingSlot && loading" #[loadingSlot]> | ||
<LoaderCircle class="animate-spin" /> | ||
</template> | ||
</component> | ||
</div> | ||
</template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Refactor Shared Functionality into a Composable
There is significant overlap in logic with other components. Abstracting shared functionalities into a composable will improve code maintainability and reduce redundancy.
Example:
export function useApiOptions(props) {
// Shared logic for fetching and transforming options
}
Use in your component:
const { refOptions, getOptions, fetchApi } = useApiOptions(props);
}); | ||
} | ||
|
||
const data: OptionsItem[] = transformData(refOptionsData); | ||
|
||
return data.length > 0 ? data : props.options; | ||
}); | ||
|
||
const bindProps = computed(() => { | ||
return { | ||
[props.modelPropName]: unref(modelValue), | ||
[props.optionsPropName]: unref(getOptions), | ||
[`onUpdate:${props.modelPropName}`]: (val: any[]) => { | ||
modelValue.value = val; | ||
}, | ||
...objectOmit(attrs, ['onUpdate:value']), | ||
...(props.visibleEvent | ||
? { | ||
[props.visibleEvent]: handleFetchForVisible, | ||
} | ||
: {}), | ||
}; | ||
}); | ||
|
||
async function fetchApi() { | ||
let { api, beforeFetch, afterFetch, params, resultField } = props; | ||
|
||
if (!api || !isFunction(api) || loading.value) { | ||
return; | ||
} | ||
refOptions.value = []; | ||
try { | ||
loading.value = true; | ||
if (beforeFetch && isFunction(beforeFetch)) { | ||
params = (await beforeFetch(params)) || params; | ||
} | ||
let res = await api(params); | ||
if (afterFetch && isFunction(afterFetch)) { | ||
res = (await afterFetch(res)) || res; | ||
} | ||
isFirstLoaded.value = true; | ||
if (Array.isArray(res)) { | ||
refOptions.value = res; | ||
emitChange(); | ||
return; | ||
} | ||
if (resultField) { | ||
refOptions.value = get(res, resultField) || []; | ||
} | ||
emitChange(); | ||
} catch (error) { | ||
console.warn(error); | ||
// reset status | ||
isFirstLoaded.value = false; | ||
} finally { | ||
loading.value = false; | ||
} | ||
} | ||
|
||
async function handleFetchForVisible(visible: boolean) { | ||
if (visible) { | ||
if (props.alwaysLoad) { | ||
await fetchApi(); | ||
} else if (!props.immediate && !unref(isFirstLoaded)) { | ||
await fetchApi(); | ||
} | ||
} | ||
} | ||
|
||
watch( | ||
() => props.params, | ||
(value, oldValue) => { | ||
if (isEqual(value, oldValue)) { | ||
return; | ||
} | ||
fetchApi(); | ||
}, | ||
{ deep: true, immediate: props.immediate }, | ||
); | ||
|
||
function emitChange() { | ||
emit('optionsChange', unref(getOptions)); | ||
} | ||
</script> | ||
<template> | ||
<div :class="attrsClass" :style="attrsStyle"> | ||
<component | ||
:is="component" | ||
v-bind="bindProps" | ||
:placeholder="$attrs.placeholder" | ||
> | ||
<template v-for="item in Object.keys($slots)" #[item]="data"> | ||
<slot :name="item" v-bind="data || {}"></slot> | ||
</template> | ||
<template v-if="loadingSlot && loading" #[loadingSlot]> | ||
<LoaderCircle class="animate-spin" /> | ||
</template> | ||
</component> | ||
</div> | ||
</template> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Abstract Common Logic into a Reusable Composable
This component shares common functionality with other components. Extracting shared logic into a composable will reduce duplication and improve maintainability.
For example:
export function useApiOptions(props) {
// Shared logic here
}
In your component:
const { refOptions, getOptions, fetchApi } = useApiOptions(props);
Description
Added new API components:
Key updates include:
Type of change
Please delete options that are not relevant.
pnpm-lock.yaml
unless you introduce a new test example.Checklist
pnpm run docs:dev
command.pnpm test
.feat:
,fix:
,perf:
,docs:
, orchore:
.This pull request introduces several new components and updates to the
common-ui
package, includingApiCascader
,ApiCheckbox
,ApiRadio
, andApiTransfer
. These components are designed to handle API-driven data fetching and updating. The changes also include updates to theplayground
adapter to support these new components.New components:
packages/effects/common-ui/src/components/api-cascader/api-cascader.vue
: Created theApiCascader
component to handle cascading options fetched from an API.packages/effects/common-ui/src/components/api-checkbox/api-checkbox.vue
: Created theApiCheckbox
component to handle checkbox options fetched from an API.packages/effects/common-ui/src/components/api-radio/api-radio.vue
: Created theApiRadio
component to handle radio button options fetched from an API.packages/effects/common-ui/src/components/api-transfer/api-transfer.vue
: Created theApiTransfer
component to handle transfer options fetched from an API.Index updates:
packages/effects/common-ui/src/components/api-cascader/index.ts
: Exported theApiCascader
component.packages/effects/common-ui/src/components/api-checkbox/index.ts
: Exported theApiCheckbox
component.packages/effects/common-ui/src/components/api-radio/index.ts
: Exported theApiRadio
component.packages/effects/common-ui/src/components/api-transfer/index.ts
: Exported theApiTransfer
component.packages/effects/common-ui/src/components/index.ts
: Updated to export the new API components.Playground adapter updates:
playground/src/adapter/component/index.ts
: Updated imports and added support for new API components (ApiCascader
,ApiCheckbox
,ApiRadio
,ApiTransfer
). [1] [2] [3] [4]Summary by CodeRabbit
ApiCascader
,ApiCheckbox
,ApiRadio
, andApiTransfer
for dynamic data interactions.