|
|
@@ -0,0 +1,70 @@
|
|
|
+import type { IComponentModelConfig } from '@/lvgl-widgets/type'
|
|
|
+import type { BaseWidget } from '@/types/baseWidget'
|
|
|
+import type { Page } from '@/types/page'
|
|
|
+
|
|
|
+import componentMap from '@/lvgl-widgets'
|
|
|
+import { customAlphabet } from 'nanoid'
|
|
|
+import { bfsWalk } from 'simple-mind-map/src/utils'
|
|
|
+
|
|
|
+type WidgetNameSource =
|
|
|
+ | Pick<BaseWidget, 'type' | 'name'>
|
|
|
+ | Pick<IComponentModelConfig, 'key' | 'defaultSchema'>
|
|
|
+
|
|
|
+const createNameSuffix = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 5)
|
|
|
+const widgetNameSuffixPattern = /_\d+(?:_[0-9A-Za-z]+)?$/
|
|
|
+
|
|
|
+const getWidgetType = (source: WidgetNameSource) => {
|
|
|
+ return 'key' in source ? source.key : source.type
|
|
|
+}
|
|
|
+
|
|
|
+const getRawWidgetName = (source: WidgetNameSource) => {
|
|
|
+ return 'defaultSchema' in source ? source.defaultSchema?.name : source.name
|
|
|
+}
|
|
|
+
|
|
|
+export const getWidgetNameBase = (source: WidgetNameSource) => {
|
|
|
+ const widgetType = getWidgetType(source)
|
|
|
+ const defaultName = widgetType ? componentMap[widgetType]?.defaultSchema?.name : ''
|
|
|
+ const rawName = String(defaultName || getRawWidgetName(source) || '')
|
|
|
+ const normalizedBaseName = rawName.replace(widgetNameSuffixPattern, '')
|
|
|
+
|
|
|
+ return normalizedBaseName || 'widget'
|
|
|
+}
|
|
|
+
|
|
|
+export const createWidgetName = (source: WidgetNameSource, index: number) => {
|
|
|
+ return `${getWidgetNameBase(source)}_${index}_${createNameSuffix()}`
|
|
|
+}
|
|
|
+
|
|
|
+const collectWidgetTypeCounts = (page?: Page) => {
|
|
|
+ const counts: Record<string, number> = {}
|
|
|
+ if (!page) return counts
|
|
|
+
|
|
|
+ bfsWalk(page, (widget) => {
|
|
|
+ if (!widget?.type) return
|
|
|
+ counts[widget.type] = (counts[widget.type] || 0) + 1
|
|
|
+ })
|
|
|
+
|
|
|
+ return counts
|
|
|
+}
|
|
|
+
|
|
|
+export const createWidgetNameGenerator = (page?: Page) => {
|
|
|
+ const widgetTypeCounts = collectWidgetTypeCounts(page)
|
|
|
+
|
|
|
+ return (source: WidgetNameSource) => {
|
|
|
+ const widgetType = getWidgetType(source) || 'widget'
|
|
|
+ const nextIndex = (widgetTypeCounts[widgetType] || 0) + 1
|
|
|
+ widgetTypeCounts[widgetType] = nextIndex
|
|
|
+
|
|
|
+ return createWidgetName(source, nextIndex)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export const isDuplicateWidgetName = (
|
|
|
+ widgets: Array<{ id: string; name: string }>,
|
|
|
+ name: string,
|
|
|
+ currentId?: string
|
|
|
+) => {
|
|
|
+ const normalizedName = name.trim()
|
|
|
+ if (!normalizedName) return false
|
|
|
+
|
|
|
+ return widgets.some((widget) => widget.id !== currentId && widget.name === normalizedName)
|
|
|
+}
|