mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2026-01-24 05:21:02 -08:00
Fix/sub wiki tag tree (#667)
* fix: different out path on macos * fix: let go hibernation promise, so it's faster on macos * log marker [test-id-TIDGI_MINI_WINDOW_CREATED] * Skip registerShortcutByKey in test * fix: mini window on mac * Remove useless log marker * Update handleAttachToTidgiMiniWindow.ts * fix: log marker check all log files * lint * fix: open in new window now showing wiki title * Update package.json * feat: basic load and save to sub wiki using in-tag-tree-of * fix: load sub-wiki content and prevent echo * fix: test and ui logic * test: refactor subwiki test logic to a file * refactor: shorten steps by using dedicated step, and test underlying micro steps * fix: review * refactor: remove outdated method signature * test: unit cover adaptor subwiki routing * Update FileSystemAdaptor.routing.test.ts * fix: merge issue
This commit is contained in:
parent
8a84d9b468
commit
c2be8e4186
57 changed files with 2176 additions and 414 deletions
|
|
@ -1,10 +1,10 @@
|
|||
import FolderIcon from '@mui/icons-material/Folder';
|
||||
import { AutocompleteRenderInputParams, MenuItem, Typography } from '@mui/material';
|
||||
import { Autocomplete, AutocompleteRenderInputParams, MenuItem, Typography } from '@mui/material';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { isWikiWorkspace } from '@services/workspaces/interface';
|
||||
import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect, SubWikiTagAutoComplete } from './FormComponents';
|
||||
import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect } from './FormComponents';
|
||||
|
||||
import { useAvailableTags } from './useAvailableTags';
|
||||
import { useValidateCloneWiki } from './useCloneWiki';
|
||||
|
|
@ -63,7 +63,7 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone
|
|||
label={t('AddWorkspace.MainWorkspaceLocation')}
|
||||
helperText={form.mainWikiToLink.wikiFolderLocation &&
|
||||
`${t('AddWorkspace.SubWorkspaceWillLinkTo')}
|
||||
${form.mainWikiToLink.wikiFolderLocation}/tiddlers/${form.wikiFolderName}`}
|
||||
${form.mainWikiToLink.wikiFolderLocation}`}
|
||||
value={form.mainWikiToLinkIndex}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const index = Number(event.target.value);
|
||||
|
|
@ -83,17 +83,23 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone
|
|||
</MenuItem>
|
||||
))}
|
||||
</SoftLinkToMainWikiSelect>
|
||||
<SubWikiTagAutoComplete
|
||||
<Autocomplete<string, true, false, true>
|
||||
multiple
|
||||
freeSolo
|
||||
options={availableTags}
|
||||
value={form.tagName}
|
||||
onInputChange={(_event: React.SyntheticEvent, value: string) => {
|
||||
form.tagNameSetter(value);
|
||||
value={form.tagNames}
|
||||
onChange={(_event, newValue) => {
|
||||
form.tagNamesSetter(newValue);
|
||||
}}
|
||||
slotProps={{
|
||||
chip: {
|
||||
variant: 'outlined',
|
||||
},
|
||||
}}
|
||||
renderInput={(parameters: AutocompleteRenderInputParams) => (
|
||||
<LocationPickerInput
|
||||
{...parameters}
|
||||
error={errorInWhichComponent.tagName}
|
||||
error={errorInWhichComponent.tagNames}
|
||||
label={t('AddWorkspace.TagName')}
|
||||
helperText={t('AddWorkspace.TagNameHelp')}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import FolderIcon from '@mui/icons-material/Folder';
|
||||
import { AutocompleteRenderInputParams, MenuItem, Typography } from '@mui/material';
|
||||
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, SubWikiTagAutoComplete } from './FormComponents';
|
||||
import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect } from './FormComponents';
|
||||
|
||||
import { useAvailableTags } from './useAvailableTags';
|
||||
import { useValidateExistedWiki } from './useExistedWiki';
|
||||
|
|
@ -32,8 +32,8 @@ export function ExistedWikiForm({
|
|||
mainWikiToLinkIndex,
|
||||
mainWikiToLinkSetter,
|
||||
mainWorkspaceList,
|
||||
tagName,
|
||||
tagNameSetter,
|
||||
tagNames,
|
||||
tagNamesSetter,
|
||||
} = form;
|
||||
|
||||
// Local state for the full path input - like NewWikiForm's direct state binding
|
||||
|
|
@ -112,7 +112,7 @@ export function ExistedWikiForm({
|
|||
label={t('AddWorkspace.MainWorkspaceLocation')}
|
||||
helperText={mainWikiToLink.wikiFolderLocation &&
|
||||
`${t('AddWorkspace.SubWorkspaceWillLinkTo')}
|
||||
${mainWikiToLink.wikiFolderLocation}/tiddlers/${wikiFolderName}`}
|
||||
${mainWikiToLink.wikiFolderLocation}`}
|
||||
value={mainWikiToLinkIndex}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const index = Number(event.target.value);
|
||||
|
|
@ -132,17 +132,23 @@ export function ExistedWikiForm({
|
|||
</MenuItem>
|
||||
))}
|
||||
</SoftLinkToMainWikiSelect>
|
||||
<SubWikiTagAutoComplete
|
||||
<Autocomplete<string, true, false, true>
|
||||
multiple
|
||||
freeSolo
|
||||
options={availableTags}
|
||||
value={tagName}
|
||||
onInputChange={(_event: React.SyntheticEvent, value: string) => {
|
||||
tagNameSetter(value);
|
||||
value={tagNames}
|
||||
onChange={(_event, newValue) => {
|
||||
tagNamesSetter(newValue);
|
||||
}}
|
||||
slotProps={{
|
||||
chip: {
|
||||
variant: 'outlined',
|
||||
},
|
||||
}}
|
||||
renderInput={(parameters: AutocompleteRenderInputParams) => (
|
||||
<LocationPickerInput
|
||||
{...parameters}
|
||||
error={errorInWhichComponent.tagName}
|
||||
error={errorInWhichComponent.tagNames}
|
||||
label={t('AddWorkspace.TagName')}
|
||||
helperText={t('AddWorkspace.TagNameHelp')}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import FolderIcon from '@mui/icons-material/Folder';
|
||||
import { AutocompleteRenderInputParams, MenuItem, Typography } from '@mui/material';
|
||||
import { Autocomplete, AutocompleteRenderInputParams, MenuItem, Typography } from '@mui/material';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { isWikiWorkspace } from '@services/workspaces/interface';
|
||||
import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect, SubWikiTagAutoComplete } from './FormComponents';
|
||||
import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect } from './FormComponents';
|
||||
|
||||
import { useAvailableTags } from './useAvailableTags';
|
||||
import type { IWikiWorkspaceFormProps } from './useForm';
|
||||
|
|
@ -68,7 +68,7 @@ export function NewWikiForm({
|
|||
label={t('AddWorkspace.MainWorkspaceLocation')}
|
||||
helperText={form.mainWikiToLink.wikiFolderLocation &&
|
||||
`${t('AddWorkspace.SubWorkspaceWillLinkTo')}
|
||||
${form.mainWikiToLink.wikiFolderLocation}/tiddlers/subwiki/${form.wikiFolderName}`}
|
||||
${form.mainWikiToLink.wikiFolderLocation}`}
|
||||
value={form.mainWikiToLinkIndex}
|
||||
slotProps={{ htmlInput: { 'data-testid': 'main-wiki-select' } }}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
|
|
@ -89,16 +89,22 @@ export function NewWikiForm({
|
|||
</MenuItem>
|
||||
))}
|
||||
</SoftLinkToMainWikiSelect>
|
||||
<SubWikiTagAutoComplete
|
||||
<Autocomplete<string, true, false, true>
|
||||
multiple
|
||||
freeSolo
|
||||
options={availableTags}
|
||||
value={form.tagName}
|
||||
onInputChange={(_event: React.SyntheticEvent, value: string) => {
|
||||
form.tagNameSetter(value);
|
||||
value={form.tagNames}
|
||||
onChange={(_event, newValue) => {
|
||||
form.tagNamesSetter(newValue);
|
||||
}}
|
||||
slotProps={{
|
||||
chip: {
|
||||
variant: 'outlined',
|
||||
},
|
||||
}}
|
||||
renderInput={(parameters: AutocompleteRenderInputParams) => (
|
||||
<LocationPickerInput
|
||||
error={errorInWhichComponent.tagName}
|
||||
error={errorInWhichComponent.tagNames}
|
||||
{...parameters}
|
||||
label={t('AddWorkspace.TagName')}
|
||||
helperText={t('AddWorkspace.TagNameHelp')}
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ const createMockForm = (overrides: Partial<IWikiWorkspaceForm> = {}): IWikiWorks
|
|||
metadata: {},
|
||||
} as unknown as IWorkspace,
|
||||
],
|
||||
tagName: '',
|
||||
tagNameSetter: vi.fn(),
|
||||
tagNames: [] as string[],
|
||||
tagNamesSetter: vi.fn(),
|
||||
gitRepoUrl: '',
|
||||
gitRepoUrlSetter: vi.fn(),
|
||||
gitUserInfo: undefined as IGitUserInfos | undefined,
|
||||
|
|
@ -194,7 +194,7 @@ describe('NewWikiForm Component', () => {
|
|||
const user = userEvent.setup();
|
||||
const mockSetter = vi.fn();
|
||||
const form = createMockForm({
|
||||
tagNameSetter: mockSetter,
|
||||
tagNamesSetter: mockSetter,
|
||||
});
|
||||
|
||||
await renderNewWikiForm({
|
||||
|
|
@ -206,7 +206,7 @@ describe('NewWikiForm Component', () => {
|
|||
const tagInput = screen.getByTestId('tagname-autocomplete-input');
|
||||
await user.type(tagInput, 'MyTag');
|
||||
await user.keyboard('{enter}');
|
||||
expect(mockSetter).toHaveBeenCalledWith('MyTag');
|
||||
expect(mockSetter).toHaveBeenCalledWith(['MyTag']);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ describe('NewWikiForm Component', () => {
|
|||
isCreateMainWorkspace: false,
|
||||
errorInWhichComponent: {
|
||||
mainWikiToLink: true,
|
||||
tagName: true,
|
||||
tagNames: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -276,11 +276,11 @@ describe('NewWikiForm Component', () => {
|
|||
isCreateMainWorkspace: false,
|
||||
});
|
||||
|
||||
// Because the text is rendered with a template literal and newlines, we need to use a regex
|
||||
// The helper text shows the main wiki location that will be linked
|
||||
expect(screen.getByText((content, _element) => {
|
||||
// The actual text might have whitespace and newlines
|
||||
const normalized = content.replace(/\s+/g, ' ').trim();
|
||||
return normalized === 'AddWorkspace.SubWorkspaceWillLinkTo /main/wiki/tiddlers/subwiki/sub-wiki';
|
||||
return normalized === 'AddWorkspace.SubWorkspaceWillLinkTo /main/wiki';
|
||||
})).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export function useValidateCloneWiki(
|
|||
form.gitRepoUrl,
|
||||
form.gitUserInfo,
|
||||
form.mainWikiToLink.wikiFolderLocation,
|
||||
form.tagName,
|
||||
form.tagNames,
|
||||
errorInWhichComponentSetter,
|
||||
]);
|
||||
return [hasError, wikiCreationMessage, wikiCreationMessageSetter, hasErrorSetter];
|
||||
|
|
@ -73,10 +73,8 @@ export function useCloneWiki(
|
|||
await window.service.wiki.cloneSubWiki(
|
||||
form.parentFolderLocation,
|
||||
form.wikiFolderName,
|
||||
form.mainWikiToLink.wikiFolderLocation,
|
||||
form.gitRepoUrl,
|
||||
form.gitUserInfo!,
|
||||
form.tagName,
|
||||
);
|
||||
}
|
||||
await callWikiInitialization(newWorkspaceConfig, wikiCreationMessageSetter, t, form.gitUserInfo, { from: WikiCreationMethod.Clone });
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export function useValidateExistedWiki(
|
|||
form.gitRepoUrl,
|
||||
form.gitUserInfo,
|
||||
form.mainWikiToLink.wikiFolderLocation,
|
||||
form.tagName,
|
||||
form.tagNames,
|
||||
errorInWhichComponentSetter,
|
||||
]);
|
||||
return [hasError, wikiCreationMessage, wikiCreationMessageSetter, hasErrorSetter];
|
||||
|
|
@ -81,14 +81,7 @@ export function useExistedWiki(
|
|||
);
|
||||
}
|
||||
await window.service.wiki.ensureWikiExist(form.wikiFolderLocation, false);
|
||||
await window.service.wiki.createSubWiki(
|
||||
parentFolderLocationForExistedFolder,
|
||||
wikiFolderNameForExistedFolder,
|
||||
'subwiki',
|
||||
form.mainWikiToLink.wikiFolderLocation,
|
||||
form.tagName,
|
||||
true,
|
||||
);
|
||||
await window.service.wiki.createSubWiki(parentFolderLocationForExistedFolder, wikiFolderNameForExistedFolder, true);
|
||||
}
|
||||
await callWikiInitialization(newWorkspaceConfig, wikiCreationMessageSetter, t, form.gitUserInfo, { from: WikiCreationMethod.LoadExisting });
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export function useWikiWorkspaceForm(options?: { fromExisted: boolean }) {
|
|||
return firstMainWiki ? { wikiFolderLocation: firstMainWiki.wikiFolderLocation, port: firstMainWiki.port, id: firstMainWiki.id } : { wikiFolderLocation: '', port: 0, id: '' };
|
||||
},
|
||||
);
|
||||
const [tagName, tagNameSetter] = useState<string>('');
|
||||
const [tagNames, tagNamesSetter] = useState<string[]>([]);
|
||||
let mainWikiToLinkIndex = mainWorkspaceList.findIndex((workspace) => workspace.id === mainWikiToLink.id);
|
||||
if (mainWikiToLinkIndex < 0) {
|
||||
mainWikiToLinkIndex = 0;
|
||||
|
|
@ -123,8 +123,8 @@ export function useWikiWorkspaceForm(options?: { fromExisted: boolean }) {
|
|||
wikiPortSetter,
|
||||
mainWikiToLink,
|
||||
mainWikiToLinkSetter,
|
||||
tagName,
|
||||
tagNameSetter,
|
||||
tagNames,
|
||||
tagNamesSetter,
|
||||
gitRepoUrl,
|
||||
gitRepoUrlSetter,
|
||||
parentFolderLocation,
|
||||
|
|
@ -162,7 +162,7 @@ export function workspaceConfigFromForm(form: INewWikiRequiredFormData, isCreate
|
|||
mainWikiID: isCreateMainWorkspace ? null : form.mainWikiToLink.id,
|
||||
name: form.wikiFolderName,
|
||||
storageService: form.storageProvider,
|
||||
tagName: isCreateMainWorkspace ? null : form.tagName,
|
||||
tagNames: isCreateMainWorkspace ? [] : form.tagNames,
|
||||
port: form.wikiPort,
|
||||
wikiFolderLocation: form.wikiFolderLocation!,
|
||||
backupOnInterval: true,
|
||||
|
|
@ -173,6 +173,9 @@ export function workspaceConfigFromForm(form: INewWikiRequiredFormData, isCreate
|
|||
excludedPlugins: [],
|
||||
enableHTTPAPI: false,
|
||||
enableFileSystemWatch: true,
|
||||
includeTagTree: false,
|
||||
fileSystemPathFilterEnable: false,
|
||||
fileSystemPathFilter: null,
|
||||
lastNodeJSArgv: [],
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ export function useValidateNewWiki(
|
|||
form.gitRepoUrl,
|
||||
form.gitUserInfo,
|
||||
form.mainWikiToLink.wikiFolderLocation,
|
||||
form.tagName,
|
||||
form.tagNames,
|
||||
errorInWhichComponentSetter,
|
||||
]);
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ export function useNewWiki(
|
|||
await window.service.wiki.copyWikiTemplate(form.parentFolderLocation, form.wikiFolderName);
|
||||
}
|
||||
} else {
|
||||
await window.service.wiki.createSubWiki(form.parentFolderLocation, form.wikiFolderName, 'subwiki', form.mainWikiToLink.wikiFolderLocation, form.tagName);
|
||||
await window.service.wiki.createSubWiki(form.parentFolderLocation, form.wikiFolderName);
|
||||
}
|
||||
await callWikiInitialization(newWorkspaceConfig, wikiCreationMessageSetter, t, form.gitUserInfo, { notClose: options?.notClose, from: WikiCreationMethod.Create });
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue