-
Notifications
You must be signed in to change notification settings - Fork 2k
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
perf: optimization codemirror component #2451
Conversation
Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -212,6 +203,7 @@ function submitDialog(val: string) { | |||
const replyNodeFormRef = ref() | |||
const nodeCascaderRef = ref() | |||
const nodeCascaderRef2 = ref() | |||
|
|||
const validate = async () => { | |||
// console.log(replyNodeFormRef.value.validate()) | |||
let ps = [ |
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.
The provided code has several issues and improvements that can be made:
-
hide-required-asterisk
Property: This property was added to an incorrect context (require-asterisk-position="right"
is on ab-form-group
, but here it's being set on the outerel-form
). It should be removed since it doesn't have any effect in this scenario. -
Conditional Rendering of Variable Assignation Options:
- The custom variable input fields are wrapped inside two conditions that prevent rendering if
item.source === 'referring'
. However, when the user chooses'reference'
, they still need to see at least the placeholder and cascading selection widget, so remove these conditional renders.
<!-- Remove the below lines --> <!-- <div v-if="item.source === 'referring'" class="flex"> ... </div> --> <!-- <NodeCascader ref="nodeCascaderRef2" ... /> -->
- The custom variable input fields are wrapped inside two conditions that prevent rendering if
-
Custom Input Field Type Selection Logic:
- Set default values for different types to ensure proper behavior:
- For
"string"
, initialize with an empty string rather than null.<el-input v-model="item.value" :placeholder="$t('common.inputPlaceholder')" show-word-limit clearable @wheel="wheel"></el-input>
- For
"num"
, initialize with zero.<el-input-number v-model="item.value"></el-input-number>
- For
<!-- Ensure correct initialization before changing value --> item.type === "string" && (item.value = ""), item.type === "num" && (item.value = 0), item.type === "json" && (item.value = '{}'),
- Set default values for different types to ensure proper behavior:
-
Error Handling for Invalid JSON:
- Improve error handling for invalid JSON by providing more specific validation logic. Instead of always using
new Error
to indicate failure, handle parsing errors correctly based on the actual reason.
const isValidJSON = (val: string): boolean => { try { JSON.parse(val); return true; } catch (error) { console.error(`Invalid JSON format: ${error.message}`); return false; } };
- Improve error handling for invalid JSON by providing more specific validation logic. Instead of always using
-
Improve UX for Custom JSON Input:
- Allow users to quickly paste JSON into the field directly or provide copy-paste buttons if applicable.
<el-input v-model="item.value" type="textarea" autosize @paste="handlePaste" @focus="(val) => { focusedJsonInput = val }" @blur="resetFocusJsonInput()" ></el-input> <el-button @click="copyToJsonString()">Copy to String</el-button>
-
Add Event Listeners to Node Cascaders:
- Ensure all necessary event listeners such as
select
events are properly initialized when creating components.
// Initialize node cascade component after creating refs watch(() => form_data.variable_list, () => { nodeCascaderRef.value?.refresh(); // Re-initiate cascader when variable list changes });
- Ensure all necessary event listeners such as
-
Optimize Form Validation Execution:
- Run validation only when needed instead of always executing on blur like
v-blur
.
const validateField = async (fieldKey: string) => { await replyNodeFormRef.value.validate([fieldKey]); }; const addVariableListenerToInputs = () => { [...document.querySelectorAll('.el-form-item__input-wrap .el-input')] .filter(el => el instanceof HTMLElement) .forEach(inputEl => { inputEl.addEventListener('input', async () => { const key = Array.from( document .querySelectorAll<HTMLInputElement>( `.el-form-item[data-index="${indexOfItemInVariablesArray}"].el-form-item` ) ).map(inputWrapper => inputWrapper.querySelector(':scope > div:nth-child(2)'))[0] ?.getAttribute('data-key'); if (!key || !form_data[key]) { return; } await validateField(key); // Call validation only on change }); }); [...document.querySelectorAll('.el-form-item__content div:last-child .el-form']) .filter((wrapper: HTMLDivElement) => wrapper.children.length >= 19) .forEach(form => [".el-form", ".el-select-dropdown", ".el-date-picker"] && Array.from(form.childNodes).some(node => node.matches(".el-form")) ? form.addEventListener("scroll", () => requestAnimationFrame(validateField) ) : null ); };
- Run validation only when needed instead of always executing on blur like
These suggestions will help improve the readability and functionality of the Vue.js application while addressing common design principles.
right: 10px; | ||
} | ||
} | ||
</style> |
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.
The code you've provided appears clean and organized for use with Vue.js along with vue-codemirror
. It introduces several improvements over the original:
-
State Management Using
Computed
andWatch
: Thedata
property is now managed using both Computed properties (computed
) and Watchers to efficiently keep the codemirror value synced between props and internal states. -
Fullscreen Dialog Integration: A new El-dialog component (El-dialog's "full-screen" mode) has been added to display the same Codemirror instance in an overlay when triggered through a button click.
-
Data Cloning and Update Handling: In the fullscreen view, the current value of the CodeMirror editor is cloned into another variable (
cloneContent
). When editing stops, this content is then passed back via events to update the parent component. -
Enhanced Styling**: Added CSS to ensure that only the main container takes up the full width while maintaining readability within its boundaries.
While these changes make the implementation more flexible and interactive, remember it might be beneficial to thoroughly test all user flows involving the pop-up dialog to verify smooth working and proper error handling in case anything goes wrong during runtime.
position: relative; | ||
} | ||
</style> | ||
<style lang="scss"></style> |
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.
The code looks generally correct but has a few improvements that can be made:
- Remove the
append-to-body
attribute from the<el-dialog>
component. It's not necessary in this context. - Use CSS grid instead of flexbox to align the form items and buttons more cleanly.
- Add some padding to the
.mb-8
class to make it look better. - Consider adding validation error messages directly inside the input fields, as opposed to using separate message placeholders.
Here is updated version of the code with these improvements:
<style lang="scss">
.mb-8 {
margin-bottom: 1rem;
}
.field-item {
display: grid;
gap: 0.5rem;
& > .form-label-group {
width: 35%;
}
& > .form-input-group {
width: 65%;
}
}
</style>
... (rest of the template remains the same)
</template>
<script setup lang="ts">
...
</script>
What this PR does / why we need it?
Summary of your change
Please indicate you've done the following: