Skip to content

Commit f0f309a

Browse files
namedgraphclaude
andcommitted
Scope modal forms to active tab pane and promise-ify their handlers
Modals (class-instances, geo, latest, search) and the Add Data / Save As / Reconcile forms now mount inside the active pane's content-body instead of document body, with pane-scoped @id and a data-container-id hook so multiple tabs no longer collide on a single shared modal id. Selectors targeting these modals move from fixed @id to CSS classes (modal-class-instances, modal-geo, modal-latest, modal-search). Converts the access / endpoint-classes / typeahead-resource handlers from xsl:schedule-action named templates to ixsl:promise chains backed by ldh:*-response functions, matching the rest of the client. The typeahead-fetching half of ldh:ShowAddDataForm is extracted to a new ldh:LoadTypeaheads helper so callers compose the two steps explicitly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2a75032 commit f0f309a

4 files changed

Lines changed: 160 additions & 105 deletions

File tree

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/constructor.xsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ exclude-result-prefixes="#all"
391391
<xsl:template match="button[contains-token(@class, 'btn-edit-constructors')]" mode="ixsl:onclick">"
392392
<xsl:variable name="type" select="ixsl:get(., 'dataset.resourceType')" as="xs:anyURI"/>
393393

394-
<xsl:for-each select="ixsl:page()//body">
394+
<xsl:for-each select="id('tab-content', ixsl:page())/div[contains-token(@class, 'tab-pane')][contains-token(@class, 'active')]/div[contains-token(@class, 'document-body')]/div[contains-token(@class, 'content-body')]">
395395
<xsl:call-template name="ldh:LoadConstructors">
396396
<xsl:with-param name="type" select="$type"/>
397397
</xsl:call-template>

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/modal.xsl

Lines changed: 118 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ LIMIT 10
144144
</xsl:value-of>
145145
</label>
146146
<div class="controls">
147-
<span>
147+
<span data-for-class="&dh;Container &dh;Item">
148148
<input type="text" name="ou" id="remote-rdf-doc" class="resource-typeahead typeahead"/>
149149
<ul class="resource-typeahead typeahead dropdown-menu" id="ul-upload-rdf-doc" style="display: none;"></ul>
150150
</span>
@@ -395,7 +395,7 @@ LIMIT 10
395395
</fieldset>
396396

397397
<div id="request-access-matrix">
398-
<!-- content replaced by the onAccessResponseLoad callback -->
398+
<!-- content replaced by the ldh:access-response callback -->
399399
</div>
400400

401401
<div class="form-actions modal-footer">
@@ -978,22 +978,34 @@ LIMIT 10
978978
</xsl:template>
979979

980980
<xsl:template match="button[contains-token(@class, 'btn-add-ontology')]" mode="ixsl:onclick">
981-
<xsl:call-template name="ldh:ShowAddDataForm">
981+
<xsl:variable name="target" select="id('tab-content', ixsl:page())/div[contains-token(@class, 'tab-pane')][contains-token(@class, 'active')]/div[contains-token(@class, 'document-body')]/div[contains-token(@class, 'content-body')]" as="element()"/>
982+
<xsl:variable name="graph" select="ldh:base-uri(.)" as="xs:anyURI"/>
983+
984+
<xsl:call-template name="ldh:ShowModalForm">
982985
<xsl:with-param name="form" as="element()">
983986
<xsl:call-template name="ldh:AddDataForm">
984987
<xsl:with-param name="action" select="ldh:href(resolve-uri('transform', ldt:base()), map{})"/>
985988
<xsl:with-param name="query" select="resolve-uri('queries/construct-constructors/#this', ldt:base())"/>
986989
<xsl:with-param name="legend-label" select="ac:label(key('resources', 'import-ontology', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri))))"/>
987990
</xsl:call-template>
988991
</xsl:with-param>
992+
<xsl:with-param name="target" select="$target"/>
993+
</xsl:call-template>
994+
995+
<xsl:call-template name="ldh:LoadTypeaheads">
996+
<xsl:with-param name="typeahead-spans" select="(id('upload-rdf-doc', ixsl:page())/.., id('remote-rdf-doc', ixsl:page())/..)"/>
997+
<xsl:with-param name="graph" select="$graph"/>
989998
</xsl:call-template>
990999
</xsl:template>
9911000

