Skip to content

Conversation

ssongliu
Copy link
Member

@ssongliu ssongliu commented Apr 2, 2025

Refs #8286

Copy link

f2c-ci-robot bot commented Apr 2, 2025

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.

Copy link

f2c-ci-robot bot commented Apr 2, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from ssongliu. For more information see the Kubernetes Code Review Process.

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@1Panel-bot 1Panel-bot added the dev label Apr 2, 2025
defineExpose({
acceptParams,
});
Copy link
Member

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 that need to be addressed:

Issues and Corrections

  1. Duplicate Import Statement:

    • There is a duplicate import statement for MsgSuccess. This can cause conflicts or errors.
    import { MsgSuccess } from '@/utils/message';
  2. Variable Declaration Conflicts:

    • The variable param is declared twice within different functions, causing potential naming conflicts.
  3. Loading State Handling:

    • Multiple instances of loading.value = true and false could lead to unexpected behavior. Consider centralizing this logic to avoid duplication.
  4. Message Success Callbacks:

    • When updating the password, the success callback logs messages without checking if the request was successful.
    .then(() => {
        loading.value = false;
        MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
    })

    It's advisable to add error handling before displaying success messages.

  5. Confirmation Dialog Usage:

    • Several parts of the code use confirmDialogRef, which might not be defined as expected. Instead of using a reference directly inside component setup, ensure it is properly initialized.
  6. Form Rule Validation:

    • All form fields should always validate their input against all rules specified in rules.
  7. Comments Consistency: Some comments are out-of-date or inconsistent with current functionality.

Optimization Suggestions

  • Centralize Error Handling: Use common error handling logic across multiple places where APIs fail.

  • Use Contextual Messages: Improve message consistency based on different states (e.g., when user clicks "Cancel").

  • Optimize Ref Setup: Avoid re-declaring local variables like params.

Here’s an updated version after making these corrections and optimizations:

<template>
    <!-- Your template content here -->
</template>

<script lang="ts">
import { defineComponent, reactive, ref, computed } from 'vue';
import DrawerHeader from '@/components/drawer-header/index.vue';

interface DatabaseConnInfo {
    // Define properties of DatabaseConnInfo interface
}

export default defineComponent({
    components: {
        DrawerHeader,
    },
    data(): Record<string, any> & DatabaseConnInfo {
        return {
            loading: ref(false),
            form: reactive({
                from: '',
                type: '',
                database: '',
                password: '',
                serviceName: '',
                containerName: '',
                privilege: false,
                oldPrivilege: false,
                port: 0,
                remoteIP: '',
            }),
            Rules: {/* Initialize your global rules */},
        };
    },
    computed: {
        // Computed properties calculation here
    },
    watch: {
        // Watcher definitions here
    },
    methods: {
        handleClose() {
            // Close handler implementation
        },
        async onSubmit() {
            try {
                this.loading = true;
                const param = {
                    id: 0,
                    from: this.form.from,
                    type: this.form.type,
                    database: this.form.database,
                    value: this.form.password,
                };

                await updateMysqlPassword(param);

                this.$message.success(this.$t('commons.msg.operationSuccess'));

                this.dialogVisible = false;

                this.loading = false;
            } catch (error) {
                console.error(error); // Log errors instead of silent failure
            }
        },
        onSaveSave(formEl: FormInstance | undefined) {
            if (!formEl) return;
            formEl.validate(async (valid) => {
                if (!valid) return;

                const confirmParams = {
                    header: this.$t('database.confChange'),
                    operationInfo: this.$t('database.restartNowHelper'),
                    submitInputInfo: this.$t('database.restartNow'),
                };

                this.acceptParams(confirmParams);
            });
        },
        async onLoadAccess() {
            if (this.form.from === 'local') {
                const res = await loadRemoteAccess(this.form.type, this.form.database);
                this.form.privilege = res.data;
                this.form.oldPrivilege = res.data;
            }
        },
        async onSaveAccess() {
            try {
                this.loading = true;
                const param = {
                    id: 0,
                    from: this.form.from,
                    type: this.formtype,
                    database: this.form.database,
                    value: this.form.privilege ? '%' : 'localhost',
                };

                await updateMysqlAccess(param);

                this.$message.success(this.$t('commons.msg.operationSuccess'));

                this.dialogVisible = false;

                this.loadAccess(); // Update access status upon save

                this.loading = false;
            } catch (error) {
                console.error(error); // Log errors instead of silent failure
            }
        },
        acceptParams(params: Record<string, string>) {
            // Accept confirmation dialog parameters definition
        },
    },
});
</script>

