diff --git a/shell/scripts/vue-migrate.js b/shell/scripts/vue-migrate.js index 986a7402dc..973968e9a7 100644 --- a/shell/scripts/vue-migrate.js +++ b/shell/scripts/vue-migrate.js @@ -348,6 +348,33 @@ const vueSyntaxUpdates = () => { const isSimpleIdentifier = (str) => /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(str.trim()); const isBracketedExpression = (str) => str.trim().startsWith('[') && str.trim().endsWith(']'); const isStringLiteral = (str) => /^['"].*['"]$/.test(str.trim()); + // Extracts the key expression from a v-for directive. + const extractKeyExpression = (vForContent) => { + const vForMatch = vForContent.match(/^\s*\(([^,]+),\s*([^)]+)\)\s+in\s+(.*)$/); + let keyExpression = null; + + if (vForMatch) { + // v-for="(item, key) in items" + keyExpression = vForMatch[2].trim(); + } else { + const simpleVForMatch = vForContent.match(/^\s*([^\s]+)\s+in\s+(.*)$/); + + if (simpleVForMatch) { + // v-for="item in items" + // Use 'item' as key if it's a simple identifier + keyExpression = isSimpleIdentifier(simpleVForMatch[1].trim()) ? simpleVForMatch[1].trim() : null; + } + } + + return keyExpression; + }; + // Adds the :key attribute to a tag if it doesn't already have one. + const addKeyAttribute = (tag, keyExpression) => { + // Add space if necessary + const space = tag.endsWith(' ') ? '' : ' '; + + return `${ tag }${ space }:key="${ keyExpression }"`; + }; const replacementCases = [ // Handle Vue.set @@ -471,6 +498,98 @@ const vueSyntaxUpdates = () => { // Remove portal-vue components (now use Teleport) [/<\/?portal(-target)?\b[^>]*>/g, '', 'Remove portal components (use Teleport instead) - https://v3.vuejs.org/guide/teleport.html'], + // Add :key to