9921001
<xsl:template match="button[contains-token(@class, 'btn-generate-containers')]" mode="ixsl:onclick">
993-
<xsl:call-template name="ldh:ShowAddDataForm">
1002+
<xsl:variable name="target" select="id('tab-content', ixsl:page())/div[contains-token(@class, 'tab-pane')][contains-token(@class, 'active')]/div[contains-token(@class, 'document-body')]/div[contains-token(@class, 'content-body')]" as="element()"/>
1003+
1004+
<xsl:call-template name="ldh:ShowModalForm">
9941005
<xsl:with-param name="form" as="element()">
9951006
<xsl:call-template name="ldh:GenerateContainersForm"/>
9961007
</xsl:with-param>
1008+
<xsl:with-param name="target" select="$target"/>
9971009
</xsl:call-template>
9981010
</xsl:template>
9991011

@@ -1065,22 +1077,28 @@ LIMIT 10
10651077
<!-- TO-DO: fix for admin apps -->
10661078
<xsl:param name="this" select="ac:absolute-path(ldh:base-uri(.))" as="xs:anyURI"/>
10671079
<xsl:variable name="request-uri" select="ldh:href(ac:build-uri(resolve-uri('access', lapp:origin($this)), map{ 'this': $this }))" as="xs:anyURI"/>
1068-
<xsl:variable name="request" as="item()*">
1069-
<ixsl:schedule-action http-request="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }">
1070-
<xsl:call-template name="onAccessResponseLoad">
1071-
<xsl:with-param name="agent" select="$acl:agent"/>
1072-
<xsl:with-param name="this" select="$this"/>
1073-
</xsl:call-template>
1074-
</ixsl:schedule-action>
1075-
</xsl:variable>
1076-
<xsl:sequence select="$request[current-date() lt xs:date('2000-01-01')]"/>
1080+
<xsl:variable name="request" select="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }" as="map(*)"/>
1081+
<xsl:variable name="context" as="map(*)" select="
1082+
map{
1083+
'request': $request,
1084+
'agent': $acl:agent,
1085+
'this': $this
1086+
}"/>
1087+
1088+
<ixsl:promise select="
1089+
ixsl:http-request($context('request'))
1090+
=> ixsl:then(ldh:rethread-response($context, ?))
1091+
=> ixsl:then(ldh:handle-response#1)
1092+
=> ixsl:then(ldh:access-response#1)
1093+
" on-failure="ldh:promise-failure#1"/>
10771094
</xsl:template>
10781095

10791096
<xsl:template match="button[contains-token(@class, 'btn-reconcile')]" mode="ixsl:onclick">
10801097
<xsl:variable name="resource" select="input[@name = 'resource']/@value" as="xs:anyURI"/>
10811098
<xsl:variable name="label" select="input[@name = 'label']/@value" as="xs:string"/>
10821099
<xsl:variable name="service" select="input[@name = 'service']/@value" as="xs:anyURI"/>
1083-
1100+
<xsl:variable name="target" select="id('tab-content', ixsl:page())/div[contains-token(@class, 'tab-pane')][contains-token(@class, 'active')]/div[contains-token(@class, 'document-body')]/div[contains-token(@class, 'content-body')]" as="element()"/>
1101+
10841102
<xsl:call-template name="ldh:ShowModalForm">
10851103
<xsl:with-param name="form" as="element()">
10861104
<xsl:call-template name="ldh:ReconcileForm">
@@ -1089,6 +1107,7 @@ LIMIT 10
10891107
<xsl:with-param name="service" select="$service"/>
10901108
</xsl:call-template>
10911109
</xsl:with-param>
1110+
<xsl:with-param name="target" select="$target"/>
10921111
</xsl:call-template>
10931112
</xsl:template>
10941113

@@ -1198,15 +1217,19 @@ LIMIT 10
11981217
</xsl:variable>
11991218
<xsl:variable name="results-uri" select="ac:build-uri($endpoint, map{ 'query': $query-string })" as="xs:anyURI"/>
12001219
<xsl:variable name="request-uri" select="ldh:href($results-uri)" as="xs:anyURI"/>
1220+
<xsl:variable name="request" select="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/sparql-results+xml' } }" as="map(*)"/>
1221+
<xsl:variable name="context" as="map(*)" select="
1222+
map{
1223+
'request': $request,
1224+
'container': $fieldset
1225+
}"/>
12011226

1202-
<xsl:variable name="request" as="item()*">
1203-
<ixsl:schedule-action http-request="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/sparql-results+xml' } }" wait="$timeout">
1204-
<xsl:call-template name="onEndpointClassesLoad">
1205-
<xsl:with-param name="container" select="$fieldset"/>
1206-
</xsl:call-template>
1207-
</ixsl:schedule-action>
1208-
</xsl:variable>
1209-
<xsl:sequence select="$request[current-date() lt xs:date('2000-01-01')]"/>
1227+
<ixsl:promise select="
1228+
ixsl:http-request($context('request'))
1229+
=> ixsl:then(ldh:rethread-response($context, ?))
1230+
=> ixsl:then(ldh:handle-response#1)
1231+
=> ixsl:then(ldh:endpoint-classes-response#1)
1232+
" on-failure="ldh:promise-failure#1"/>
12101233
</xsl:template>
12111234

12121235
<!-- validate form before submitting it and show errors on required control-groups where input values are missing -->
@@ -1288,65 +1311,60 @@ LIMIT 10
12881311
</xsl:choose>
12891312
</xsl:function>
12901313

1291-
<!-- show "Add data"/"Save as" form -->
12921314

1293-
<xsl:template name="ldh:ShowAddDataForm">
1315+
<!-- show modal form -->
1316+
1317+
<xsl:template name="ldh:ShowModalForm">
12941318
<xsl:param name="form" as="element()"/>
1295-
<xsl:param name="graph" select="ldh:base-uri(.)" as="xs:anyURI?"/>
1319+
<xsl:param name="target" as="element()"/>
12961320

1297-
<!-- don't append the div if it's already there -->
1321+
<!-- per-pane modal ids guarantee uniqueness, so the page-wide existence check suffices -->
12981322
<xsl:if test="not(id($form/@id, ixsl:page()))">
1299-
<xsl:for-each select="ixsl:page()//body">
1300-
<!-- append modal div to body -->
1323+
<xsl:for-each select="$target">
13011324
<xsl:result-document href="?." method="ixsl:append-content">
13021325
<xsl:sequence select="$form"/>
13031326
</xsl:result-document>
13041327

1305-
<xsl:if test="$graph">
1306-
<xsl:variable name="request-uri" select="ldh:href($graph, map{})" as="xs:anyURI"/>
1307-
<!-- fill the container typeahead values for both #upload-rdf-doc and #remote-rdf-doc -->
1308-
<xsl:for-each select="(id('upload-rdf-doc', ixsl:page())/.., id('remote-rdf-doc', ixsl:page())/..)">
1309-
<xsl:variable name="request" as="item()*">
1310-
<ixsl:schedule-action http-request="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }">
1311-
<xsl:call-template name="onTypeaheadResourceLoad">
1312-
<xsl:with-param name="resource-uri" select="$graph"/>
1313-
<xsl:with-param name="typeahead-span" select="."/>
1314-
</xsl:call-template>
1315-
</ixsl:schedule-action>
1316-
</xsl:variable>
1317-
<xsl:sequence select="$request[current-date() lt xs:date('2000-01-01')]"/>
1318-
</xsl:for-each>
1319-
</xsl:if>
1320-
13211328
<ixsl:set-style name="cursor" select="'default'"/>
13221329
</xsl:for-each>
13231330
</xsl:if>
13241331
</xsl:template>
13251332

1326-
<!-- show modal form -->
1327-
1328-
<xsl:template name="ldh:ShowModalForm">
1329-
<xsl:param name="form" as="element()"/>
1330-
1331-
<!-- don't append the div if it's already there -->
1332-
<xsl:if test="not(id($form/@id, ixsl:page()))">
1333-
<xsl:for-each select="ixsl:page()//body">
1334-
<!-- append modal div to body -->
1335-
<xsl:result-document href="?." method="ixsl:append-content">
1336-
<xsl:sequence select="$form"/>
1337-
</xsl:result-document>
1333+
<!-- populate typeahead spans inside a freshly-appended form modal with values from $graph -->
13381334

1339-
<ixsl:set-style name="cursor" select="'default'"/>
1340-
</xsl:for-each>
1341-
</xsl:if>
1335+
<xsl:template name="ldh:LoadTypeaheads">
1336+
<xsl:param name="typeahead-spans" as="element()*"/>
1337+
<xsl:param name="graph" as="xs:anyURI"/>
1338+
1339+
<xsl:variable name="request-uri" select="ldh:href($graph, map{})" as="xs:anyURI"/>
1340+
<xsl:variable name="request" select="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }" as="map(*)"/>
1341+
<xsl:for-each select="$typeahead-spans">
1342+
<xsl:variable name="context" as="map(*)" select="
1343+
map{
1344+
'request': $request,
1345+
'resource-uri': $graph,
1346+
'typeahead-span': .
1347+
}"/>
1348+
<ixsl:promise select="
1349+
ixsl:http-request($context('request'))
1350+
=> ixsl:then(ldh:rethread-response($context, ?))
1351+
=> ixsl:then(ldh:handle-response#1)
1352+
=> ixsl:then(ldh:typeahead-resource-response#1)
1353+
" on-failure="ldh:promise-failure#1"/>
1354+
</xsl:for-each>
13421355
</xsl:template>
13431356

13441357
<!-- render schema classes loaded from a SPARQL endpoint -->
1345-
1346-
<xsl:template name="onEndpointClassesLoad">
1347-
<xsl:context-item as="map(*)" use="required"/>
1348-
<xsl:param name="container" as="element()"/>
1349-
<xsl:param name="arg-bnode-id" select="'generate'" as="xs:string"/>
1358+
1359+
<xsl:function name="ldh:endpoint-classes-response" ixsl:updating="yes">
1360+
<xsl:param name="context" as="map(*)"/>
1361+
<xsl:variable name="response" select="$context('response')" as="map(*)"/>
1362+
<xsl:variable name="status" select="$response?status" as="xs:double"/>
1363+
<xsl:variable name="media-type" select="$response?media-type" as="xs:string?"/>
1364+
<xsl:variable name="container" select="$context('container')" as="element()"/>
1365+
<xsl:variable name="arg-bnode-id" select="if (map:contains($context, 'arg-bnode-id')) then $context('arg-bnode-id') else 'generate'" as="xs:string"/>
1366+
1367+
<xsl:message>ldh:endpoint-classes-response</xsl:message>
13501368

13511369
<!-- append the controls for the class list if they don't exist -->
13521370
<xsl:for-each select="$container[not(./div[contains-token(@class, 'endpoint-classes')])]">
@@ -1365,8 +1383,8 @@ LIMIT 10
13651383
<ixsl:set-style name="cursor" select="'default'" object="ixsl:page()//body"/>
13661384

13671385
<xsl:choose>
1368-
<xsl:when test="?status = 200 and ?media-type = 'application/sparql-results+xml'">
1369-
<xsl:for-each select="?body">
1386+
<xsl:when test="$status = 200 and $media-type = 'application/sparql-results+xml'">
1387+
<xsl:for-each select="$response?body">
13701388
<xsl:variable name="results" select="." as="document-node()"/>
13711389

13721390
<!-- populate the class list within div.controls -->
@@ -1406,8 +1424,8 @@ LIMIT 10
14061424
</xsl:for-each>
14071425
</xsl:when>
14081426
<xsl:otherwise>
1409-
<xsl:variable name="message" select="?message" as="xs:string?"/>
1410-
1427+
<xsl:variable name="message" select="$response?message" as="xs:string?"/>
1428+
14111429
<xsl:for-each select="$container//div[contains-token(@class, 'endpoint-classes')]/div">
14121430
<xsl:result-document href="?." method="ixsl:replace-content">
14131431
<div class="alert alert-block">
@@ -1424,16 +1442,21 @@ LIMIT 10
14241442
</xsl:for-each>
14251443
</xsl:otherwise>
14261444
</xsl:choose>
1427-
</xsl:template>
1445+
</xsl:function>
14281446

1429-
<xsl:template name="onTypeaheadResourceLoad">
1430-
<xsl:context-item as="map(*)" use="required"/>
1431-
<xsl:param name="resource-uri" as="xs:anyURI"/>
1432-
<xsl:param name="typeahead-span" as="element()"/>
1447+
<xsl:function name="ldh:typeahead-resource-response" ixsl:updating="yes">
1448+
<xsl:param name="context" as="map(*)"/>
1449+
<xsl:variable name="response" select="$context('response')" as="map(*)"/>
1450+
<xsl:variable name="status" select="$response?status" as="xs:double"/>
1451+
<xsl:variable name="media-type" select="$response?media-type" as="xs:string?"/>
1452+
<xsl:variable name="resource-uri" select="$context('resource-uri')" as="xs:anyURI"/>
1453+
<xsl:variable name="typeahead-span" select="$context('typeahead-span')" as="element()"/>
1454+
1455+
<xsl:message>ldh:typeahead-resource-response</xsl:message>
14331456

14341457
<xsl:choose>
1435-
<xsl:when test="?status = 200 and ?media-type = 'application/rdf+xml'">
1436-
<xsl:for-each select="?body">
1458+
<xsl:when test="$status = 200 and $media-type = 'application/rdf+xml'">
1459+
<xsl:for-each select="$response?body">
14371460
<xsl:variable name="resource" select="key('resources', $resource-uri)" as="element()?"/>
14381461

14391462
<xsl:choose>
@@ -1462,31 +1485,38 @@ LIMIT 10
14621485
</xsl:for-each>
14631486
</xsl:when>
14641487
<xsl:otherwise>
1465-
<xsl:sequence select="ixsl:call(ixsl:window(), 'alert', [ ?message ])"/>
1488+
<xsl:sequence select="ldh:error-response-alert($context)"/>
14661489
</xsl:otherwise>
14671490
</xsl:choose>
1468-
1491+
14691492
<ixsl:set-style name="cursor" select="'default'" object="ixsl:page()//body"/>
1470-
</xsl:template>
1493+
</xsl:function>
14711494

1472-
<xsl:template name="onAccessResponseLoad">
1473-
<xsl:context-item as="map(*)" use="required"/>
1474-
<xsl:param name="agent" as="xs:anyURI"/>
1475-
<xsl:param name="this" as="xs:anyURI"/>
1495+
<xsl:function name="ldh:access-response" ixsl:updating="yes">
1496+
<xsl:param name="context" as="map(*)"/>
1497+
<xsl:variable name="response" select="$context('response')" as="map(*)"/>
1498+
<xsl:variable name="status" select="$response?status" as="xs:double"/>
1499+
<xsl:variable name="media-type" select="$response?media-type" as="xs:string?"/>
1500+
<xsl:variable name="agent" select="$context('agent')" as="xs:anyURI"/>
1501+
<xsl:variable name="this" select="$context('this')" as="xs:anyURI"/>
1502+
1503+
<xsl:message>ldh:access-response</xsl:message>
14761504

14771505
<xsl:choose>
1478-
<xsl:when test="?status = 200 and ?media-type = 'application/rdf+xml'">
1479-
<xsl:variable name="body" select="?body" as="document-node()"/>
1480-
1506+
<xsl:when test="$status = 200 and $media-type = 'application/rdf+xml'">
1507+
<xsl:variable name="body" select="$response?body" as="document-node()"/>
1508+
<xsl:variable name="target" select="id('tab-content', ixsl:page())/div[contains-token(@class, 'tab-pane')][contains-token(@class, 'active')]/div[contains-token(@class, 'document-body')]/div[contains-token(@class, 'content-body')]" as="element()"/>
1509+
14811510
<xsl:call-template name="ldh:ShowModalForm">
14821511
<xsl:with-param name="form" as="element()">
14831512
<xsl:apply-templates select="$body" mode="ldh:RequestAccessForm">
14841513
<xsl:with-param name="this" select="$this"/>
14851514
<xsl:with-param name="agent" select="$agent"/>
14861515
</xsl:apply-templates>
14871516
</xsl:with-param>
1517+
<xsl:with-param name="target" select="$target"/>
14881518
</xsl:call-template>
1489-
1519+
14901520
<xsl:for-each select="id('request-access-matrix', ixsl:page())">
14911521
<xsl:result-document href="?." method="ixsl:replace-content">
14921522
<xsl:apply-templates select="$body/rdf:RDF" mode="request-access-matrix">
@@ -1497,10 +1527,10 @@ LIMIT 10
14971527
</xsl:for-each>
14981528
</xsl:when>
14991529
<xsl:otherwise>
1500-
<xsl:sequence select="ixsl:call(ixsl:window(), 'alert', [ ?message ])"/>
1530+
<xsl:sequence select="ldh:error-response-alert($context)"/>
15011531
</xsl:otherwise>
15021532
</xsl:choose>
1503-
</xsl:template>
1533+
</xsl:function>
15041534

15051535
<xsl:function name="ldh:settings-form-response" ixsl:updating="yes">
15061536
<xsl:param name="context" as="map(*)"/>

0 commit comments

Comments
 (0)