1- import { useCallback , useRef , useState } from 'react'
1+ import React , { useCallback , useRef , useState } from 'react'
22import type { TreeItemIndex } from 'react-complex-tree'
3- import {
4- createFileInProject ,
5- createFolderInProject ,
6- renameInProject ,
7- deleteInProject ,
8- } from '~/services/file-tree-service'
3+ import { createFile , deleteFile , renameFile } from '~/services/file-service'
4+ import { createFolderInProject } from '~/services/file-tree-service'
95import { clearConfigurationCache } from '~/services/configuration-service'
106import useTabStore from '~/stores/tab-store'
117import useEditorTabStore from '~/stores/editor-tab-store'
12- import { showErrorToastFrom } from '~/components/toast'
8+ import { showErrorToast , showErrorToastFrom } from '~/components/toast'
139
1410export interface ContextMenuState {
1511 position : { x : number ; y : number }
@@ -47,15 +43,19 @@ interface UseFileTreeContextMenuOptions {
4743 onAfterDelete ?: ( path : string ) => void
4844}
4945
46+ const ALLOWED_EXTENSIONS = [ '.xml' , '.json' , '.yaml' , '.yml' , '.properties' ]
47+
5048export function getParentItemId ( itemId : TreeItemIndex ) : TreeItemIndex {
5149 const str = String ( itemId )
5250 const lastSlash = str . lastIndexOf ( '/' )
5351 return lastSlash > 0 ? str . slice ( 0 , Math . max ( 0 , lastSlash ) ) : 'root'
5452}
5553
56- function ensureXmlExtension ( name : string ) : string {
57- if ( name . includes ( '.' ) ) return name
58- return `${ name } .xml`
54+ function ensureHasCorrectExtension ( name : string ) : boolean {
55+ const dotIndex = name . lastIndexOf ( '.' )
56+ if ( dotIndex === - 1 ) return false
57+ const extension = name . slice ( dotIndex )
58+ return ALLOWED_EXTENSIONS . includes ( extension . toLowerCase ( ) )
5959}
6060
6161function buildNewPath ( oldPath : string , newName : string ) : string {
@@ -117,9 +117,13 @@ export function useFileTreeContextMenu({
117117 setNameDialog ( {
118118 title : 'New File' ,
119119 onSubmit : async ( name : string ) => {
120- const fileName = ensureXmlExtension ( name )
120+ if ( ! ensureHasCorrectExtension ( name ) ) {
121+ showErrorToast ( `Filename must have one of the following extensions: ${ ALLOWED_EXTENSIONS . join ( ', ' ) } ` )
122+ return
123+ }
124+
121125 try {
122- await createFileInProject ( projectName , parentPath , fileName )
126+ await createFile ( projectName , ` ${ parentPath } / ${ name } ` )
123127 await dataProvider . reloadDirectory ( parentItemId )
124128 } catch ( error ) {
125129 showErrorToastFrom ( 'Failed to create file' , error )
@@ -143,7 +147,7 @@ export function useFileTreeContextMenu({
143147 title : 'New Folder' ,
144148 onSubmit : async ( name : string ) => {
145149 try {
146- await createFolderInProject ( projectName , parentPath , name )
150+ await createFolderInProject ( projectName , ` ${ parentPath } / ${ name } ` )
147151 await dataProvider . reloadDirectory ( parentItemId )
148152 } catch ( error ) {
149153 showErrorToastFrom ( 'Failed to create folder' , error )
@@ -171,9 +175,13 @@ export function useFileTreeContextMenu({
171175 if ( newName === oldName ) {
172176 setNameDialog ( null )
173177 return
178+ } else if ( ! ensureHasCorrectExtension ( newName ) ) {
179+ showErrorToast ( `Filename must have one of the following extensions: ${ ALLOWED_EXTENSIONS . join ( ', ' ) } ` )
180+ return
174181 }
182+
175183 try {
176- await renameInProject ( projectName , oldPath , newName )
184+ await renameFile ( projectName , ` ${ oldPath } ` , ` ${ oldPath } ` . replace ( oldName , newName ) )
177185 clearConfigurationCache ( projectName , oldPath )
178186 const newPath = buildNewPath ( oldPath , newName )
179187 useTabStore . getState ( ) . renameTabsForConfig ( oldPath , newPath )
@@ -209,7 +217,7 @@ export function useFileTreeContextMenu({
209217 if ( ! deleteTarget || ! projectName || ! dataProvider ) return
210218
211219 try {
212- await deleteInProject ( projectName , deleteTarget . path )
220+ await deleteFile ( projectName , deleteTarget . path )
213221 clearConfigurationCache ( projectName , deleteTarget . path )
214222 useTabStore . getState ( ) . removeTabsForConfig ( deleteTarget . path )
215223 useEditorTabStore . getState ( ) . refreshAllTabs ( )
0 commit comments