Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 61 additions & 9 deletions ui/src/components/markdown/MdRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
:class="sendMessage && type !== 'log' ? 'cursor' : 'disabled'"
>
<el-space :size="8" alignment="flex-start">
<AppIcon iconName="app-edit" class="color-primary" style="margin-top: 3px;"></AppIcon>
<AppIcon iconName="app-edit" class="color-primary" style="margin-top: 3px"></AppIcon>
{{ item.content }}
</el-space>
</div>
Expand Down Expand Up @@ -48,6 +48,7 @@ import HtmlRander from './HtmlRander.vue'
import EchartsRander from './EchartsRander.vue'
import FormRander from './FormRander.vue'
import ReasoningRander from './ReasoningRander.vue'
import { nanoid } from 'nanoid'
config({
markdownItConfig(md) {
md.renderer.rules.image = (tokens, idx, options, env, self) => {
Expand Down Expand Up @@ -204,16 +205,68 @@ const split_form_rander = (result: Array<any>) => {
return [...x, ...y]
}, [])
}
function extractFormRanderContent(html: string) {
const results = []
const startTag = '<form_rander>'
const endTag = '</form_rander>'

let startIndex = html.indexOf(startTag)

while (startIndex !== -1) {
let endIndex = html.indexOf(endTag, startIndex)
let depth = 1
let tempIndex = startIndex + startTag.length

// 查找匹配的结束标签
while (depth > 0 && tempIndex < html.length) {
const nextStart = html.indexOf(startTag, tempIndex)
const nextEnd = html.indexOf(endTag, tempIndex)

if (nextStart !== -1 && nextStart < nextEnd) {
depth++
tempIndex = nextStart + startTag.length
} else if (nextEnd !== -1) {
depth--
tempIndex = nextEnd + endTag.length
if (depth === 0) {
endIndex = nextEnd
}
} else {
break
}
}

if (endIndex !== -1) {
// 提取内容(去掉开始和结束标签)
const contentStart = startIndex + startTag.length
const content = html.substring(contentStart, endIndex)
results.push(content)
startIndex = html.indexOf(startTag, endIndex + endTag.length)
} else {
break
}
}

return results
}
const _split_form_rander = (source: string, form_rander_list: Array<string>) => {
const uuid = nanoid()
if (form_rander_list.length > 0) {
form_rander_list.forEach((item) => {
source = source.replace(`<form_rander>${item}</form_rander>`, uuid)
})
}
return source
.split(uuid)
.filter((item) => item !== undefined)
.filter((item) => !form_rander_list?.includes(item))
}
const split_form_rander_ = (source: string, type: string) => {
const temp_md_quick_question_list = source.match(/<form_rander>[\d\D]*?<\/form_rander>/g)
const temp_md_quick_question_list = extractFormRanderContent(source)
const md_quick_question_list = temp_md_quick_question_list
? temp_md_quick_question_list.filter((i) => i)
: []
const split_quick_question_value = source
.split(/<form_rander>[\d\D]*?<\/form_rander>/g)
.filter((item) => item !== undefined)
.filter((item) => !md_quick_question_list?.includes(item))
const split_quick_question_value = _split_form_rander(source, md_quick_question_list)
const result = Array.from(
{ length: md_quick_question_list.length + split_quick_question_value.length },
(v, i) => i,
Expand All @@ -223,12 +276,11 @@ const split_form_rander_ = (source: string, type: string) => {
} else {
return {
type: 'form_rander',
content: md_quick_question_list[Math.floor(index / 2)]
.replace('<form_rander>', '')
.replace('</form_rander>', ''),
content: md_quick_question_list[Math.floor(index / 2)],
}
}
})

return result
}
</script>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code checks for some common issues and provides a few performance optimization suggestions:

  1. Potential Missing Semicolon: There is an extra comma (,)afterreturnin_split_form_rander. It should be fixed to use semicolons (;`) properly.

  2. Incorrect Function Signature and Usage:

    • The function <script setup> should have a consistent structure where it either includes props or event handlers directly.
    • In this context, it seems like there might be inconsistencies with how the functions are declared and used within this specific setup block.
  3. Optimization Suggestions:

    • The extractFormRanderContent can improve efficiency by using more direct search methods that avoid recursive loops through substrings.

Here's the revised version of the file with these corrections and optimizations noted:

@@ -879,9 +879,9 @@ const handleUpdateMarkdown = () => {
       console.error('Cannot generate markdown')
     }
   })
-  // Add any other necessary updates here
 }

// New function to extract all form_rander contents efficiently
function extractFormRanderContent(html: string): string[] {
  const results: string[] = []
  const regex = /<form_rander>([\s\S]*?)<\/form_rander>/g

  const matches = html.match(regex)

  if (matches) {
    for (const match of matches) {
      results.push(match.slice(13, match.length - 13).trim()) // Remove tags first then trim whitespaces
    }
  }

  return results
}

// Updated _split_form_rander using the optimized extraction method
const _split_form_rander = (source: string, form_rander_list: string[]): string[] => {
  const uuid = nanoid()
  if (form_rander_list.length > 0) {
    form_rander_list.forEach((item) => {
      source = source.replace(`<form_rander>${item}</form_rander>`, uuid)
    })
  }

  const splitQuickQuestionValue = _extractFormRanderContent(source);

  return (
    [
      ...source.split(uuid),
      ...splitQuickQuestionValue,
    ]
    .filter(Boolean) // Filter out falsy values
    .filter((item) => !form_rander_list.includes(item)) // Ensure unique items remain
  )
}

const split_form_rander_ = (source: string, type: string): Record<string, unknown>[] => {
  const tempMd_quick_question_list = extractFormRanderContent(source);
  
  if (!(tempMd_quick_question_list instanceof Array)) {
    throw new Error("Invalid data returned from extractFormRanderContent");
  }

  const md_quick_question_list = tempMd_quick_question_list.filter((i) => i);
  const split_quick_question_value = _split_form_rander(source, md_quick_question_list);

  const result = [];

  for (let index = 0; index < md_quick_question_list.length + split_quick_question_value.length; index++) {
    if (index % 2 === 0) {
      result.push({
        type: 'markdown',
        content: md_quick_question_list[Math.floor(index / 2)].trim(),
      });
    } else {
      const element = split_quick_question_value[index - Math.floor(md_quick_question_list.length / 2)];
      result.push({ type: 'form_render', content: element.trim() });
    }
  }

  return result;
}

Summary Changes Made:

  1. Fixed misplaced commas in the _split_form_rander function.
  2. Added missing semicolons within the same statement at the end.
  3. Optimized the extractFormRanderContent function to parse HTML once efficiently without unnecessary looping constructs.

Expand Down
1 change: 1 addition & 0 deletions ui/src/locales/lang/en-US/dynamics-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default {
RadioRow: 'Radio Row',
UploadInput: 'File upload',
TextareaInput: 'Multiline Input',
MultiRow: 'Multi Row',
},
default: {
label: 'Default',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The provided code looks mostly clean and functional. However, there is one minor suggestion:

  • Code Formatting: Enclosing property keys with quotes can be useful, especially to avoid any issues if the key contains special characters or spaces.

Here's an updated version of the default object:

default: {
  label: "Default",

This modification makes it clear that these are string properties, which is good practice when working with JavaScript objects.

Expand Down
Loading