Release 2.4.0 — parameter forms, property paths and Connect your app - #133
Merged
Conversation
Bump version to 2.4.0-SNAPSHOT following the 2.3.0 release.
Post-2.3.0 back-merge and 2.4.0-SNAPSHOT bump
…lves #72 Addresses #108 Extend the Query Library UI so non-technical users can interact with parameterised queries through input fields without seeing or editing raw SPARQL. Approach: - Query parameters are declared in src/assets/query-parameters.json, a human-reviewed file generated by scripts/extract-query-parameters.js. - Each parameterised query has a template with {{placeholder}} tokens and a parameters array (label, type, placeholder name, default value). - At runtime, fillTemplate() replaces placeholders with typed literals — no regex matching of date values in the query text, no positional ambiguity, no same-default collision bugs. UI behaviour: - When a parameterised query is selected, a form appears with labelled date pickers pre-filled with default values. SPARQL is hidden behind a "Show query / Hide query" toggle. - The SPARQL preview updates live as the user changes dates. - "Try this query" validates inputs, fills the template, and executes. - "Customise" fills the template and opens the editor for further edits. - For non-parameterised queries, behaviour is unchanged (no form, SPARQL visible). Validation: - Form path: isValidDate() checks real calendar validity (rejects month 13, Feb 30, malformed shapes). Invalid fields get red border + toast notification. Execution is blocked. - Editor path: SPARQL linter flags invalid xsd:date literals with inline error markers. Run Query button is disabled when invalid dates are present, consistent with syntax error behaviour. - Injection path: fillTemplate() falls back to the declared default when a user value is invalid — the query is never broken. Maintenance: - When new queries are added to the upstream library, run node scripts/extract-query-parameters.js to generate entries for new queries (existing reviewed entries are preserved). - Review and correct the suggested labels, then commit the updated query-parameters.json. New files: - scripts/extract-query-parameters.js - src/assets/query-parameters.json - src/js/utils/queryParameters.js - test/queryParameters.test.js Modified files: - index.html (parameter form container, toggle button, SPARQL wrapper) - src/assets/style.css (parameter form styling) - src/js/QueryEditor.js (date linter, Run button disabling) - src/js/QueryLibrary.js (form rendering, validation, template filling)
…ocedure ID fields now render as text inputs for lots-associated-to-procedure and awarded-tender-amounts queries. QueryLibrary renders type-appropriate inputs and validates accordingly (non-empty for text, isValidDate for dates). - Add month/year picker support for aggregation queries: 'per month' queries now show month pickers (YYYY-MM), 'per year' query shows year inputs (2015-2035 range). fillTemplate converts month-start to first day, month-end to last day (handles leap years), year-start to Jan 1, year-end to Dec 31. - Rename 'Try this query' to 'Run query' (both top and bottom buttons). - Hide bottom action buttons by default, show only when SPARQL query is visible (avoids redundant buttons for short content). - Hide SPARQL by default for all queries (consistent behavior), togglable via 'Show query' button. - Added isValidMonth, isValidYear, lastDayOfMonth helpers with tests. Partially addresses reviewer feedback on PR #109: - Procedure ID form field (comment 1) ✓ - Month/year alignment with query titles (comment 2) ✓ - Advanced queries left as-is by design (comment 3)
…he two advanced queries: - notice-per-publication-number.sparql: text field for publication number - named-graphs-per-period.sparql: date pickers for period start/end Introduces 'date-raw' parameter type for queries using xsd:dateTime. The user picks a date, and the template contains the surrounding time and type formatting (e.g. "{{startDate}}T00:00:00"^^xsd:dateTime). fillTemplate outputs just the bare date string for this type. Also updates QueryLibrary rendering and validation to handle date-raw as a date picker with isValidDate checking.
…ext form fields too narrow: Added min-width: 320px for text inputs so procedure IDs (UUIDs) are fully readable without scrolling. 2. Field memory / stale values when switching queries: Moved _updatePreview() call to after new form fields are created. Previously it ran before replaceChildren(), reading stale values from the previous query's inputs. 3. Date range validation: Added rangeGroup/role mechanism to query-parameters.json for explicit start/end pairing. - "Run query" blocks execution when start > end (red border + toast) - "Customise" shows non-blocking yellow warning toast but opens editor - Toast message distinguishes field errors from range errors - New script scripts/add-range-groups.js automates adding rangeGroup and role fields to newly added query pairs
feat: add form mode for query library and validate dates
… exploring nested relationships in the Inspect/Reuse tree view, it was hard to track the hierarchical path taken to reach a deeply nested node, and there was no way to capture that path for reuse. This adds a "copy path" affordance to nested card headers and leaf rows. Hovering a node reveals a clipboard icon; clicking it copies a full SPARQL triple pattern snippet from the root to that node, e.g.: ?notice a epo:Notice ; epo:refersToLot / epo:hasPurpose / epo:hasMainClassification ?value . Implementation: - TreeRenderer threads a predicatePath array through the recursive render (_renderSubjectTree, _buildCardBody, _buildCardHeader, _renderPredicateObject), appending each predicate as it descends. - Each root card computes its own rootContext (type + variable name) via _buildRootContext, so multi-root graphs (Notice + Contract + SubmissionInfo) each produce correct snippets. - For resources with multiple rdf:type values (e.g. Notice, Notice29, ResultNotice), the type with the shortest local name is preferred to ensure consistent snippets regardless of triple order from the endpoint. Tested with notices 00467941-2026 and 00029093-2026. - _formatPropertyPath shrinks known-namespace predicates to prefixed form (epo:...) and wraps unknown-namespace URIs in angle brackets. - rdf:type rows are excluded (classification metadata, not useful paths). - The button is hidden by default and revealed on hover/focus. Files: - src/js/TreeRenderer.js (path threading, root context, copy button) - src/assets/style.css (hover-reveal button styling) - test/treeRenderer.test.js (_formatPropertyPath tests)
feat: add copy property path to inspect tree nodes
#74 The tree view badges previously displayed the class name extracted from the resource URI (e.g. "SettledContract"), which is a mapping-specific name that does not match the ePO ontology terminology. Now the badge type text is taken from the subject's rdf:type triple, which declares the actual ontology class (e.g. "Contract"). The type data is already in the loaded triples — no extra network call needed. Key changes: - SettledContract → Contract - Organization → Business - LotPurpose → Purpose - MonetaryValueLot/Procedure/etc → MonetaryValue - ProcurementProjectContractTerm → ContractTerm Terms whose URI segment already matches rdf:type (Lot, Procedure, Buyer, Tender, etc.) are unaffected.
fix: use rdf:type for tree badge labels instead of URI segment
…-chronological "What's new" accordion at the top of the Help tab, showing user-facing features introduced in each release: - 2.4.0: form mode, copy property path, ontology badge labels, date validation - 2.3.0: chart visualization, currency snippet, clickable URLs, execution time, not-found tracking, ePO v3+v4 autocomplete, guided tours, query library - 2.2.0: ePO 3 (Standard Forms) notice support - 2.1.0: search in tree, SPARQL reference card, Turtle prefixes - 2.0.0: explorer integration, procedure timeline, share/download, Home tab Latest release is expanded by default; older releases are collapsed. Uses the same Bootstrap accordion pattern as the Query Library.
feat: add What's new release notes section to Help tab
…The single 'Copy endpoint URL' button on the SELECT results toolbar is replaced with a 'Copy Query' dropdown offering three options: - Query link: the full GET URL (endpoint + encoded SPARQL) for use in Excel, Power BI, or any HTTP client - SPARQL query: the raw query text from the editor for pasting into other SPARQL tools - cURL command: a ready-to-paste curl POST command for terminal use Single quotes in the SPARQL body are percent-encoded (%27) in the cURL output to prevent shell injection when queries contain string literals. Also updates the guided tour step, help tab text, and the 504 timeout recovery link to use the new onShare('query-link') method.
Follow-up fixes from review:
- Renamed 'Nothing to share' toast to 'Nothing to copy' for consistency
with the Copy Query button label.
- Extracted cURL command construction into a static _buildCurlCommand()
method and added unit tests covering the single-quote escaping fix,
closing a test coverage gap for the shell-injection prevention logic.
feat: replace Copy endpoint URL with Copy Query dropdown
chore: drop version number from What's new headers
…solves #75 The query library runtime fetcher and the parameter-extraction script now read from the dedicated OP-TED/ted-open-data-examples repository instead of the ted-rdf-docs Antora module. Changes: - REMOTE_QUERIES_URL points to the new repo root (main branch) - Manifest filename changed from index.yaml to web-library.yaml - Parameter form lookup uses basename of the sparql path to match query-parameters.json keys (which are bare filenames), since the new manifest uses relative paths (e.g. queries/notices-per-day.sparql) - extract-query-parameters.js uses full path for fetch but basename for the JSON key, keeping the output format stable
Switch query library source to ted-open-data-examples
feat: add copy property path to inspect tree nodes
Tree clicks now record the predicate chain walked, so the card can show how the displayed resource is reached from the notice, as a triple pattern ready to paste into a query. Resolves #73
Addresses Anoop's review of #110: a path was reachable only on a card you had navigated to, and a literal had none at all.
# Conflicts: # src/assets/style.css # src/js/TreeRenderer.js # test/treeRenderer.test.js
…The single 'Copy endpoint URL' button on the SELECT results toolbar is replaced with a 'Copy Query' dropdown offering three options: - Query link: the full GET URL (endpoint + encoded SPARQL) for use in Excel, Power BI, or any HTTP client - SPARQL query: the raw query text from the editor for pasting into other SPARQL tools - cURL command: a ready-to-paste curl POST command for terminal use Single quotes in the SPARQL body are percent-encoded (%27) in the cURL output to prevent shell injection when queries contain string literals. Also updates the guided tour step, help tab text, and the 504 timeout recovery link to use the new onShare('query-link') method.
Follow-up fixes from review:
- Renamed 'Nothing to share' toast to 'Nothing to copy' for consistency
with the Copy Query button label.
- Extracted cURL command construction into a static _buildCurlCommand()
method and added unit tests covering the single-quote escaping fix,
closing a test coverage gap for the shell-injection prevention logic.
…solves #75 The query library runtime fetcher and the parameter-extraction script now read from the dedicated OP-TED/ted-open-data-examples repository instead of the ted-rdf-docs Antora module. Changes: - REMOTE_QUERIES_URL points to the new repo root (main branch) - Manifest filename changed from index.yaml to web-library.yaml - Parameter form lookup uses basename of the sparql path to match query-parameters.json keys (which are bare filenames), since the new manifest uses relative paths (e.g. queries/notices-per-day.sparql) - extract-query-parameters.js uses full path for fetch but basename for the JSON key, keeping the output format stable
The query library moved, but the contribute links still sent people to a guide for the repository it moved out of.
Bootstrap holds every popover until dispose(), and a disposed one is empty — so the teardown both disposes and drops the reference, once, for all four ways a card closes. Without animation, since hide() must finish before dispose().
# Conflicts: # src/js/TreeRenderer.js
Property path on the SPARQL reference card (rework of #110)
Name resources from the types they declare (rework of #111)
Connect your app: sharing the query as a request (rework of #113)
Query library reads from ted-open-data-examples (rework of #115)
Reject impossible dates before a query runs
Offer a query's values as a form, read from the query itself
Conflicts resolved to this line, which re-implements the same features; develop's CI workflows taken as they are.
2.4.0: the reworked line
Anoop-Variyan
approved these changes
Aug 26, 2026
Anoop-Variyan
left a comment
Contributor
There was a problem hiding this comment.
Verified: version bump to 2.4.0 is the only diff from the already-approved rework/2.4.0 (#132). 701/701 tests pass, lint clean, CI green. Manually tested all features in the browser, including form mode (temporarily against ted-open-data-examples/develop, since annotations aren't on main yet — reverted after testing). Confirmed OP-TED/ted-open-data-examples#15 is still open, matching the PR's own note that form mode stays inert until it merges. Approving.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cut from
developat 234570a, which is the reworked 2.4.0 line after #132.What is in it
Property path on the SPARQL reference card (#73) — every card and row carries a menu; the card shows the triple pattern that reaches the resource, ready to paste into a query.
Resources named from the types they declare (#74) — a badge reads the class from the resource's own
rdf:typerather than guessing from its URI, so aSettledContractshows asContract.Connect your app (#103) — the results toolbar offers the query as a request: a link in JSON, CSV, TSV or XML for Excel or Power BI, the raw SPARQL, and the same call as cURL, wget or PowerShell.
Query library read from
ted-open-data-examples(#75) — queries live in their own repository and reach readers when published there, with no release of this application.What's new (#106) — the release notes sit beside the help text rather than on top of it.
Impossible dates refused before a query runs (#108) — the 31st of February is not an error the endpoint reports: the query runs and returns nothing, which reads as an answer. Dates, times and dates-and-times are all now checked, in the editor and in the parameter form.
A query's values offered as a form (#72) — a library query can name a variable in a comment, and pressing Run offers that value as a field. The type of the field, what it opens with, and whether two bounds are a range are all read from the query itself; the comment carries only the label.
Plus, across the application: the tree view holds together on a narrow window, and eslint is enabled.
Before this is deployed
OP-TED/ted-open-data-examples#15 must reach
mainfirst. The parameter annotations live there and are ondevelop; until they are published, a library query has nothing for the form to read and Run behaves as it always did. Nothing breaks either way — the feature is simply inert.Checks
701 tests pass,
npx eslint src test scriptsis clean, and every part of this was reviewed on its own PR: #118, #119, #121, #122, #129, #130, #131, then #132 for the whole line.