Skip to content

Commit c0abb5d

Browse files
Improved name input patterns for files and folders (#433)
* fix: improve name input patterns for files and folders * fix: update folder name patterns to include adapter names
1 parent e60733c commit c0abb5d

5 files changed

Lines changed: 45 additions & 6 deletions

File tree

src/main/frontend/app/components/file-structure/file-tree-dialogs.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import ContextMenu from './context-menu'
2-
import NameInputDialog from './name-input-dialog'
2+
import NameInputDialog, { FILE_NAME_PATTERNS, FOLDER_OR_ADAPTER_NAME_PATTERNS } from './name-input-dialog'
33
import ConfirmDeleteDialog from './confirm-delete-dialog'
44
import type { ContextMenuState, NameDialogState, DeleteTargetState } from './use-file-tree-context-menu'
55

@@ -51,6 +51,9 @@ export default function FileTreeDialogs({
5151
initialValue={nameDialog.initialValue}
5252
onSubmit={nameDialog.onSubmit}
5353
onCancel={onCloseNameDialog}
54+
patterns={
55+
nameDialog.title.toLowerCase().includes('folder') ? FOLDER_OR_ADAPTER_NAME_PATTERNS : FILE_NAME_PATTERNS
56+
}
5457
/>
5558
)}
5659

src/main/frontend/app/components/file-structure/name-input-dialog.tsx

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,42 @@
1-
import { useRef, useState } from 'react'
1+
import React, { useRef, useState } from 'react'
22
import { createPortal } from 'react-dom'
33
import Button from '~/components/inputs/button'
44
import ValidatedInput from '~/components/inputs/validatedInput'
55

6-
const namePatterns: Record<string, RegExp> = {
6+
const BASE_NAME_PATTERNS: Record<string, RegExp> = {
77
'Cannot be empty': /^(?!\s*$).+/,
88
'Cannot contain /': /^[^/]*$/,
99
'Cannot contain \\': /^[^\\]*$/,
1010
'Cannot contain ..': /^(?!.*\.\.).*$/,
11+
}
12+
13+
export const FILE_NAME_PATTERNS: Record<string, RegExp> = {
14+
...BASE_NAME_PATTERNS,
1115
'Must end with:\n.xml, .json, .yaml, .yml, or .properties': /^(.*\.(xml|json|yaml|yml|properties))?$/i,
1216
}
1317

18+
export const CONFIGURATION_NAME_PATTERNS: Record<string, RegExp> = {
19+
...BASE_NAME_PATTERNS,
20+
'Must end with:\n.xml': /^(.*\.(xml))?$/i,
21+
}
22+
23+
export const FOLDER_OR_ADAPTER_NAME_PATTERNS: Record<string, RegExp> = BASE_NAME_PATTERNS
24+
1425
interface NameInputDialogProps {
1526
title: string
1627
initialValue?: string
1728
onSubmit: (name: string) => void
1829
onCancel: () => void
30+
patterns?: Record<string, RegExp>
1931
}
2032

21-
export default function NameInputDialog({ title, initialValue = '', onSubmit, onCancel }: NameInputDialogProps) {
33+
export default function NameInputDialog({
34+
title,
35+
initialValue = '',
36+
onSubmit,
37+
onCancel,
38+
patterns = FOLDER_OR_ADAPTER_NAME_PATTERNS,
39+
}: NameInputDialogProps) {
2240
const [value, setValue] = useState(initialValue)
2341
const [isValid, setIsValid] = useState(false)
2442
const overlayRef = useRef<HTMLDivElement>(null)
@@ -54,7 +72,7 @@ export default function NameInputDialog({ title, initialValue = '', onSubmit, on
5472
autoFocus
5573
onFocus={(e) => e.target.select()}
5674
value={value}
57-
patterns={namePatterns}
75+
patterns={patterns}
5876
onValidChange={setIsValid}
5977
onChange={(e) => setValue(e.target.value)}
6078
onKeyDown={handleKeyDown}

src/main/frontend/app/components/file-structure/studio-file-tree-dialogs.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export default function StudioFileTreeDialogs({
5353
initialValue={nameDialog.initialValue}
5454
onSubmit={nameDialog.onSubmit}
5555
onCancel={onCloseNameDialog}
56+
patterns={nameDialog.patterns}
5657
/>
5758
)}
5859

src/main/frontend/app/components/file-structure/use-file-tree-context-menu.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { clearConfigurationCache } from '~/services/configuration-service'
66
import useTabStore from '~/stores/tab-store'
77
import useEditorTabStore from '~/stores/editor-tab-store'
88
import { showErrorToast, showErrorToastFrom } from '~/components/toast'
9+
import { FILE_NAME_PATTERNS, FOLDER_OR_ADAPTER_NAME_PATTERNS } from '~/components/file-structure/name-input-dialog'
910

1011
export interface ContextMenuState {
1112
position: { x: number; y: number }
@@ -20,6 +21,7 @@ export interface NameDialogState {
2021
title: string
2122
initialValue?: string
2223
onSubmit: (name: string) => void
24+
patterns?: Record<string, RegExp>
2325
}
2426

2527
export interface DeleteTargetState {
@@ -130,6 +132,7 @@ export function useFileTreeContextMenu({
130132
}
131133
setNameDialog(null)
132134
},
135+
patterns: FILE_NAME_PATTERNS,
133136
})
134137
},
135138
[projectName, dataProvider, closeContextMenu],
@@ -154,6 +157,7 @@ export function useFileTreeContextMenu({
154157
}
155158
setNameDialog(null)
156159
},
160+
patterns: FOLDER_OR_ADAPTER_NAME_PATTERNS,
157161
})
158162
},
159163
[projectName, dataProvider, closeContextMenu],
@@ -193,6 +197,7 @@ export function useFileTreeContextMenu({
193197
}
194198
setNameDialog(null)
195199
},
200+
patterns: menu.isFolder ? FOLDER_OR_ADAPTER_NAME_PATTERNS : FILE_NAME_PATTERNS,
196201
})
197202
},
198203
[projectName, dataProvider, onAfterRename, closeContextMenu],

src/main/frontend/app/components/file-structure/use-studio-context-menu.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useRef, useState } from 'react'
1+
import React, { useCallback, useRef, useState } from 'react'
22
import type { TreeItemIndex } from 'react-complex-tree'
33
import { deleteFile, renameFile } from '~/services/file-service'
44
import { createFolderInProject } from '~/services/file-tree-service'
@@ -7,6 +7,10 @@ import { clearConfigurationCache, createConfiguration } from '~/services/configu
77
import useTabStore from '~/stores/tab-store'
88
import { showErrorToastFrom } from '~/components/toast'
99
import type { StudioItemData, StudioFolderData, StudioAdapterData } from './studio-files-data-provider'
10+
import {
11+
CONFIGURATION_NAME_PATTERNS,
12+
FOLDER_OR_ADAPTER_NAME_PATTERNS,
13+
} from '~/components/file-structure/name-input-dialog'
1014

1115
export type StudioItemType = 'root' | 'folder' | 'configuration' | 'adapter'
1216

@@ -23,6 +27,7 @@ export interface NameDialogState {
2327
title: string
2428
initialValue?: string
2529
onSubmit: (name: string) => void
30+
patterns?: Record<string, RegExp>
2631
}
2732

2833
export interface DeleteTargetState {
@@ -159,6 +164,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
159164
}
160165
setNameDialog(null)
161166
},
167+
patterns: CONFIGURATION_NAME_PATTERNS,
162168
})
163169
},
164170
[projectName, dataProvider, closeContextMenu],
@@ -181,6 +187,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
181187
}
182188
setNameDialog(null)
183189
},
190+
patterns: FOLDER_OR_ADAPTER_NAME_PATTERNS,
184191
})
185192
},
186193
[projectName, dataProvider, closeContextMenu],
@@ -203,6 +210,7 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
203210
}
204211
setNameDialog(null)
205212
},
213+
patterns: FOLDER_OR_ADAPTER_NAME_PATTERNS,
206214
})
207215
},
208216
[projectName, dataProvider, closeContextMenu],
@@ -239,6 +247,10 @@ export function useStudioContextMenu({ projectName, dataProvider }: UseStudioCon
239247
}
240248
setNameDialog(null)
241249
},
250+
patterns:
251+
menu.itemType === 'folder' || menu.itemType === 'adapter'
252+
? FOLDER_OR_ADAPTER_NAME_PATTERNS
253+
: CONFIGURATION_NAME_PATTERNS,
242254
})
243255
},
244256
[projectName, dataProvider, closeContextMenu],

0 commit comments

Comments
 (0)