Merge pull request #15465 from Budibase/BUDI-9016/avoid-duplicated-names-on-creating-components
Avoid duplicated names on creating components
This commit is contained in:
commit
859894a82c
|
@ -76,13 +76,15 @@ export const getSequentialName = <T extends any>(
|
||||||
{
|
{
|
||||||
getName,
|
getName,
|
||||||
numberFirstItem,
|
numberFirstItem,
|
||||||
|
separator = "",
|
||||||
}: {
|
}: {
|
||||||
getName?: (item: T) => string
|
getName?: (item: T) => string
|
||||||
numberFirstItem?: boolean
|
numberFirstItem?: boolean
|
||||||
|
separator?: string
|
||||||
} = {}
|
} = {}
|
||||||
) => {
|
) => {
|
||||||
if (!prefix?.length) {
|
if (!prefix?.length) {
|
||||||
return null
|
return ""
|
||||||
}
|
}
|
||||||
const trimmedPrefix = prefix.trim()
|
const trimmedPrefix = prefix.trim()
|
||||||
const firstName = numberFirstItem ? `${prefix}1` : trimmedPrefix
|
const firstName = numberFirstItem ? `${prefix}1` : trimmedPrefix
|
||||||
|
@ -107,5 +109,5 @@ export const getSequentialName = <T extends any>(
|
||||||
max = num
|
max = num
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return max === 0 ? firstName : `${prefix}${max + 1}`
|
return max === 0 ? firstName : `${prefix}${separator}${max + 1}`
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ describe("getSequentialName", () => {
|
||||||
|
|
||||||
it("handles nullish prefix", async () => {
|
it("handles nullish prefix", async () => {
|
||||||
const name = getSequentialName([], null)
|
const name = getSequentialName([], null)
|
||||||
expect(name).toBe(null)
|
expect(name).toBe("")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("handles just the prefix", async () => {
|
it("handles just the prefix", async () => {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
previewStore,
|
previewStore,
|
||||||
tables,
|
tables,
|
||||||
componentTreeNodesStore,
|
componentTreeNodesStore,
|
||||||
|
screenComponents,
|
||||||
} from "@/stores/builder"
|
} from "@/stores/builder"
|
||||||
import { buildFormSchema, getSchemaForDatasource } from "@/dataBinding"
|
import { buildFormSchema, getSchemaForDatasource } from "@/dataBinding"
|
||||||
import {
|
import {
|
||||||
|
@ -37,6 +38,7 @@ import {
|
||||||
Table,
|
Table,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { utils } from "@budibase/shared-core"
|
import { utils } from "@budibase/shared-core"
|
||||||
|
import { getSequentialName } from "@/helpers/duplicate"
|
||||||
|
|
||||||
interface Component extends ComponentType {
|
interface Component extends ComponentType {
|
||||||
_id: string
|
_id: string
|
||||||
|
@ -452,7 +454,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
createInstance(
|
createInstance(
|
||||||
componentName: string,
|
componentType: string,
|
||||||
presetProps: any,
|
presetProps: any,
|
||||||
parent: any
|
parent: any
|
||||||
): Component | null {
|
): Component | null {
|
||||||
|
@ -461,11 +463,20 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
throw "A valid screen must be selected"
|
throw "A valid screen must be selected"
|
||||||
}
|
}
|
||||||
|
|
||||||
const definition = this.getDefinition(componentName)
|
const definition = this.getDefinition(componentType)
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const componentName = getSequentialName(
|
||||||
|
get(screenComponents),
|
||||||
|
`New ${definition.friendlyName || definition.name}`,
|
||||||
|
{
|
||||||
|
getName: c => c._instanceName,
|
||||||
|
separator: " ",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Generate basic component structure
|
// Generate basic component structure
|
||||||
let instance: Component = {
|
let instance: Component = {
|
||||||
_id: Helpers.uuid(),
|
_id: Helpers.uuid(),
|
||||||
|
@ -475,7 +486,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
hover: {},
|
hover: {},
|
||||||
active: {},
|
active: {},
|
||||||
},
|
},
|
||||||
_instanceName: `New ${definition.friendlyName || definition.name}`,
|
_instanceName: componentName,
|
||||||
...presetProps,
|
...presetProps,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +511,7 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add step name to form steps
|
// Add step name to form steps
|
||||||
if (componentName.endsWith("/formstep")) {
|
if (componentType.endsWith("/formstep")) {
|
||||||
const parentForm = findClosestMatchingComponent(
|
const parentForm = findClosestMatchingComponent(
|
||||||
screen.props,
|
screen.props,
|
||||||
get(selectedComponent)?._id,
|
get(selectedComponent)?._id,
|
||||||
|
@ -529,14 +540,14 @@ export class ComponentStore extends BudiStore<ComponentState> {
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async create(
|
async create(
|
||||||
componentName: string,
|
componentType: string,
|
||||||
presetProps: any,
|
presetProps: any,
|
||||||
parent: Component,
|
parent: Component,
|
||||||
index: number
|
index: number
|
||||||
) {
|
) {
|
||||||
const state = get(this.store)
|
const state = get(this.store)
|
||||||
const componentInstance = this.createInstance(
|
const componentInstance = this.createInstance(
|
||||||
componentName,
|
componentType,
|
||||||
presetProps,
|
presetProps,
|
||||||
parent
|
parent
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { userStore, userSelectedResourceMap, isOnlyUser } from "./users.js"
|
||||||
import { deploymentStore } from "./deployments.js"
|
import { deploymentStore } from "./deployments.js"
|
||||||
import { contextMenuStore } from "./contextMenu.js"
|
import { contextMenuStore } from "./contextMenu.js"
|
||||||
import { snippets } from "./snippets"
|
import { snippets } from "./snippets"
|
||||||
import { screenComponentErrors } from "./screenComponent"
|
import { screenComponents, screenComponentErrors } from "./screenComponent"
|
||||||
|
|
||||||
// Backend
|
// Backend
|
||||||
import { tables } from "./tables"
|
import { tables } from "./tables"
|
||||||
|
@ -68,6 +68,7 @@ export {
|
||||||
snippets,
|
snippets,
|
||||||
rowActions,
|
rowActions,
|
||||||
appPublished,
|
appPublished,
|
||||||
|
screenComponents,
|
||||||
screenComponentErrors,
|
screenComponentErrors,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,12 @@ import { tables } from "./tables"
|
||||||
import { selectedScreen } from "./screens"
|
import { selectedScreen } from "./screens"
|
||||||
import { viewsV2 } from "./viewsV2"
|
import { viewsV2 } from "./viewsV2"
|
||||||
import { findComponentsBySettingsType } from "@/helpers/screen"
|
import { findComponentsBySettingsType } from "@/helpers/screen"
|
||||||
import { UIDatasourceType, Screen } from "@budibase/types"
|
import { UIDatasourceType, Screen, Component } from "@budibase/types"
|
||||||
import { queries } from "./queries"
|
import { queries } from "./queries"
|
||||||
import { views } from "./views"
|
import { views } from "./views"
|
||||||
import { bindings, featureFlag } from "@/helpers"
|
import { bindings, featureFlag } from "@/helpers"
|
||||||
import { getBindableProperties } from "@/dataBinding"
|
import { getBindableProperties } from "@/dataBinding"
|
||||||
|
import { findAllComponents } from "@/helpers/components"
|
||||||
|
|
||||||
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
function reduceBy<TItem extends {}, TKey extends keyof TItem>(
|
||||||
key: TKey,
|
key: TKey,
|
||||||
|
@ -111,3 +112,16 @@ export const screenComponentErrors = derived(
|
||||||
return getInvalidDatasources($selectedScreen, datasources)
|
return getInvalidDatasources($selectedScreen, datasources)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const screenComponents = derived(
|
||||||
|
[selectedScreen],
|
||||||
|
([$selectedScreen]) => {
|
||||||
|
if (!$selectedScreen) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const allComponents = findAllComponents(
|
||||||
|
$selectedScreen.props
|
||||||
|
) as Component[]
|
||||||
|
return allComponents
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue