Skip to content
This repository was archived by the owner on Aug 16, 2025. It is now read-only.

Commit fe93192

Browse files
Feature yaml editor (#76)
* added yaml editor * name fix * moved component to one code block * removed logs * fix: yaml editor * fix: reviews * new line * fix: merge fix
1 parent f7722c4 commit fe93192

File tree

3 files changed

+160
-121
lines changed

3 files changed

+160
-121
lines changed

‎docs/configure-coderabbit.md‎

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,6 @@ You can add a `.coderabbit.yaml` configuration file to the root of your
3939
repositories. Below is a sample YAML file that can be used as a starting point
4040
and changed as needed:
4141

42-
```yaml
43-
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
44-
language: "en-US"
45-
early_access: false
46-
reviews:
47-
profile: "chill"
48-
request_changes_workflow: false
49-
high_level_summary: true
50-
poem: true
51-
review_status: true
52-
collapse_walkthrough: false
53-
auto_review:
54-
enabled: true
55-
drafts: false
56-
chat:
57-
auto_reply: true
58-
```
59-
6042
Write your configuration file in the below editor to validate:
6143

6244
```mdx-code-block

‎src/components/YamlEditor/YamlEditor.jsx‎

Lines changed: 0 additions & 103 deletions
This file was deleted.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
importReact,{useState,useEffect}from"react";
2+
3+
importAceEditorfrom"react-ace";
4+
import"ace-builds/src-noconflict/theme-github";
5+
import"ace-builds/src-noconflict/ext-language_tools";
6+
7+
import"ace-builds/webpack-resolver";
8+
import"ace-builds/src-noconflict/mode-yaml";
9+
10+
importjsYamlfrom"js-yaml";
11+
12+
importAjvfrom"ajv";
13+
constajv=newAjv({allErrors: true});
14+
15+
importSchemafrom"../../../static/schema/schema.v2.json";
16+
17+
constvalidate=ajv.compile(Schema.definitions.schema);
18+
constinitialValue=`# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
19+
language: "en-US"
20+
early_access: false
21+
reviews:
22+
profile: "chill"
23+
request_changes_workflow: false
24+
high_level_summary: true
25+
poem: true
26+
review_status: true
27+
collapse_walkthrough: false
28+
auto_review:
29+
enabled: true
30+
drafts: false
31+
chat:
32+
auto_reply: true
33+
34+
`;
35+
exportdefaultfunctionYamlEditor(){
36+
const[value,setValue]=useState(initialValue);
37+
const[annotations,setAnnotations]=useState([]);
38+
39+
useEffect(()=>{
40+
setValue(initialValue);
41+
validateAndSetAnnotations(initialValue);
42+
},[]);
43+
44+
functionvalidateAndSetAnnotations(yaml){
45+
try{
46+
constdoc=jsYaml.load(yaml,{strict: true});
47+
constisValid=validate(doc);
48+
49+
if(!isValid&&validate.errors){
50+
setAnnotations(
51+
validate.errors.map((err)=>{
52+
constinstancePathArr=err?.instancePath?.split("/");
53+
constkey=
54+
instancePathArr&&instancePathArr[instancePathArr.length-1];
55+
return{
56+
row: err.instancePath ? getLineNumber(yaml,err.instancePath) : 0,
57+
column: 0,
58+
text: `${key}: ${err.message}${
59+
err?.params?.allowedValues
60+
? `Allowed values: ${err.params.allowedValues.join(", ")}`
61+
: ""
62+
}`,
63+
type: "error",
64+
};
65+
})
66+
);
67+
}else{
68+
setAnnotations([]);
69+
}
70+
}catch(err){
71+
constinstancePathArr=err?.instancePath?.split("/");
72+
constkey=
73+
instancePathArr&&instancePathArr[instancePathArr.length-1];
74+
75+
setAnnotations([
76+
{
77+
row: err.instancePath ? getLineNumber(yaml,err.instancePath) : 0,
78+
column: 0,
79+
text:
80+
`${key}: ${err.message}${
81+
err?.params?.allowedValues
82+
? `Allowed values: ${err.params.allowedValues.join(", ")}`
83+
: ""
84+
}`||"YAML parsing error",
85+
type: "error",
86+
},
87+
]);
88+
}
89+
}
90+
91+
functiongetLineNumber(yaml,instancePath){
92+
constlines=yaml.split("\n");
93+
constpathParts=instancePath.split("/").filter(Boolean);
94+
letcurrentObj=jsYaml.load(yaml);
95+
letlineNumber=0;
96+
97+
constlastPathPart=pathParts[pathParts.length-1];
98+
constlastPathPartIndex=pathParts.length-1;
99+
100+
for(leti=0;i<lines.length;i++){
101+
if(lines[i].trim().startsWith(pathParts[0]+":")){
102+
// Found the top-level field
103+
lineNumber=i;
104+
currentObj=currentObj[pathParts[0]];
105+
106+
for(letj=1;j<lastPathPartIndex;j++){
107+
// Go through the nested fields
108+
for(letk=lineNumber+1;k<lines.length;k++){
109+
if(lines[k].trim().startsWith(pathParts[j]+":")){
110+
lineNumber=k;
111+
currentObj=currentObj[pathParts[j]];
112+
break;
113+
}
114+
}
115+
}
116+
117+
// look for the last path part with array syntax as well as object syntax
118+
for(letl=lineNumber+1;l<lines.length;l++){
119+
if(lines[l].trim().startsWith(`- ${lastPathPart}:`)){
120+
lineNumber=l;
121+
break;
122+
}elseif(lines[l].trim().startsWith(lastPathPart+":")){
123+
lineNumber=l;
124+
break;
125+
}
126+
}
127+
break;
128+
}
129+
}
130+
131+
returnlineNumber;
132+
}
133+
134+
functiononChange(newValue){
135+
setValue(newValue);
136+
validateAndSetAnnotations(newValue);
137+
}
138+
139+
return(
140+
<divclassName="m4">
141+
<AceEditor
142+
mode="yaml"
143+
theme="github"
144+
onChange={onChange}
145+
value={value}
146+
name="yaml-editor"
147+
editorProps={{$blockScrolling: true}}
148+
setOptions={{
149+
useWorker: false,
150+
showPrintMargin: false,
151+
showGutter: true,
152+
}}
153+
annotations={annotations}
154+
width="100%"
155+
height="400px"
156+
/>
157+
<br/>
158+
</div>
159+
);
160+
}

0 commit comments

Comments
(0)