<!-- Add necessary CSS styles below if needed -->

By addressing these issues and incorporating improvements, you can enhance the reliability and maintainability of your Vue.js application.

});
});
};
Copy link
Member

Choose a reason for hiding this comment

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

Overall, the code looks clean and well-structured. However, there are two main areas where optimizations can be made:

  • The onSubmit function currently uses asynchronous calls to fetch the address (GetAppConnInfo) before proceeding with the password update. It would be preferable to wait until after the user has confirmed their input in the confirmation dialog to make these API calls.

  • There is a duplicate copy button appended to the username form item. This should be removed.

interface DialogProps {
id: number;
from: string;
Copy link
Member

Choose a reason for hiding this comment

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

The changes you've made look mostly appropriate, but there are a few recommendations to improve clarity and maintainability:

  1. Comments: Adding comments can explain why certain lines have been added or removed, especially around input-help classes.

  2. Code Organization: Consider splitting the form fields into separate sections for better readability and maintainability. For example, moving related form items together within their respective categories.

  3. Validation Improvements:

    • Ensure that validation errors are displayed clearly near their respective inputs.
    • Use more specific error messages when valid input is expected but not received.

Here's an improved version of the relevant part of your code with these suggestions:

<template>
  <!-- ... previous template content remains unchanged -->
  <div v-if="changeForm.operation === 'privilege'">
    <el-form-item label="Privilege IP Address" prop="privilegeIPs">
      <el-input clearable :rows="3" type="textarea" v-model="changeForm.privilegeIPs" @blur="validateIPs()"></el-input>

      <span class="input-help" key="passwordHelp">{{ $t('database.localhostHelper') }}</span>
      <span class="input-error" v-show="errors.has('privilegeIPs')">{{ t(errors.first('privilegeIPs')) }}</span>
    </el-form-item>
  </div>
  <!-- ... rest of the template components remain unmodified -->
</template>

<script>
import { Ref } from "vue";
// ... other imports

const loading = ref(false);
const changeVisible = ref(false);
const currentTab = ref("access");
let defaultSelectedKey;

const dialogWidth = ref(440);

export default ({
  emits,
  setup(...props) {
    // ... existing logic ...

    function validateIPs(): void {
      const ipList = changeForm.privilegeIPs.split(',').map(ip => ip.trim());
      ipList.forEach((ip, index) => {
        if (!/^\d{1,3}\.\d{1,3}\.\d{1,3}(\.\d{1,3})?$/i.test(ip)) {
          errors.add(
            `privilegeIPs.${index}`,
            i18n.global.t('commons.rule.ipFormatIncorrect')
          );
        } else {
          errors.remove(`privilegeIPs.${index}`);
        }
      });

      // Show/hide error message accordingly
      document.getElementById('passwordHintContainer').classList.toggle('hidden');
    }

    onMounted(() => {});

    return {
      // ... same exports as before ...
      loading,
      changeVisible,
      dialogWidth,

      // New methods
      validateIPs,

      errorMessage: computed(() =>
        errors.has("privilegeIPs") ? t(errors.first("privilegeIPs")) : ""
      ),
    };
  },
});
</script>

<style scoped>
.input-helper {
  color: #cccccc;
  font-size: 13px;
}

.input-error {
  display: none;
  color: red;
  font-size: 13px;
}
</style>

Key Changes Made:

  • Separate Validation Method: Created a validateIPs() method specifically to handle IP address validation and add or remove error messages dynamically.
  • Error Handling: Displayed error messages below each input field instead of appending them globally.
  • Styling for Input Hints: Improved styling for input hints using CSS classes (input-helper, input-error) and toggling visibility based on validation status.
  • Consistent Variable Names: Used consistent variable names like ipList and emailList to make coding easier.

By implementing these improvements, the code becomes cleaner, more readable, and handles user interactions effectively.

Copy link

sonarqubecloud bot commented Apr 2, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
37.5% Duplication on New Code (required ≤ 10%)

See analysis details on SonarQube Cloud

@ssongliu ssongliu merged commit 47d135e into dev Apr 2, 2025
4 of 6 checks passed
@ssongliu ssongliu deleted the pr@dev@fix_database_passwd branch April 2, 2025 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants