import FolderIcon from '@mui/icons-material/Folder'; import { Autocomplete, AutocompleteRenderInputParams, MenuItem, Typography } from '@mui/material'; import { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { isWikiWorkspace } from '@services/workspaces/interface'; import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect } from './FormComponents'; import { useAvailableTags } from './useAvailableTags'; import { useValidateExistedWiki } from './useExistedWiki'; import type { IWikiWorkspaceFormProps } from './useForm'; export function ExistedWikiForm({ form, isCreateMainWorkspace, isCreateSyncedWorkspace, errorInWhichComponent, errorInWhichComponentSetter, }: IWikiWorkspaceFormProps & { isCreateSyncedWorkspace: boolean }): React.JSX.Element { const { t } = useTranslation(); const [tagInputValue, setTagInputValue] = useState(''); // Fetch all tags from main wiki for autocomplete suggestions const availableTags = useAvailableTags(form.mainWikiToLink.id, !isCreateMainWorkspace); const tagHelperText = tagInputValue.trim().length > 0 ? t('AddWorkspace.TagNameInputWarning') : (isCreateMainWorkspace ? t('AddWorkspace.TagNameHelpForMain') : t('AddWorkspace.TagNameHelp')); const { wikiFolderLocation, wikiFolderNameSetter, parentFolderLocation, parentFolderLocationSetter, mainWikiToLink, wikiFolderName, mainWikiToLinkIndex, mainWikiToLinkSetter, mainWorkspaceList, tagNames, tagNamesSetter, } = form; // Local state for the full path input - like NewWikiForm's direct state binding // Initialize from form values const [fullPath, setFullPath] = useState(() => { if (parentFolderLocation && wikiFolderName) { return `${parentFolderLocation}${parentFolderLocation.endsWith('/') || parentFolderLocation.endsWith('\\') ? '' : '/'}${wikiFolderName}`; } return ''; }); useValidateExistedWiki(isCreateMainWorkspace, isCreateSyncedWorkspace, form, errorInWhichComponentSetter); const onLocationChange = useCallback( async (newLocation: string) => { const folderName = await window.service.native.path('basename', newLocation); const directoryName = await window.service.native.path('dirname', newLocation); if (folderName !== undefined && directoryName !== undefined) { wikiFolderNameSetter(folderName); parentFolderLocationSetter(directoryName); // Update local state setFullPath(newLocation); } }, [wikiFolderNameSetter, parentFolderLocationSetter], ); return ( ) => { // Update local state immediately for responsive UI const newValue = event.target.value; setFullPath(newValue); // Parse path into parent and folder for validation const lastSlashIndex = Math.max(newValue.lastIndexOf('/'), newValue.lastIndexOf('\\')); if (lastSlashIndex >= 0) { const folder = newValue.slice(lastSlashIndex + 1); // Handle root paths: "/" or "C:\" const parent = lastSlashIndex === 0 ? '/' : newValue.slice(0, lastSlashIndex); wikiFolderNameSetter(folder); parentFolderLocationSetter(parent); } else { // No slash found - treat as relative path or bare folder name wikiFolderNameSetter(newValue); parentFolderLocationSetter(''); } }} label={t('AddWorkspace.WorkspaceFolder')} helperText={`${t('AddWorkspace.ImportWiki')}${wikiFolderLocation ?? ''}`} value={fullPath} /> { // first clear the text, so button will refresh await onLocationChange(''); const filePaths = await window.service.native.pickDirectory(parentFolderLocation); if (filePaths.length > 0) { await onLocationChange(filePaths[0]); } }} endIcon={} > {t('AddWorkspace.Choose')} {!isCreateMainWorkspace && ( <> ) => { const index = Number(event.target.value); const selectedWorkspace = mainWorkspaceList[index]; if (selectedWorkspace && isWikiWorkspace(selectedWorkspace)) { mainWikiToLinkSetter({ wikiFolderLocation: selectedWorkspace.wikiFolderLocation, port: selectedWorkspace.port, id: selectedWorkspace.id, }); } }} > {mainWorkspaceList.map((workspace, index) => ( {workspace.name} ))} multiple freeSolo options={availableTags} value={tagNames} onInputChange={(_event, newInputValue) => { setTagInputValue(newInputValue); }} onChange={(_event, newValue) => { tagNamesSetter(newValue); setTagInputValue(''); }} slotProps={{ chip: { variant: 'outlined', }, }} renderInput={(parameters: AutocompleteRenderInputParams) => ( )} /> )} ); }