Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4b1bac3

Browse files
feat(site): allow any file extension on template editor (#12000)
1 parent4e7b208 commit4b1bac3

20 files changed

+517
-333
lines changed

‎site/src/components/SyntaxHighlighter/SyntaxHighlighter.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { type ComponentProps, type FC } from "react";
22
importEditor,{DiffEditor,loader}from"@monaco-editor/react";
33
import*asmonacofrom"monaco-editor";
44
import{useCoderTheme}from"./coderTheme";
5+
import{useTheme}from"@emotion/react";
56

67
loader.config({ monaco});
78

89
interfaceSyntaxHighlighterProps{
910
value:string;
10-
language:string;
11+
language?:string;
1112
editorProps?:ComponentProps<typeofEditor>&
1213
ComponentProps<typeofDiffEditor>;
1314
compareWith?:string;
@@ -20,6 +21,7 @@ export const SyntaxHighlighter: FC<SyntaxHighlighterProps> = ({
2021
editorProps,
2122
})=>{
2223
consthasDiff=compareWith&&value!==compareWith;
24+
consttheme=useTheme();
2325
constcoderTheme=useCoderTheme();
2426
constcommonProps={
2527
language,
@@ -45,6 +47,7 @@ export const SyntaxHighlighter: FC<SyntaxHighlighterProps> = ({
4547
css={{
4648
padding:"8px 0",
4749
height:"100%",
50+
backgroundColor:theme.monaco.colors["editor.background"],
4851
}}
4952
>
5053
{hasDiff ?(
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{chromatic}from"testHelpers/chromatic";
3+
import{TemplateFileTree}from"./TemplateFileTree";
4+
import{FileTree}from"utils/filetree";
5+
import{useTheme}from"@emotion/react";
6+
7+
constfileTree:FileTree={
8+
"main.tf":"resource aws_instance my_instance {}",
9+
"variables.tf":"variable my_var {}",
10+
"outputs.tf":"output my_output {}",
11+
folder:{
12+
"nested.tf":"resource aws_instance my_instance {}",
13+
},
14+
};
15+
16+
constmeta:Meta<typeofTemplateFileTree>={
17+
title:"modules/templates/TemplateFileTree",
18+
parameters:{ chromatic},
19+
component:TemplateFileTree,
20+
args:{
21+
fileTree,
22+
activePath:"main.tf",
23+
},
24+
decorators:[
25+
(Story)=>{
26+
consttheme=useTheme();
27+
return(
28+
<div
29+
css={{
30+
maxWidth:260,
31+
borderRadius:8,
32+
border:`1px solid${theme.palette.divider}`,
33+
}}
34+
>
35+
<Story/>
36+
</div>
37+
);
38+
},
39+
],
40+
};
41+
42+
exportdefaultmeta;
43+
typeStory=StoryObj<typeofTemplateFileTree>;
44+
45+
exportconstExample:Story={};
46+
47+
exportconstNestedOpen:Story={
48+
args:{
49+
activePath:"folder/nested.tf",
50+
},
51+
};
52+
53+
exportconstGroupEmptyFolders:Story={
54+
args:{
55+
activePath:"folder/other-folder/another/nested.tf",
56+
fileTree:{
57+
"main.tf":"resource aws_instance my_instance {}",
58+
"variables.tf":"variable my_var {}",
59+
"outputs.tf":"output my_output {}",
60+
folder:{
61+
"other-folder":{
62+
another:{
63+
"nested.tf":"resource aws_instance my_instance {}",
64+
},
65+
},
66+
},
67+
},
68+
},
69+
};
70+
71+
exportconstGreyOutHiddenFiles:Story={
72+
args:{
73+
fileTree:{
74+
".vite":{
75+
"config.json":"resource aws_instance my_instance {}",
76+
},
77+
".nextjs":{
78+
"nested.tf":"resource aws_instance my_instance {}",
79+
},
80+
".terraform.lock.hcl":"{}",
81+
"main.tf":"resource aws_instance my_instance {}",
82+
"variables.tf":"variable my_var {}",
83+
"outputs.tf":"output my_output {}",
84+
},
85+
},
86+
};

‎site/src/pages/TemplateVersionEditorPage/FileTreeView.tsxrenamed to‎site/src/modules/templates/TemplateFiles/TemplateFileTree.tsx

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,59 @@ type ContextMenu = {
2828
clientY:number;
2929
};
3030

31-
interfaceFileTreeViewProps{
31+
interfaceTemplateFilesTreeProps{
3232
onSelect:(path:string)=>void;
33-
onDelete:(path:string)=>void;
34-
onRename:(path:string)=>void;
33+
onDelete?:(path:string)=>void;
34+
onRename?:(path:string)=>void;
3535
fileTree:FileTree;
3636
activePath?:string;
37+
Label?:FC<{
38+
path:string;
39+
filename:string;
40+
label:string;
41+
isFolder:boolean;
42+
}>;
3743
}
3844

39-
exportconstFileTreeView:FC<FileTreeViewProps>=({
45+
exportconstTemplateFileTree:FC<TemplateFilesTreeProps>=({
4046
fileTree,
4147
activePath,
4248
onDelete,
4349
onRename,
4450
onSelect,
51+
Label,
4552
})=>{
4653
const[contextMenu,setContextMenu]=useState<ContextMenu|undefined>();
54+
55+
constisFolder=(content?:FileTree|string):content isFileTree=>
56+
typeofcontent==="object";
57+
4758
constbuildTreeItems=(
59+
label:string,
4860
filename:string,
4961
content?:FileTree|string,
5062
parentPath?:string,
5163
):JSX.Element=>{
5264
constcurrentPath=parentPath ?`${parentPath}/${filename}` :filename;
53-
constisFolder=typeofcontent==="object";
54-
leticon:JSX.Element|null=isFolder ?null :(
65+
// Used to group empty folders in one single label like VSCode does
66+
constshouldGroupFolder=
67+
isFolder(content)&&
68+
Object.keys(content).length===1&&
69+
isFolder(Object.values(content)[0]);
70+
constisHiddenFile=currentPath.startsWith(".");
71+
72+
if(shouldGroupFolder){
73+
constfirstChildFileName=Object.keys(content)[0];
74+
constchild=content[firstChildFileName];
75+
returnbuildTreeItems(
76+
`${label} /${firstChildFileName}`,
77+
firstChildFileName,
78+
child,
79+
currentPath,
80+
);
81+
}
82+
83+
leticon:JSX.Element|null=isFolder(content) ?null :(
5584
<FormatAlignLeftOutlined/>
5685
);
5786

@@ -69,26 +98,40 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
6998
<TreeItem
7099
nodeId={currentPath}
71100
key={currentPath}
72-
label={filename}
101+
label={
102+
Label ?(
103+
<Label
104+
path={currentPath}
105+
label={label}
106+
filename={filename}
107+
isFolder={isFolder(content)}
108+
/>
109+
) :(
110+
label
111+
)
112+
}
73113
css={(theme)=>css`
74114
overflow: hidden;
75115
user-select: none;
76116
77117
&> .MuiTreeItem-content {
78118
padding:2px16px;
79-
color:${theme.palette.text.secondary};
119+
color:${isHiddenFile
120+
?theme.palette.text.disabled
121+
:theme.palette.text.secondary};
80122
height:32px;
81123
82124
&svg {
83125
width:12px;
84126
height:12px;
85-
color:${theme.palette.text.secondary};
127+
color:currentColor;
86128
}
87129
88130
&> .MuiTreeItem-label {
89131
margin-left:4px;
90132
font-size:13px;
91133
color: inherit;
134+
white-space: nowrap;
92135
}
93136
94137
&.Mui-selected {
@@ -103,17 +146,22 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
103146
104147
& .MuiTreeItem-group {
105148
margin-left:0;
149+
position: relative;
106150
107151
// We need to find a better way to recursive padding here
108152
& .MuiTreeItem-content {
109-
padding-left:calc(var(--level)*40px);
153+
padding-left:calc(8px+ (var(--level)+1)*8px);
110154
}
111155
}
112156
`}
113157
onClick={()=>{
114158
onSelect(currentPath);
115159
}}
116160
onContextMenu={(event)=>{
161+
consthasContextActions=onRename||onDelete;
162+
if(!hasContextActions){
163+
return;
164+
}
117165
event.preventDefault();// Avoid default browser behavior
118166
event.stopPropagation();// Avoid trigger parent context menu
119167
setContextMenu(
@@ -133,12 +181,12 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
133181
}asCSSProperties
134182
}
135183
>
136-
{isFolder&&
184+
{isFolder(content)&&
137185
Object.keys(content)
138186
.sort(sortFileTree(content))
139187
.map((filename)=>{
140188
constchild=content[filename];
141-
returnbuildTreeItems(filename,child,currentPath);
189+
returnbuildTreeItems(filename,filename,child,currentPath);
142190
})}
143191
</TreeItem>
144192
);
@@ -149,13 +197,14 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
149197
defaultCollapseIcon={<ExpandMoreIcon/>}
150198
defaultExpandIcon={<ChevronRightIcon/>}
151199
aria-label="Files"
200+
defaultExpanded={activePath ?expandablePaths(activePath) :[]}
152201
defaultSelected={activePath}
153202
>
154203
{Object.keys(fileTree)
155204
.sort(sortFileTree(fileTree))
156205
.map((filename)=>{
157206
constchild=fileTree[filename];
158-
returnbuildTreeItems(filename,child);
207+
returnbuildTreeItems(filename,filename,child);
159208
})}
160209

161210
<Menu
@@ -184,7 +233,7 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
184233
if(!contextMenu){
185234
return;
186235
}
187-
onRename(contextMenu.path);
236+
onRename&&onRename(contextMenu.path);
188237
setContextMenu(undefined);
189238
}}
190239
>
@@ -195,7 +244,7 @@ export const FileTreeView: FC<FileTreeViewProps> = ({
195244
if(!contextMenu){
196245
return;
197246
}
198-
onDelete(contextMenu.path);
247+
onDelete&&onDelete(contextMenu.path);
199248
setContextMenu(undefined);
200249
}}
201250
>
@@ -232,3 +281,12 @@ const FileTypeMarkdown: FC = () => (
232281
<polygonpoints="22.955 20.636 18.864 16.136 21.591 16.136 21.591 11.364 24.318 11.364 24.318 16.136 27.045 16.136 22.955 20.636"/>
233282
</svg>
234283
);
284+
285+
constexpandablePaths=(path:string)=>{
286+
constpaths=path.split("/");
287+
constresult=[];
288+
for(leti=1;i<paths.length;i++){
289+
result.push(paths.slice(0,i).join("/"));
290+
}
291+
returnresult;
292+
};

‎site/src/modules/templates/TemplateFiles/TemplateFiles.stories.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import{action}from"@storybook/addon-actions";
21
importtype{Meta,StoryObj}from"@storybook/react";
32
import{chromatic}from"testHelpers/chromatic";
43
import{TemplateFiles}from"./TemplateFiles";
@@ -19,7 +18,6 @@ const meta: Meta<typeof TemplateFiles> = {
1918
args:{
2019
currentFiles:exampleFiles,
2120
baseFiles:exampleFiles,
22-
tab:{value:"0",set:action("change tab")},
2321
},
2422
};
2523

@@ -28,4 +26,14 @@ type Story = StoryObj<typeof TemplateFiles>;
2826

2927
constExample:Story={};
3028

29+
exportconstWithDiff:Story={
30+
args:{
31+
currentFiles:{
32+
...exampleFiles,
33+
"main.tf":`${exampleFiles["main.tf"]} - with changes`,
34+
},
35+
baseFiles:exampleFiles,
36+
},
37+
};
38+
3139
export{ExampleasTemplateFiles};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp