Skip to content

Commit 90a34b5

Browse files
committed
feat(react): new 'page' concept for defining custom endpoints
Instead of opening a node you open a page that calls a named renderer. This allows designing UIs that have a different structure than the AST.
1 parent 44444f6 commit 90a34b5

File tree

7 files changed

+254
-6
lines changed

7 files changed

+254
-6
lines changed

mps/.mps/modules.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<modulePath path="$PROJECT_DIR$/modules/org.modelix.mps.webaspect.devkit/org.modelix.mps.webaspect.devkit.devkit" folder="aspect" />
1111
<modulePath path="$PROJECT_DIR$/modules/org.modelix.mps.webaspect.genplan/org.modelix.mps.webaspect.genplan.msd" folder="aspect" />
1212
<modulePath path="$PROJECT_DIR$/modules/org.modelix.mps.webaspect.runtime/org.modelix.mps.webaspect.runtime.msd" folder="aspect" />
13+
<modulePath path="$PROJECT_DIR$/modules/test.org.modelix.webaspect/test.org.modelix.webaspect.msd" folder="test" />
1314
</projectModules>
1415
</component>
1516
</project>

mps/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ mpsBuild {
4646
module("org.modelix.mps.webaspect.devkit")
4747
module("org.modelix.mps.webaspect.genplan")
4848
}
49+
publication("tests") {
50+
module("test.org.modelix.webaspect")
51+
}
4952
}
5053

5154
tasks.all {

mps/modules/org.modelix.mps.react/models/org.modelix.mps.react.editor.mps

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@
135135
</concept>
136136
<concept id="1223387125302" name="jetbrains.mps.lang.editor.structure.QueryFunction_Boolean" flags="in" index="3nzxsE" />
137137
<concept id="1088185857835" name="jetbrains.mps.lang.editor.structure.InlineEditorComponent" flags="ig" index="1sVBvm" />
138-
<concept id="5425882385312046132" name="jetbrains.mps.lang.editor.structure.QueryFunctionParameter_SubstituteMenu_CurrentTargetNode" flags="nn" index="1yR$tW" />
139138
<concept id="1215007762405" name="jetbrains.mps.lang.editor.structure.FloatStyleClassItem" flags="ln" index="3$6MrZ">
140139
<property id="1215007802031" name="value" index="3$6WeP" />
141140
</concept>
@@ -2203,6 +2202,12 @@
22032202
</node>
22042203
</node>
22052204
</node>
2205+
<node concept="3F0ifn" id="G8IVG9FtGL" role="3EZMnx">
2206+
<property role="3F0ifm" value="/" />
2207+
<node concept="11L4FC" id="G8IVG9FtGN" role="3F10Kt">
2208+
<property role="VOm3f" value="true" />
2209+
</node>
2210+
</node>
22062211
<node concept="2iRfu4" id="6eUjE42hpKT" role="2iSdaV" />
22072212
</node>
22082213
</node>
@@ -2277,7 +2282,13 @@
22772282
<node concept="1pGfFk" id="6eUjE42rIP2" role="2ShVmc">
22782283
<property role="373rjd" value="true" />
22792284
<ref role="37wK5l" to="j809:~FailingPropertyConstraintContext.&lt;init&gt;(org.jetbrains.mps.openapi.model.SNode,org.jetbrains.mps.openapi.language.SProperty,java.lang.Object)" resolve="FailingPropertyConstraintContext" />
2280-
<node concept="1yR$tW" id="6eUjE42rJB3" role="37wK5m" />
2285+
<node concept="2ShNRf" id="G8IVG9Do8D" role="37wK5m">
2286+
<node concept="3zrR0B" id="G8IVG9DNHG" role="2ShVmc">
2287+
<node concept="3Tqbb2" id="G8IVG9DNHI" role="3zrR0E">
2288+
<ref role="ehGHo" to="8xo1:6eUjE42hnW_" resolve="StaticPagePathPart" />
2289+
</node>
2290+
</node>
2291+
</node>
22812292
<node concept="355D3s" id="6eUjE42rK1L" role="37wK5m">
22822293
<ref role="355D3t" to="8xo1:6eUjE42hnW_" resolve="StaticPagePathPart" />
22832294
<ref role="355D3u" to="8xo1:6eUjE42hnWA" resolve="value" />
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<model ref="r:cb4ea846-d62a-4b22-b433-1f1188720a47(test.org.modelix.webaspect.modelix)">
3+
<persistence version="9" />
4+
<languages>
5+
<devkit ref="46d68387-81c7-4c54-9dd2-2717eb3f009b(org.modelix.mps.webaspect.devkit)" />
6+
</languages>
7+
<imports>
8+
<import index="jh6v" ref="r:f2f39a18-fd23-4090-b7f2-ba8da340eec2(org.modelix.model.repositoryconcepts.structure)" />
9+
<import index="tpck" ref="r:00000000-0000-4000-0000-011c89590288(jetbrains.mps.lang.core.structure)" />
10+
</imports>
11+
<registry>
12+
<language id="67accce2-9676-4728-9e9c-8b15ea30d924" name="org.modelix.mps.react">
13+
<concept id="8876946878574531757" name="org.modelix.mps.react.structure.TextComponent" flags="ng" index="ggXia">
14+
<child id="8876946878574531775" name="value" index="ggXio" />
15+
</concept>
16+
<concept id="8876946878574654557" name="org.modelix.mps.react.structure.PrimitivePropertyValue" flags="ng" index="ghjhU">
17+
<child id="8876946878574654571" name="value" index="ghjhc" />
18+
</concept>
19+
<concept id="8876946878573696709" name="org.modelix.mps.react.structure.ReactModule" flags="ng" index="gl9ry">
20+
<child id="8876946878573903290" name="content" index="gmrQt" />
21+
</concept>
22+
<concept id="8876946878573903439" name="org.modelix.mps.react.structure.GenericReactComponent" flags="ng" index="gmrTC">
23+
<property id="8876946878573977569" name="componentType" index="gmPZ6" />
24+
<child id="8876946878574187978" name="properties" index="gn1nH" />
25+
<child id="8876946878574187976" name="children" index="gn1nJ" />
26+
</concept>
27+
<concept id="8876946878574187981" name="org.modelix.mps.react.structure.Property" flags="ng" index="gn1nE">
28+
<property id="8876946878574187995" name="propertyName" index="gn1nW" />
29+
<child id="8876946878574187997" name="value" index="gn1nU" />
30+
</concept>
31+
<concept id="1612157992440222093" name="org.modelix.mps.react.structure.ForEachInteratorVariableReference" flags="ng" index="rqPyE">
32+
<reference id="1612157992440222094" name="forEach" index="rqPyD" />
33+
</concept>
34+
<concept id="1612157992440089595" name="org.modelix.mps.react.structure.ForEachComponent" flags="ng" index="rrkbs">
35+
<child id="1612157992440089646" name="input" index="rrkk9" />
36+
<child id="1612157992440089600" name="component" index="rrkkB" />
37+
</concept>
38+
<concept id="5355184975880615610" name="org.modelix.mps.react.structure.NamedRendererParameter" flags="ng" index="2rzwrA">
39+
<child id="5355184975880615618" name="type" index="2rzwqu" />
40+
</concept>
41+
<concept id="5355184975880615607" name="org.modelix.mps.react.structure.NamedRenderer" flags="ng" index="2rzwrF" />
42+
<concept id="5355184975881978516" name="org.modelix.mps.react.structure.CallNamedRenderer" flags="ng" index="2rDjb8">
43+
<reference id="5355184975881978525" name="renderer" index="2rDjb1" />
44+
<child id="5355184975881978527" name="parameterValues" index="2rDjb3" />
45+
</concept>
46+
<concept id="5355184975880958844" name="org.modelix.mps.react.structure.NamedRendererParameterReference" flags="ng" index="2rHscw">
47+
<reference id="5355184975880958845" name="decl" index="2rHscx" />
48+
</concept>
49+
<concept id="5355184975881056557" name="org.modelix.mps.react.structure.NamedRendererBase" flags="ng" index="2rHO5L">
50+
<child id="5355184975881056561" name="parameters" index="2rHO5H" />
51+
<child id="5355184975881056562" name="components" index="2rHO5I" />
52+
</concept>
53+
<concept id="7186142608857783837" name="org.modelix.mps.react.structure.ContextRepositoryExpression" flags="ng" index="1xZx2W" />
54+
<concept id="7186142608857762387" name="org.modelix.mps.react.structure.Page" flags="ng" index="1xZ$jM">
55+
<child id="7186142608858233588" name="path" index="1xWnhl" />
56+
<child id="7186142608857776878" name="content" index="1xZwLf" />
57+
</concept>
58+
<concept id="7186142608857847244" name="org.modelix.mps.react.structure.PagePath" flags="ng" index="1xZLHH">
59+
<child id="7186142608857857834" name="parts" index="1xZN6b" />
60+
</concept>
61+
<concept id="7186142608857857829" name="org.modelix.mps.react.structure.StaticPagePathPart" flags="ng" index="1xZN64">
62+
<property id="7186142608857857830" name="value" index="1xZN67" />
63+
</concept>
64+
<concept id="793519207835900435" name="org.modelix.mps.react.structure.EmptyContent" flags="ng" index="3ywjYg" />
65+
</language>
66+
<language id="f3061a53-9226-4cc5-a443-f952ceaf5816" name="jetbrains.mps.baseLanguage">
67+
<concept id="1197027756228" name="jetbrains.mps.baseLanguage.structure.DotExpression" flags="nn" index="2OqwBi">
68+
<child id="1197027771414" name="operand" index="2Oq$k0" />
69+
<child id="1197027833540" name="operation" index="2OqNvi" />
70+
</concept>
71+
<concept id="1070475926800" name="jetbrains.mps.baseLanguage.structure.StringLiteral" flags="nn" index="Xl_RD">
72+
<property id="1070475926801" name="value" index="Xl_RC" />
73+
</concept>
74+
<concept id="1068581242875" name="jetbrains.mps.baseLanguage.structure.PlusExpression" flags="nn" index="3cpWs3" />
75+
<concept id="1081773326031" name="jetbrains.mps.baseLanguage.structure.BinaryOperation" flags="nn" index="3uHJSO">
76+
<child id="1081773367579" name="rightExpression" index="3uHU7w" />
77+
<child id="1081773367580" name="leftExpression" index="3uHU7B" />
78+
</concept>
79+
</language>
80+
<language id="7866978e-a0f0-4cc7-81bc-4d213d9375e1" name="jetbrains.mps.lang.smodel">
81+
<concept id="1138055754698" name="jetbrains.mps.lang.smodel.structure.SNodeType" flags="in" index="3Tqbb2">
82+
<reference id="1138405853777" name="concept" index="ehGHo" />
83+
</concept>
84+
<concept id="1138056022639" name="jetbrains.mps.lang.smodel.structure.SPropertyAccess" flags="nn" index="3TrcHB">
85+
<reference id="1138056395725" name="property" index="3TsBF5" />
86+
</concept>
87+
<concept id="1138056282393" name="jetbrains.mps.lang.smodel.structure.SLinkListAccess" flags="nn" index="3Tsc0h">
88+
<reference id="1138056546658" name="link" index="3TtcxE" />
89+
</concept>
90+
</language>
91+
<language id="ceab5195-25ea-4f22-9b92-103b95ca8c0c" name="jetbrains.mps.lang.core">
92+
<concept id="1169194658468" name="jetbrains.mps.lang.core.structure.INamedConcept" flags="ngI" index="TrEIO">
93+
<property id="1169194664001" name="name" index="TrG5h" />
94+
</concept>
95+
</language>
96+
</registry>
97+
<node concept="gl9ry" id="6eUjE42h0De">
98+
<property role="TrG5h" value="pages" />
99+
<node concept="1xZ$jM" id="6eUjE42q5xy" role="gmrQt">
100+
<node concept="1xZLHH" id="6eUjE42q5x$" role="1xWnhl">
101+
<node concept="1xZN64" id="G8IVG9Fnkz" role="1xZN6b">
102+
<property role="1xZN67" value="modelix" />
103+
</node>
104+
<node concept="1xZN64" id="6eUjE42qNC7" role="1xZN6b">
105+
<property role="1xZN67" value="test" />
106+
</node>
107+
<node concept="1xZN64" id="G8IVG9FmFQ" role="1xZN6b">
108+
<property role="1xZN67" value="modules-list" />
109+
</node>
110+
</node>
111+
<node concept="2rDjb8" id="6eUjE42sp_X" role="1xZwLf">
112+
<ref role="2rDjb1" node="6eUjE42h0Dw" resolve="main" />
113+
<node concept="1xZx2W" id="6eUjE42spA5" role="2rDjb3" />
114+
</node>
115+
</node>
116+
<node concept="3ywjYg" id="6eUjE42q5xx" role="gmrQt" />
117+
<node concept="2rzwrF" id="6eUjE42h0Dw" role="gmrQt">
118+
<property role="TrG5h" value="main" />
119+
<node concept="2rzwrA" id="6eUjE42h0Dz" role="2rHO5H">
120+
<property role="TrG5h" value="repository" />
121+
<node concept="3Tqbb2" id="6eUjE42h0DH" role="2rzwqu">
122+
<ref role="ehGHo" to="jh6v:qmkA5fOskm" resolve="Repository" />
123+
</node>
124+
</node>
125+
<node concept="gmrTC" id="G8IVG9FmFY" role="2rHO5I">
126+
<property role="gmPZ6" value="html.ul" />
127+
<node concept="rrkbs" id="6eUjE42h7AY" role="gn1nJ">
128+
<property role="TrG5h" value="module" />
129+
<node concept="gmrTC" id="6eUjE42hjbe" role="rrkkB">
130+
<property role="gmPZ6" value="html.li" />
131+
<node concept="gn1nE" id="GzuF_KKeEI" role="gn1nH">
132+
<property role="gn1nW" value="class" />
133+
<node concept="ghjhU" id="GzuF_KKeEL" role="gn1nU">
134+
<node concept="Xl_RD" id="GzuF_KKeEK" role="ghjhc">
135+
<property role="Xl_RC" value="module" />
136+
</node>
137+
</node>
138+
</node>
139+
<node concept="ggXia" id="6eUjE42hjf7" role="gn1nJ">
140+
<node concept="3cpWs3" id="6eUjE42hkeR" role="ggXio">
141+
<node concept="2OqwBi" id="6eUjE42hkFH" role="3uHU7w">
142+
<node concept="rqPyE" id="6eUjE42hkeZ" role="2Oq$k0">
143+
<ref role="rqPyD" node="6eUjE42h7AY" resolve="module" />
144+
</node>
145+
<node concept="3TrcHB" id="6eUjE42hl1f" role="2OqNvi">
146+
<ref role="3TsBF5" to="tpck:h0TrG11" resolve="name" />
147+
</node>
148+
</node>
149+
<node concept="Xl_RD" id="6eUjE42hjf9" role="3uHU7B">
150+
<property role="Xl_RC" value="Module: " />
151+
</node>
152+
</node>
153+
</node>
154+
</node>
155+
<node concept="2OqwBi" id="6eUjE42hiY7" role="rrkk9">
156+
<node concept="2rHscw" id="6eUjE42hiNW" role="2Oq$k0">
157+
<ref role="2rHscx" node="6eUjE42h0Dz" resolve="repository" />
158+
</node>
159+
<node concept="3Tsc0h" id="6eUjE42hj7i" role="2OqNvi">
160+
<ref role="3TtcxE" to="jh6v:qmkA5fOskn" />
161+
</node>
162+
</node>
163+
</node>
164+
</node>
165+
</node>
166+
<node concept="3ywjYg" id="6eUjE42h0Dv" role="gmrQt" />
167+
</node>
168+
</model>
169+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<solution name="test.org.modelix.webaspect" uuid="449beddd-ca19-4e39-bf87-81fca480320a" moduleVersion="0">
3+
<models>
4+
<modelRoot contentPath="${module}" type="default">
5+
<sourceRoot path="${module}/models" />
6+
</modelRoot>
7+
</models>
8+
<facets>
9+
<facet type="java" compile="mps" classes="mps" ext="no">
10+
<classes generated="true" path="${module}/classes_gen" />
11+
</facet>
12+
</facets>
13+
<dependencies>
14+
<dependency reexport="false">0a7577d1-d4e5-431d-98b1-fae38f9aee80(org.modelix.model.repositoryconcepts)</dependency>
15+
<dependency reexport="false">ceab5195-25ea-4f22-9b92-103b95ca8c0c(jetbrains.mps.lang.core)</dependency>
16+
<dependency reexport="false">83a7cbdc-dd9d-4dad-be97-957aa1b07375(org.modelix.mps.react.ssr.stubs)</dependency>
17+
</dependencies>
18+
<languageVersions>
19+
<language slang="l:f3061a53-9226-4cc5-a443-f952ceaf5816:jetbrains.mps.baseLanguage" version="12" />
20+
<language slang="l:fd392034-7849-419d-9071-12563d152375:jetbrains.mps.baseLanguage.closures" version="0" />
21+
<language slang="l:83888646-71ce-4f1c-9c53-c54016f6ad4f:jetbrains.mps.baseLanguage.collections" version="2" />
22+
<language slang="l:515552c7-fcc0-4ab4-9789-2f3c49344e85:jetbrains.mps.baseLanguage.varVariable" version="0" />
23+
<language slang="l:df345b11-b8c7-4213-ac66-48d2a9b75d88:jetbrains.mps.baseLanguageInternal" version="0" />
24+
<language slang="l:4caf0310-491e-41f5-8a9b-2006b3a94898:jetbrains.mps.execution.util" version="0" />
25+
<language slang="l:6b3888c1-9802-44d8-8baf-f8e6c33ed689:jetbrains.mps.kotlin" version="13" />
26+
<language slang="l:b17a9ec8-44a5-40a1-9216-058d277424eb:jetbrains.mps.kotlin.internal" version="0" />
27+
<language slang="l:9e4ff22b-60f1-43ef-a50b-f9f0fcec22e0:jetbrains.mps.kotlin.javaRefs" version="0" />
28+
<language slang="l:eb56ebf4-df56-438e-af06-fc1cd08b495a:jetbrains.mps.kotlin.smodel" version="0" />
29+
<language slang="l:ceab5195-25ea-4f22-9b92-103b95ca8c0c:jetbrains.mps.lang.core" version="2" />
30+
<language slang="l:446c26eb-2b7b-4bf0-9b35-f83fa582753e:jetbrains.mps.lang.modelapi" version="0" />
31+
<language slang="l:7866978e-a0f0-4cc7-81bc-4d213d9375e1:jetbrains.mps.lang.smodel" version="19" />
32+
<language slang="l:c7fb639f-be78-4307-89b0-b5959c3fa8c8:jetbrains.mps.lang.text" version="0" />
33+
<language slang="l:9ded098b-ad6a-4657-bfd9-48636cfe8bc3:jetbrains.mps.lang.traceable" version="0" />
34+
<language slang="l:c7b55726-1795-47bd-aa21-714ac1e30f21:org.modelix.mps.notation" version="0" />
35+
<language slang="l:67accce2-9676-4728-9e9c-8b15ea30d924:org.modelix.mps.react" version="0" />
36+
</languageVersions>
37+
<dependencyVersions>
38+
<module reference="3f233e7f-b8a6-46d2-a57f-795d56775243(Annotations)" version="0" />
39+
<module reference="6354ebe7-c22a-4a0f-ac54-50b52ab9b065(JDK)" version="0" />
40+
<module reference="6ed54515-acc8-4d1e-a16c-9fd6cfe951ea(MPS.Core)" version="0" />
41+
<module reference="498d89d2-c2e9-11e2-ad49-6cf049e62fe5(MPS.IDEA)" version="0" />
42+
<module reference="8865b7a8-5271-43d3-884c-6fd1d9cfdd34(MPS.OpenAPI)" version="0" />
43+
<module reference="ceab5195-25ea-4f22-9b92-103b95ca8c0c(jetbrains.mps.lang.core)" version="0" />
44+
<module reference="0a7577d1-d4e5-431d-98b1-fae38f9aee80(org.modelix.model.repositoryconcepts)" version="0" />
45+
<module reference="208eaf68-fd3a-497a-a4b6-4923ff457c3b(org.modelix.mps.editor.common.stubs)" version="0" />
46+
<module reference="83a7cbdc-dd9d-4dad-be97-957aa1b07375(org.modelix.mps.react.ssr.stubs)" version="0" />
47+
<module reference="02ad200e-1634-449d-8b0b-db88f7ea0f2d(org.modelix.mps.webaspect.genplan)" version="0" />
48+
<module reference="449beddd-ca19-4e39-bf87-81fca480320a(test.org.modelix.webaspect)" version="0" />
49+
</dependencyVersions>
50+
</solution>
51+

react-ssr-mps-test/build.gradle.kts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,25 @@ val collectPlugins by tasks.registering(Sync::class) {
1919
into(pluginsDir)
2020
}
2121

22+
val testLanguagesDir = layout.buildDirectory.dir("test-languages")
23+
val copyTestLanguages by tasks.registering(Sync::class) {
24+
dependsOn(":packageAllPlugins")
25+
from(zipTree({ project(":mps").layout.buildDirectory.file("mpsbuild/publications/tests.zip") }))
26+
into(testLanguagesDir)
27+
}
28+
2229
tasks {
2330
test {
2431
dependsOn(collectPlugins)
32+
dependsOn(copyTestLanguages)
2533
environment("MPS_VERSION", mpsVersion)
2634
environment(
2735
"MODELIX_MPS_PLUGINS_PATH",
2836
pluginsDir.get().asFile.absolutePath,
2937
)
38+
environment(
39+
"MODELIX_TEST_LANGUAGES_PATH",
40+
testLanguagesDir.get().asFile.absolutePath,
41+
)
3042
}
3143
}

react-ssr-mps-test/src/test/kotlin/PagesTest.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ class PagesTest : TestCase() {
2020
Playwright.create().use { playwright ->
2121
val browser = playwright.chromium().launch()
2222
val page = browser.newPage()
23-
page.navigate("http://localhost:$port/pages/dependency-analyzer/")
23+
page.navigate("http://localhost:$port/pages/modelix/test/modules-list/")
2424
for (i in 1..10) {
2525
delay(1.seconds)
26-
if (page.content().contains("""<div class="module">""")) break
26+
if (page.content().contains("""<li class="module">""")) break
2727
}
2828
val content = page.content()
2929
println(content)
30-
assertTrue(content.contains("""<div class="module">"""))
31-
assertTrue(content.contains("""org.modelix.mps.react"""))
30+
assertTrue(content.contains("""<li class="module">"""))
31+
assertTrue(content.contains("""Module: org.modelix.mps.react"""))
3232
}
3333
}
3434
}
@@ -40,6 +40,7 @@ fun runWithMPS(
4040
withTimeout(5.minutes) {
4141
val mps: GenericContainer<*> = GenericContainer("modelix/mps-vnc-baseimage:0.9.4-mps${System.getenv("MPS_VERSION")}")
4242
.withCopyFileToContainer(MountableFile.forHostPath(File(System.getenv("MODELIX_MPS_PLUGINS_PATH")).toPath()), "/mps/plugins")
43+
.withCopyFileToContainer(MountableFile.forHostPath(File(System.getenv("MODELIX_TEST_LANGUAGES_PATH")).toPath()), "/mps-languages")
4344
.withExposedPorts(43595)
4445
.waitingFor(Wait.forListeningPort().withStartupTimeout(3.minutes.toJavaDuration()))
4546
.withLogConsumer {

0 commit comments

Comments
 (0)