-
Notifications
You must be signed in to change notification settings - Fork 2.8k
refactor: Password input constractor #2430
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,194 @@ | ||
| <template> | ||
| <el-form-item :label="$t('dynamicsForm.TextInput.length.label')" required> | ||
| <el-row class="w-full"> | ||
| <el-col :span="11"> | ||
| <el-form-item | ||
| :rules="[ | ||
| { | ||
| required: true, | ||
| message: $t('dynamicsForm.TextInput.length.minRequired'), | ||
| trigger: 'change' | ||
| } | ||
| ]" | ||
| prop="minlength" | ||
| > | ||
| <el-input-number | ||
| style="width: 100%" | ||
| :min="1" | ||
| :step="1" | ||
| step-strictly | ||
| v-model="formValue.minlength" | ||
| controls-position="right" | ||
| /> | ||
| </el-form-item> | ||
| </el-col> | ||
| <el-col :span="2" class="text-center"> | ||
| <span>-</span> | ||
| </el-col> | ||
| <el-col :span="11"> | ||
| <el-form-item | ||
| :rules="[ | ||
| { | ||
| required: true, | ||
| message: $t('dynamicsForm.TextInput.length.maxRequired'), | ||
| trigger: 'change' | ||
| } | ||
| ]" | ||
| prop="maxlength" | ||
| > | ||
| <el-input-number | ||
| style="width: 100%" | ||
| :min="formValue.minlength > formValue.maxlength ? formValue.minlength : 1" | ||
| step-strictly | ||
| :step="1" | ||
| v-model="formValue.maxlength" | ||
| controls-position="right" | ||
| /> | ||
| </el-form-item> | ||
| </el-col> | ||
| </el-row> | ||
| </el-form-item> | ||
|
|
||
| <el-form-item | ||
| class="defaultValueItem" | ||
| :required="formValue.required" | ||
| prop="default_value" | ||
| :label="$t('dynamicsForm.default.label')" | ||
| :rules=" | ||
| formValue.required ? [{ required: true, message: `${$t('dynamicsForm.default.label')}${$t('dynamicsForm.default.requiredMessage')}` }, ...rules] : rules | ||
| " | ||
| > | ||
| <div class="defaultValueCheckbox"> | ||
| <el-checkbox | ||
| v-model="formValue.show_default_value" | ||
| :label="$t('dynamicsForm.default.show')" | ||
| /> | ||
| </div> | ||
|
|
||
| <el-input | ||
| v-model="formValue.default_value" | ||
| :maxlength="formValue.maxlength" | ||
| :minlength="formValue.minlength" | ||
| :placeholder="$t('dynamicsForm.default.placeholder')" | ||
| show-word-limit | ||
| type="password" | ||
| show-password | ||
| /> | ||
| </el-form-item> | ||
| </template> | ||
| <script setup lang="ts"> | ||
| import { computed, onMounted, watch } from 'vue' | ||
| import { t } from '@/locales' | ||
|
|
||
| const props = defineProps<{ | ||
| modelValue: any | ||
| }>() | ||
| const emit = defineEmits(['update:modelValue']) | ||
| const formValue = computed({ | ||
| set: (item) => { | ||
| emit('update:modelValue', item) | ||
| }, | ||
| get: () => { | ||
| return props.modelValue | ||
| } | ||
| }) | ||
| watch( | ||
| () => formValue.value.minlength, | ||
| () => { | ||
| if (formValue.value.minlength > formValue.value.maxlength) { | ||
| formValue.value.maxlength = formValue.value.minlength | ||
| } | ||
| } | ||
| ) | ||
| const getData = () => { | ||
| return { | ||
| input_type: 'PasswordInput', | ||
| attrs: { | ||
| maxlength: formValue.value.maxlength, | ||
| minlength: formValue.value.minlength, | ||
| 'show-word-limit': true, | ||
| type: 'password', | ||
| 'show-password': true | ||
| }, | ||
| default_value: formValue.value.default_value, | ||
| show_default_value: formValue.value.show_default_value, | ||
| props_info: { | ||
| rules: formValue.value.required | ||
| ? [ | ||
| { | ||
| required: true, | ||
| message: `${formValue.value.label} ${t('dynamicsForm.default.requiredMessage')}` | ||
| }, | ||
| { | ||
| min: formValue.value.minlength, | ||
| max: formValue.value.maxlength, | ||
| message: `${formValue.value.label}${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`, | ||
| trigger: 'blur' | ||
| } | ||
| ] | ||
| : [ | ||
| { | ||
| min: formValue.value.minlength, | ||
| max: formValue.value.maxlength, | ||
| message: `${formValue.value.label}${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`, | ||
| trigger: 'blur' | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| const rander = (form_data: any) => { | ||
| const attrs = form_data.attrs || {} | ||
| formValue.value.minlength = attrs.minlength | ||
| formValue.value.maxlength = attrs.maxlength | ||
| formValue.value.default_value = form_data.default_value | ||
| formValue.value.show_default_value = form_data.show_default_value | ||
| formValue.value.show_password = attrs['show-password'] | ||
| } | ||
| const rangeRules = [ | ||
| { | ||
| required: true, | ||
| validator: (rule: any, value: any, callback: any) => { | ||
| if (!formValue.value.minlength) { | ||
| callback(new Error(t('dynamicsForm.TextInput.length.requiredMessage4'))) | ||
| } | ||
| if (!formValue.value.maxlength) { | ||
| callback(new Error(t('dynamicsForm.TextInput.length.requiredMessage4'))) | ||
| } | ||
| return true | ||
| }, | ||
| message: `${formValue.value.label} ${t('dynamicsForm.default.requiredMessage')}` | ||
| } | ||
| ] | ||
| const rules = computed(() => [ | ||
| { | ||
| min: formValue.value.minlength, | ||
| max: formValue.value.maxlength, | ||
| message: `${t('dynamicsForm.TextInput.length.requiredMessage1')} ${formValue.value.minlength} ${t('dynamicsForm.TextInput.length.requiredMessage2')} ${formValue.value.maxlength} ${t('dynamicsForm.TextInput.length.requiredMessage3')}`, | ||
| trigger: 'blur' | ||
| } | ||
| ]) | ||
|
|
||
| defineExpose({ getData, rander }) | ||
| onMounted(() => { | ||
| formValue.value.minlength = 0 | ||
| formValue.value.maxlength = 20 | ||
| formValue.value.default_value = '' | ||
| formValue.value.show_password = true | ||
|
|
||
| if (formValue.value.show_default_value === undefined) { | ||
| formValue.value.show_default_value = true | ||
| } | ||
| }) | ||
| </script> | ||
| <style lang="scss" scoped> | ||
| .defaultValueItem { | ||
| position: relative; | ||
|
|
||
| .defaultValueCheckbox { | ||
| position: absolute; | ||
| right: 0; | ||
| top: -35px; | ||
| } | ||
| } | ||
| </style> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,4 @@ | ||
| <template> | ||
| <el-form-item | ||
| class="defaultValueItem" | ||
| prop="show_password" | ||
| :label="$t('dynamicsForm.TextInput.showPassword')" | ||
| > | ||
| <el-switch v-model="formValue.show_password" /> | ||
| </el-form-item> | ||
| <el-form-item :label="$t('dynamicsForm.TextInput.length.label')" required> | ||
| <el-row class="w-full"> | ||
| <el-col :span="11"> | ||
|
|
@@ -77,8 +70,7 @@ | |
| :minlength="formValue.minlength" | ||
| :placeholder="$t('dynamicsForm.default.placeholder')" | ||
| show-word-limit | ||
| :type="formValue.show_password ? 'password' : 'text'" | ||
| :show-password="formValue.show_password" | ||
| type="text" | ||
| /> | ||
| </el-form-item> | ||
| </template> | ||
|
|
@@ -111,9 +103,7 @@ const getData = () => { | |
| attrs: { | ||
| maxlength: formValue.value.maxlength, | ||
| minlength: formValue.value.minlength, | ||
| 'show-word-limit': true, | ||
| type: formValue.value.show_password ? 'password' : 'text', | ||
| 'show-password': formValue.value.show_password | ||
| 'show-word-limit': true | ||
| }, | ||
| default_value: formValue.value.default_value, | ||
| show_default_value: formValue.value.show_default_value, | ||
|
|
@@ -145,7 +135,6 @@ const rander = (form_data: any) => { | |
| formValue.value.maxlength = attrs.maxlength | ||
| formValue.value.default_value = form_data.default_value | ||
| formValue.value.show_default_value = form_data.show_default_value | ||
| formValue.value.show_password = attrs['show-password'] | ||
| } | ||
| const rangeRules = [ | ||
| { | ||
|
|
@@ -176,8 +165,7 @@ onMounted(() => { | |
| formValue.value.minlength = 0 | ||
| formValue.value.maxlength = 20 | ||
| formValue.value.default_value = '' | ||
| formValue.value.show_password = false | ||
|
|
||
| // console.log(formValue.value.show_default_value) | ||
| if (formValue.value.show_default_value === undefined) { | ||
| formValue.value.show_default_value = true | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are several issues and improvements that can be made to this Vue.js template and JavaScript code:
Here's a revised version of the code: <template>
<el-form-item :label="$t('dynamicsForm.TextInput.length.label')" required>
<el-row class="w-full">
<el-col :span="11">
<el-input-number v-model.number="value.maxlength" placeholder="Enter max length" />
</el-col>
<el-col :span="11">
<el-input-number v-model.number="value.minlength" placeholder="Enter min length" />
</el-col>
</el-row>
<el-form-item :label="$t('dynamicsForm.TextInput.text.type')">Text Type</el-form-item>
<el-radio-group v-model:value.type>
<el-radio-button label="text">Text Input</el-radio-button>
<el-radio-button label="password">Password Input</el-radio-button>
</el-radio-group>
<el-form-item :label="$t('dynamicsForm.TextInput.placeholder')">Placeholder</el-form-item>
<el-input v-model:value.placeholder />
<el-form-item :label="$t('dynamicsForm.TextInput.default')">
Default Value <em>(Optional)</em></el-form-item>
<el-input v-model:value.default-value />
</el-form-item>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
// Assume formValue is defined somewhere and imported
export default defineComponent({
data() {
return {
value: {
maxlen: null,
minlength: null,
type: 'text',
placeholder: '',
default_value: '',
show_default_value: true,
},
};
},
});
</script>In this improved version:
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,9 @@ | |
| <el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">{{ | ||
| $t('dynamicsForm.input_type_list.TextInput') | ||
| }}</el-tag> | ||
| <el-tag type="info" class="info-tag" v-if="row.input_type === 'PasswordInput'">{{ | ||
| $t('dynamicsForm.input_type_list.PasswordInput') | ||
| }}</el-tag> | ||
| <el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">{{ | ||
| $t('dynamicsForm.input_type_list.Slider') | ||
| }}</el-tag> | ||
|
|
@@ -169,6 +172,9 @@ function refreshFieldTitle(data: any) { | |
| } | ||
|
|
||
| const getDefaultValue = (row: any) => { | ||
| if(row.input_type === 'PasswordInput') { | ||
| return '******' | ||
| } | ||
| if (row.default_value) { | ||
| const default_value = row.option_list | ||
| ?.filter((v: any) => row.default_value.indexOf(v.value) > -1) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are no immediate issues with the provided code snippet. It appears to be correct in terms of syntax and structure, though there's an empty Here is the updated version with potential improvements suggested: // Function to check input types and display corresponding tags
function handleInputTypeTags(row) {
switch (row.input_type) {
case 'TextInput':
return <el-tag type="info" class="info-tag">{{ $t('dynamicsForm.input_type_list.TextInput') }}</el-tag>;
case 'PasswordInput':
return (
<>
<el-tag type="info" class="info-tag">
{{ $t('dynamicsForm.input_type_list.PasswordInput') }}
</el-tag>
{/* Show the password field placeholder here */}
</>
);
case 'Slider':
return <el-tag type="info" class="info-tag">{{ $t('dynamicsForm.input_type_list.Slider') }}</el-tag>;
default:
// Handle other cases if needed
break;
}
}
// Update the refreshFieldTitle function usage
const refreshFieldTitle = (data) => {
// Use a loop to process each element in data array using handleInputTypeTags
};
// Updated getDefaultValue function handling PasswordInput
const getDefaultValue = (row) => {
if (row.default_value && row.option_list) {
const filteredValues = row.option_list.filter((v) =>
row.default_value.includes(v.value)
);
if (filteredValues.length > 0) {
return filteredValues[0].value; // Return the first available value from option_list
} else {
return 'No matching values found';
}
}
};Optimization Suggestions:
These changes make the code cleaner and more functional while keeping performance considerations in mind where necessary. |
||
|
|
||
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 mostly well-formed, but there are a few areas that could be optimized or corrected:
HTML Structure: The HTML structure is correct and semantically appropriate.
TypeScript Setup: The
setupfunction in Vue 3 uses TypeScript correctly withdefineProperties,defineEmits,computed,watch, etc.Computed Properties and Watches: The computed properties (
formValue) and watches are functioning as expected to handle updates.Data Methods:
getData: This method correctly returns an object containing the form data.rander: This method updates the form values based on incoming form data.Validation Rules:
rangeRulesensure that both fields have valid lengths before submission.rulescomputation checks if the length constraints are met when needed.Style Scopes: The SASS scope is properly defined within
.defaultValueItem.Suggestions for Improvement:
Default Values in Template: Currently, the placeholder text for
default_valueis hardcoded. Make sure this should come from translations if available.Password Visibility Toggle: Ensure the password visibility toggle functionality works as intended. If it doesn't, consider using a library like
vue-password-toggle.Testing Edge Cases: Although not critical here, thoroughly test extreme cases such as very short and long string inputs to ensure all conditions behave as expected.
Additional Considerations:
Accessibility: Ensure the page meets accessibility standards. For example, make sure aria labels are used appropriately.
Internationalization: Since
tcomes from'@/locales', ensure$route.name(or similar dynamic route handling) is working correctly to provide context-sensitive translation messages.Overall, the existing code is functional and follows best practices. Minor improvements can enhance readability and maintainability.