-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
feat: add context menu to file tabs with close actions (#162)
1 parent
3ca0339
commit c847988
Showing
8 changed files
with
305 additions
and
141 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type { MenuProps } from 'antd'; | ||
import { Dropdown } from 'antd'; | ||
import { FC } from 'react'; | ||
|
||
interface Props { | ||
menu?: MenuProps; | ||
children: React.ReactNode; | ||
} | ||
|
||
const ContextMenu: FC<Props> = ({ menu, children }) => { | ||
return ( | ||
<Dropdown menu={menu} trigger={['contextMenu']}> | ||
{children} | ||
</Dropdown> | ||
); | ||
}; | ||
|
||
export default ContextMenu; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export { default as AppLogo } from './AppLogo'; | ||
export { default as ContextMenu } from './ContextMenu'; | ||
export { default as NonProductionNotice } from './NonProductionNotice'; | ||
export { default as Skeleton } from './Skeleton'; | ||
export { default as Tooltip } from './Tooltip'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { Project } from '@/interfaces/workspace.interface'; | ||
import fileSystem from '@/lib/fs'; | ||
import { IFileTab } from '@/state/IDE.context'; | ||
import cloneDeep from 'lodash.clonedeep'; | ||
import EventEmitter from './eventEmitter'; | ||
|
||
export const DEFAULT_PROJECT_SETTING = { | ||
tab: { | ||
items: [], | ||
active: null, | ||
}, | ||
}; | ||
|
||
type ProjectSettingWithTab = Project & IFileTab; | ||
|
||
export async function updateProjectTabSetting( | ||
projectPath: string | undefined, | ||
updatedTab: IFileTab | null, | ||
defaultFilePath?: string, | ||
): Promise<IFileTab> { | ||
if (!projectPath) return DEFAULT_PROJECT_SETTING.tab; | ||
const settingPath = `${projectPath}/.ide/setting.json`; | ||
|
||
try { | ||
await ensureSettingFileExists(settingPath); | ||
|
||
let parsedSetting = await readSettingFile(settingPath); | ||
|
||
if (updatedTab) { | ||
parsedSetting.tab = updatedTab; | ||
} else { | ||
parsedSetting = { ...DEFAULT_PROJECT_SETTING, ...parsedSetting }; | ||
} | ||
|
||
let clonedTab: IFileTab | undefined = cloneDeep(parsedSetting.tab); | ||
|
||
if (!clonedTab?.active && defaultFilePath) { | ||
clonedTab = { | ||
active: defaultFilePath, | ||
items: [ | ||
{ | ||
name: defaultFilePath.split('/').pop() ?? defaultFilePath, | ||
path: defaultFilePath, | ||
isDirty: false, | ||
}, | ||
], | ||
}; | ||
parsedSetting.tab = clonedTab; | ||
} | ||
|
||
await writeSettingFile(settingPath, parsedSetting); | ||
return clonedTab ?? DEFAULT_PROJECT_SETTING.tab; | ||
} catch (error) { | ||
console.error('Error syncing tab settings:', error); | ||
return DEFAULT_PROJECT_SETTING.tab; | ||
} | ||
} | ||
|
||
/** | ||
* Ensure the setting file exists and initialize it with default content if it doesn't. | ||
*/ | ||
async function ensureSettingFileExists(settingPath: string) { | ||
if (!(await fileSystem.exists(settingPath))) { | ||
await fileSystem.writeFile( | ||
settingPath, | ||
JSON.stringify(DEFAULT_PROJECT_SETTING, null, 4), | ||
{ | ||
overwrite: true, | ||
}, | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* Read and parse the settings file. | ||
*/ | ||
async function readSettingFile(settingPath: string) { | ||
const settingContent = (await fileSystem.readFile(settingPath)) as string; | ||
return settingContent | ||
? JSON.parse(settingContent) | ||
: { ...DEFAULT_PROJECT_SETTING }; | ||
} | ||
|
||
/** | ||
* Write the updated settings to the file. | ||
*/ | ||
async function writeSettingFile( | ||
settingPath: string, | ||
parsedSetting: ProjectSettingWithTab, | ||
) { | ||
await fileSystem.writeFile( | ||
settingPath, | ||
JSON.stringify(parsedSetting, null, 2), | ||
{ | ||
overwrite: true, | ||
}, | ||
); | ||
EventEmitter.emit('FORCE_UPDATE_FILE', settingPath); | ||
} |