vzcode 0.80.0 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{index-FsyJOC4a.js → index-CnwdGSLW.js} +53 -53
- package/dist/assets/{worker-DrXASJTP.js → worker-tyOiPqgH.js} +47 -47
- package/dist/index.html +1 -1
- package/package.json +3 -3
- package/src/client/AIAssist/AIAssistWidget/index.tsx +4 -16
- package/src/client/CodeEditor/getOrCreateEditor.ts +6 -1
- package/src/client/CodeEditor/index.tsx +7 -1
- package/src/client/CodeEditor/widgets.ts +173 -167
- package/src/client/TabList/index.tsx +13 -19
- package/src/client/VZCodeContext.tsx +12 -0
- package/src/client/VZMiddle.tsx +7 -29
- package/src/client/VZSidebar/DirectoryListing.tsx +12 -32
- package/src/client/VZSidebar/FileListing.tsx +6 -5
- package/src/client/VZSidebar/Item.tsx +30 -10
- package/src/client/VZSidebar/Listing.tsx +6 -30
- package/src/client/VZSidebar/index.tsx +0 -7
- package/src/client/useTypeScript/worker.ts +8 -1
- package/src/types.ts +5 -1
package/src/client/VZMiddle.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import { PresenceNotifications } from './PresenceNotifications';
|
|
|
7
7
|
import { AIAssistWidget } from './AIAssist/AIAssistWidget';
|
|
8
8
|
import { VZCodeContext } from './VZCodeContext';
|
|
9
9
|
import { RunCodeWidget } from './RunCodeWidget';
|
|
10
|
+
import { InteractRule } from '@replit/codemirror-interact';
|
|
10
11
|
|
|
11
12
|
// The middle portion of the VZCode environment, containing:
|
|
12
13
|
// * The list of tabs at the top
|
|
@@ -20,38 +21,25 @@ export const VZMiddle = ({
|
|
|
20
21
|
aiAssistOptions,
|
|
21
22
|
aiAssistTooltipText,
|
|
22
23
|
aiAssistClickOverride,
|
|
24
|
+
customInteractRules,
|
|
23
25
|
}: {
|
|
24
26
|
enableAIAssist?: boolean;
|
|
25
27
|
aiAssistEndpoint?: string;
|
|
26
28
|
aiAssistOptions?: { [key: string]: string };
|
|
27
29
|
aiAssistTooltipText?: string;
|
|
28
30
|
aiAssistClickOverride?: () => void;
|
|
31
|
+
customInteractRules?: Array<InteractRule>;
|
|
29
32
|
}) => {
|
|
30
33
|
const { codeEditorWidth } = useContext(
|
|
31
34
|
SplitPaneResizeContext,
|
|
32
35
|
);
|
|
33
36
|
|
|
34
|
-
// TODO leverage this context in deeper levels of the component tree.
|
|
35
37
|
const {
|
|
36
38
|
content,
|
|
37
|
-
shareDBDoc,
|
|
38
|
-
submitOperation,
|
|
39
39
|
localPresence,
|
|
40
40
|
docPresence,
|
|
41
|
-
files,
|
|
42
|
-
createFile,
|
|
43
41
|
activeFileId,
|
|
44
|
-
setActiveFileId,
|
|
45
|
-
tabList,
|
|
46
|
-
openTab,
|
|
47
|
-
closeTabs,
|
|
48
|
-
theme,
|
|
49
|
-
username,
|
|
50
|
-
editorCache,
|
|
51
|
-
editorWantsFocus,
|
|
52
|
-
editorNoLongerWantsFocus,
|
|
53
42
|
errorMessage,
|
|
54
|
-
typeScriptWorker,
|
|
55
43
|
} = useContext(VZCodeContext);
|
|
56
44
|
|
|
57
45
|
// This prevents the CodeEditor from rendering
|
|
@@ -66,27 +54,17 @@ export const VZMiddle = ({
|
|
|
66
54
|
className="middle"
|
|
67
55
|
style={{ width: codeEditorWidth + 'px' }}
|
|
68
56
|
>
|
|
69
|
-
<TabList
|
|
70
|
-
files={files}
|
|
71
|
-
tabList={tabList}
|
|
72
|
-
activeFileId={activeFileId}
|
|
73
|
-
setActiveFileId={setActiveFileId}
|
|
74
|
-
openTab={openTab}
|
|
75
|
-
closeTabs={closeTabs}
|
|
76
|
-
createFile={createFile}
|
|
77
|
-
/>
|
|
57
|
+
<TabList />
|
|
78
58
|
{isClient && content && activeFileId && (
|
|
79
|
-
<CodeEditor
|
|
59
|
+
<CodeEditor
|
|
60
|
+
customInteractRules={customInteractRules}
|
|
61
|
+
/>
|
|
80
62
|
)}
|
|
81
63
|
{isClient &&
|
|
82
64
|
enableAIAssist &&
|
|
83
65
|
content &&
|
|
84
66
|
activeFileId ? (
|
|
85
67
|
<AIAssistWidget
|
|
86
|
-
activeFileId={activeFileId}
|
|
87
|
-
shareDBDoc={shareDBDoc}
|
|
88
|
-
editorCache={editorCache}
|
|
89
|
-
tabList={tabList}
|
|
90
68
|
aiAssistEndpoint={aiAssistEndpoint}
|
|
91
69
|
aiAssistOptions={aiAssistOptions}
|
|
92
70
|
aiAssistTooltipText={aiAssistTooltipText}
|
|
@@ -1,44 +1,30 @@
|
|
|
1
|
-
import { useCallback, useMemo } from 'react';
|
|
1
|
+
import { useCallback, useContext, useMemo } from 'react';
|
|
2
|
+
import type { FileTree, FileTreeFile } from '../../types';
|
|
3
|
+
import { DirectoryArrowSVG } from '../Icons';
|
|
4
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
2
5
|
import { Item } from './Item';
|
|
3
6
|
import { Listing } from './Listing';
|
|
4
|
-
import { DirectoryArrowSVG } from '../Icons';
|
|
5
|
-
import type {
|
|
6
|
-
FileTree,
|
|
7
|
-
FileTreeFile,
|
|
8
|
-
FileTreePath,
|
|
9
|
-
} from '../../types';
|
|
10
7
|
|
|
11
8
|
export const DirectoryListing = ({
|
|
12
9
|
name,
|
|
13
10
|
path,
|
|
14
11
|
children,
|
|
15
|
-
renameFile,
|
|
16
|
-
deleteFile,
|
|
17
|
-
renameDirectory,
|
|
18
|
-
deleteDirectory,
|
|
19
12
|
handleFileClick,
|
|
20
13
|
handleFileDoubleClick,
|
|
21
|
-
isDirectoryOpen,
|
|
22
|
-
toggleDirectory,
|
|
23
|
-
activeFileId,
|
|
24
14
|
}: {
|
|
25
15
|
name: string;
|
|
26
16
|
path: string;
|
|
27
17
|
children: Array<FileTree | FileTreeFile>;
|
|
28
|
-
renameFile: (fileId: string, newName: string) => void;
|
|
29
|
-
deleteFile: (fileId: string) => void;
|
|
30
|
-
renameDirectory: (
|
|
31
|
-
path: FileTreePath,
|
|
32
|
-
oldName: string,
|
|
33
|
-
newName: string,
|
|
34
|
-
) => void;
|
|
35
|
-
deleteDirectory: (path: FileTreePath) => void;
|
|
36
18
|
handleFileClick: (fileId: string) => void;
|
|
37
19
|
handleFileDoubleClick: (fileId: string) => void;
|
|
38
|
-
isDirectoryOpen: (path: string) => boolean;
|
|
39
|
-
toggleDirectory: (path: string) => void;
|
|
40
|
-
activeFileId: string;
|
|
41
20
|
}) => {
|
|
21
|
+
const {
|
|
22
|
+
renameDirectory,
|
|
23
|
+
deleteDirectory,
|
|
24
|
+
isDirectoryOpen,
|
|
25
|
+
toggleDirectory,
|
|
26
|
+
} = useContext(VZCodeContext);
|
|
27
|
+
|
|
42
28
|
const handleClick = useCallback(() => {
|
|
43
29
|
toggleDirectory(path);
|
|
44
30
|
}, [toggleDirectory, path]);
|
|
@@ -62,6 +48,7 @@ export const DirectoryListing = ({
|
|
|
62
48
|
return (
|
|
63
49
|
<>
|
|
64
50
|
<Item
|
|
51
|
+
id={path}
|
|
65
52
|
name={name}
|
|
66
53
|
handleClick={handleClick}
|
|
67
54
|
handleDeleteClick={handleDeleteClick}
|
|
@@ -87,17 +74,10 @@ export const DirectoryListing = ({
|
|
|
87
74
|
<Listing
|
|
88
75
|
entity={entity}
|
|
89
76
|
key={fileId || path}
|
|
90
|
-
renameFile={renameFile}
|
|
91
|
-
deleteFile={deleteFile}
|
|
92
|
-
renameDirectory={renameDirectory}
|
|
93
|
-
deleteDirectory={deleteDirectory}
|
|
94
77
|
handleFileClick={handleFileClick}
|
|
95
78
|
handleFileDoubleClick={
|
|
96
79
|
handleFileDoubleClick
|
|
97
80
|
}
|
|
98
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
99
|
-
toggleDirectory={toggleDirectory}
|
|
100
|
-
activeFileId={activeFileId}
|
|
101
81
|
/>
|
|
102
82
|
);
|
|
103
83
|
})}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useCallback, useContext } from 'react';
|
|
2
2
|
import { Item } from './Item';
|
|
3
3
|
import { FileId } from '../../types';
|
|
4
4
|
import { FileSVG } from '../Icons';
|
|
5
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
5
6
|
|
|
6
7
|
export const FileListing = ({
|
|
7
8
|
name,
|
|
8
9
|
fileId,
|
|
9
|
-
renameFile,
|
|
10
|
-
deleteFile,
|
|
11
10
|
handleFileClick,
|
|
12
11
|
handleFileDoubleClick,
|
|
13
12
|
isActive,
|
|
14
13
|
}: {
|
|
15
14
|
name: string;
|
|
16
15
|
fileId: FileId;
|
|
17
|
-
renameFile: (fileId: FileId, newName: string) => void;
|
|
18
|
-
deleteFile: (fileId: FileId) => void;
|
|
19
16
|
handleFileClick: (fileId: FileId) => void;
|
|
20
17
|
handleFileDoubleClick: (fileId: FileId) => void;
|
|
21
18
|
isActive: boolean;
|
|
22
19
|
}) => {
|
|
20
|
+
const { renameFile, deleteFile } =
|
|
21
|
+
useContext(VZCodeContext);
|
|
22
|
+
|
|
23
23
|
const handleClick = useCallback(() => {
|
|
24
24
|
handleFileClick(fileId);
|
|
25
25
|
}, [fileId, handleFileClick]);
|
|
@@ -41,6 +41,7 @@ export const FileListing = ({
|
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
43
|
<Item
|
|
44
|
+
id={fileId}
|
|
44
45
|
name={name}
|
|
45
46
|
handleClick={handleClick}
|
|
46
47
|
handleDoubleClick={handleDoubleClick}
|
|
@@ -3,12 +3,15 @@ import {
|
|
|
3
3
|
useCallback,
|
|
4
4
|
useRef,
|
|
5
5
|
useEffect,
|
|
6
|
+
useContext,
|
|
6
7
|
} from 'react';
|
|
7
8
|
import { EditSVG, FileSVG, TrashSVG } from '../Icons';
|
|
8
9
|
import { Tooltip, OverlayTrigger } from '../bootstrap';
|
|
9
10
|
|
|
10
11
|
// TODO consider moving this up to a higher level of the component tree
|
|
11
12
|
import { DeleteConfirmationModal } from './DeleteConfirmationModal';
|
|
13
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
14
|
+
import { ItemId } from '../../types';
|
|
12
15
|
|
|
13
16
|
// TODO support renaming directories
|
|
14
17
|
// See https://github.com/vizhub-core/vzcode/issues/103
|
|
@@ -16,6 +19,7 @@ const enableRenameDirectory = true;
|
|
|
16
19
|
|
|
17
20
|
// A file or directory in the sidebar.
|
|
18
21
|
export const Item = ({
|
|
22
|
+
id,
|
|
19
23
|
name,
|
|
20
24
|
children,
|
|
21
25
|
handleClick,
|
|
@@ -31,6 +35,7 @@ export const Item = ({
|
|
|
31
35
|
? 'Delete Directory'
|
|
32
36
|
: 'Delete File',
|
|
33
37
|
}: {
|
|
38
|
+
id: ItemId;
|
|
34
39
|
name: string;
|
|
35
40
|
children: React.ReactNode;
|
|
36
41
|
handleClick: (event: React.MouseEvent) => void;
|
|
@@ -42,8 +47,21 @@ export const Item = ({
|
|
|
42
47
|
renameFileTooltipText?: string;
|
|
43
48
|
deleteFileTooltipText?: string;
|
|
44
49
|
}) => {
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
const { hoveredItemId, setHoveredItemId } =
|
|
51
|
+
useContext(VZCodeContext);
|
|
52
|
+
// // Tracks whether the mouse is hovering over the file or directory
|
|
53
|
+
// const [isHovered, setIsHovered] = useState(false);
|
|
54
|
+
const isHovered = hoveredItemId === id;
|
|
55
|
+
const setIsHovered = useCallback(
|
|
56
|
+
(isHovered: boolean) => {
|
|
57
|
+
if (isHovered) {
|
|
58
|
+
setHoveredItemId(id);
|
|
59
|
+
} else {
|
|
60
|
+
setHoveredItemId(null);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
[id, setHoveredItemId],
|
|
64
|
+
);
|
|
47
65
|
|
|
48
66
|
// Tracks whether the file is being renamed (inline text input)
|
|
49
67
|
const [isRenaming, setIsRenaming] = useState(false);
|
|
@@ -207,14 +225,16 @@ export const Item = ({
|
|
|
207
225
|
</OverlayTrigger>
|
|
208
226
|
</div>
|
|
209
227
|
) : null}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
{/* TODO Move this up to a higher level of the tree */}
|
|
229
|
+
{showModal && (
|
|
230
|
+
<DeleteConfirmationModal
|
|
231
|
+
show={showModal}
|
|
232
|
+
onClose={handleModalClose}
|
|
233
|
+
onConfirm={handleConfirmModal}
|
|
234
|
+
isDirectory={isDirectory}
|
|
235
|
+
name={name}
|
|
236
|
+
/>
|
|
237
|
+
)}
|
|
218
238
|
</div>
|
|
219
239
|
);
|
|
220
240
|
};
|
|
@@ -1,49 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import type {
|
|
3
3
|
FileId,
|
|
4
4
|
FileTree,
|
|
5
5
|
FileTreeFile,
|
|
6
|
-
FileTreePath,
|
|
7
6
|
} from '../../types';
|
|
7
|
+
import { VZCodeContext } from '../VZCodeContext';
|
|
8
|
+
import { DirectoryListing } from './DirectoryListing';
|
|
8
9
|
import { FileListing } from './FileListing';
|
|
9
10
|
|
|
10
11
|
// A "Listing" is a "FileListing" or a "DirectoryListing"
|
|
11
12
|
// that appears in the Sidebar.
|
|
12
13
|
export const Listing = ({
|
|
13
14
|
entity,
|
|
14
|
-
renameFile,
|
|
15
|
-
deleteFile,
|
|
16
|
-
renameDirectory,
|
|
17
|
-
deleteDirectory,
|
|
18
15
|
handleFileClick,
|
|
19
16
|
handleFileDoubleClick,
|
|
20
|
-
isDirectoryOpen,
|
|
21
|
-
toggleDirectory,
|
|
22
|
-
activeFileId,
|
|
23
17
|
}: {
|
|
24
18
|
entity: FileTree | FileTreeFile;
|
|
25
|
-
renameFile: (fileId: FileId, newName: string) => void;
|
|
26
|
-
deleteFile: (fileId: FileId) => void;
|
|
27
|
-
renameDirectory: (
|
|
28
|
-
path: FileTreePath,
|
|
29
|
-
oldName: string,
|
|
30
|
-
newName: string,
|
|
31
|
-
) => void;
|
|
32
|
-
deleteDirectory: (path: FileTreePath) => void;
|
|
33
19
|
handleFileClick: (fileId: FileId) => void;
|
|
34
20
|
handleFileDoubleClick: (fileId: FileId) => void;
|
|
35
|
-
isDirectoryOpen: (path: string) => boolean;
|
|
36
|
-
toggleDirectory: (path: string) => void;
|
|
37
|
-
activeFileId: FileId;
|
|
38
21
|
}) => {
|
|
22
|
+
const { activeFileId } = useContext(VZCodeContext);
|
|
39
23
|
const { name, file, fileId } = entity as FileTreeFile;
|
|
40
24
|
const { path, children } = entity as FileTree;
|
|
25
|
+
|
|
41
26
|
return file ? (
|
|
42
27
|
<FileListing
|
|
43
28
|
fileId={fileId}
|
|
44
29
|
name={name}
|
|
45
|
-
renameFile={renameFile}
|
|
46
|
-
deleteFile={deleteFile}
|
|
47
30
|
handleFileClick={handleFileClick}
|
|
48
31
|
handleFileDoubleClick={handleFileDoubleClick}
|
|
49
32
|
isActive={fileId === activeFileId}
|
|
@@ -53,15 +36,8 @@ export const Listing = ({
|
|
|
53
36
|
name={name}
|
|
54
37
|
path={path}
|
|
55
38
|
children={children}
|
|
56
|
-
renameFile={renameFile}
|
|
57
|
-
deleteFile={deleteFile}
|
|
58
|
-
renameDirectory={renameDirectory}
|
|
59
|
-
deleteDirectory={deleteDirectory}
|
|
60
39
|
handleFileClick={handleFileClick}
|
|
61
40
|
handleFileDoubleClick={handleFileDoubleClick}
|
|
62
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
63
|
-
toggleDirectory={toggleDirectory}
|
|
64
|
-
activeFileId={activeFileId}
|
|
65
41
|
/>
|
|
66
42
|
);
|
|
67
43
|
};
|
|
@@ -174,17 +174,10 @@ export const VZSidebar = ({
|
|
|
174
174
|
<Listing
|
|
175
175
|
key={key}
|
|
176
176
|
entity={entity}
|
|
177
|
-
renameFile={renameFile}
|
|
178
|
-
deleteFile={deleteFile}
|
|
179
|
-
renameDirectory={renameDirectory}
|
|
180
|
-
deleteDirectory={deleteDirectory}
|
|
181
177
|
handleFileClick={handleFileClick}
|
|
182
178
|
handleFileDoubleClick={
|
|
183
179
|
handleFileDoubleClick
|
|
184
180
|
}
|
|
185
|
-
isDirectoryOpen={isDirectoryOpen}
|
|
186
|
-
toggleDirectory={toggleDirectory}
|
|
187
|
-
activeFileId={activeFileId}
|
|
188
181
|
/>
|
|
189
182
|
);
|
|
190
183
|
})
|
|
@@ -267,7 +267,12 @@ onmessage = async ({ data }) => {
|
|
|
267
267
|
// flag or with a '--target' of 'es2015' or higher."
|
|
268
268
|
const LINT_ERROR_CODE_ITERATED_THROUGH = 2802;
|
|
269
269
|
|
|
270
|
+
// Argument of type '{ Month: string; High: number; Temp: number; Low: number; }'
|
|
271
|
+
// is not assignable to parameter of type 'never'.
|
|
272
|
+
const LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER = 2345;
|
|
273
|
+
|
|
270
274
|
if (debug) {
|
|
275
|
+
console.log('tsErrors');
|
|
271
276
|
console.log(tsErrors);
|
|
272
277
|
}
|
|
273
278
|
tsErrors = tsErrors.filter(
|
|
@@ -279,7 +284,9 @@ onmessage = async ({ data }) => {
|
|
|
279
284
|
error.code !== LINT_ERROR_CODE_ANY_TYPE_KEYS &&
|
|
280
285
|
error.code !==
|
|
281
286
|
LINT_ERROR_CODE_NON_EXISTENT_PROPERTY &&
|
|
282
|
-
error.code !== LINT_ERROR_CODE_ITERATED_THROUGH
|
|
287
|
+
error.code !== LINT_ERROR_CODE_ITERATED_THROUGH &&
|
|
288
|
+
error.code !==
|
|
289
|
+
LINT_ERROR_CODE_ASSIGNABLE_TO_NEVER,
|
|
283
290
|
);
|
|
284
291
|
// }
|
|
285
292
|
tsErrors = convertToCodeMirrorDiagnostic(tsErrors);
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
// FileId
|
|
2
2
|
// * A unique ID for a file.
|
|
3
|
-
|
|
4
3
|
// * This is a random string.
|
|
5
4
|
export type FileId = string;
|
|
6
5
|
|
|
6
|
+
// ItemId
|
|
7
|
+
// * A unique ID for an item in the sidebar.
|
|
8
|
+
// * This could be either a file ID or a directory path.
|
|
9
|
+
export type ItemId = FileId | FileTreePath;
|
|
10
|
+
|
|
7
11
|
// Files
|
|
8
12
|
// * A collection of files.
|
|
9
13
|
// * Keys are _not_ file names or array indices,
|