Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,14 @@ For dynamic frontend changes, run the Playwright tests under `tests/end-to-end/`
Components and functions are documented in [official-site migrations](./examples/official-site/sqlpage/migrations/). Edit the existing migration for an existing entity; add an appropriately ordered migration for a new entity. The official-site database is recreated from migrations on each deployment.

official documentation website sql tables:
- `parameter_type(type)`
- `parameter_type(name)` -- the allowed values of `parameter.type`
- `component(name,description,icon,introduced_in_version)` -- icon name from tabler icon
- `parameter(top_level BOOLEAN, name, component REFERENCES component(name), description, description_md, type, optional BOOLEAN)` parameter types: BOOLEAN, COLOR, HTML, ICON, INTEGER, JSON, REAL, TEXT, TIMESTAMP, URL
- `parameter(top_level BOOLEAN, name, component REFERENCES component(name), description, description_md, type REFERENCES parameter_type(name), optional BOOLEAN)` parameter types: BOOLEAN, COLOR, HTML, ICON, INTEGER, JSON, REAL, TEXT, TIMESTAMP, URL. Set exactly one of `description` (plain text) and `description_md` (markdown).
- `example(component REFERENCES component(name), description, properties JSON)`
- `sqlpage_functions(name,icon,description_md,return_type,introduced_in_version)`
- `sqlpage_function_parameters(function,index,name,description_md,type)`
- `blog_posts(title,description,icon,external_url,content,created_at)` -- release announcements and long-form guides
- `example_cards(title,folder,db_engine,description)`

#### Project Conventions

Expand Down
26 changes: 17 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,27 @@ Windows comes with ODBC pre-installed; SQLPage cannot statically link to the uni

### Rust

- Use `cargo fmt` to format your Rust code
- Use `cargo fmt --all` to format your Rust code
- Run `cargo clippy` to catch common mistakes and improve code quality
- All code must pass the following checks:

```bash
cargo fmt --all -- --check
cargo clippy
cargo clippy --all-targets --all-features -- -D warnings
```

### Frontend

We use Biome for linting and formatting of the frontend code.
We use Biome for linting and formatting of the frontend code, and TypeScript
to typecheck it.

```bash
npx @biomejs/biome check .
npm install # once
npm run format # apply formatting
npm test # the check CI runs: biome, typecheck, and the frontend unit tests
```

This will check the entire codebase (html, css, js).
`npm test` checks the entire frontend codebase (html, css, js, ts).

## Testing

Expand Down Expand Up @@ -127,7 +130,11 @@ INSERT INTO component(name, icon, description, introduced_in_version) VALUES

-- Document all parameters
INSERT INTO parameter(component, name, description, type, top_level, optional)
VALUES ('component_name', 'param_name', 'param_description', 'TEXT|BOOLEAN|NUMBER|JSON|ICON|COLOR', false, true);
VALUES ('component_name', 'param_name', 'param_description', 'TEXT|BOOLEAN|INTEGER|JSON|ICON|COLOR|HTML|REAL|TIMESTAMP|URL', false, true);

-- Use description_md instead of description when the text contains markdown
INSERT INTO parameter(component, name, description_md, type, top_level, optional)
VALUES ('component_name', 'other_param', 'Set to `true` to see [the docs](/documentation.sql).', 'BOOLEAN', true, true);

-- Include usage examples
INSERT INTO example(component, description, properties) VALUES
Expand Down Expand Up @@ -180,7 +187,7 @@ VALUES (
1,
'parameter_name',
'Description of what this parameter does and how to use it.',
'TEXT|BOOLEAN|NUMBER|JSON'
'TEXT|BOOLEAN|INTEGER|JSON'
);
```

Expand Down Expand Up @@ -208,6 +215,7 @@ git checkout -b feature/your-feature-name
- Code is properly formatted
- New features are documented
- tests cover new functionality
- `CHANGELOG.md` has an entry for any user-visible change

3. Push your changes and create a Pull Request

Expand All @@ -216,8 +224,8 @@ git checkout -b feature/your-feature-name
- Run Rust formatting and clippy checks
- Execute all tests across multiple platforms (Linux, Windows)
- Build Docker images for multiple architectures
- Run frontend linting with Biome
- Test against multiple databases (PostgreSQL, MySQL, MSSQL)
- Run frontend linting, typechecking and unit tests (`npm test`)
- Test against multiple databases (SQLite, PostgreSQL, MySQL, MSSQL, Oracle, and ODBC)

## Release Process

Expand Down
12 changes: 6 additions & 6 deletions examples/official-site/component.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,35 @@ where name = $component and introduced_in_version IS NOT NULL;

select 'title' as component, 3 as level, 'Top-level parameters' as contents where $component IS NOT NULL;
select 'table' as component, true as striped, true as hoverable, true as freeze_columns,
'type' as markdown
'type' as markdown, 'description' as markdown
where $component IS NOT NULL;
select
name,
CASE WHEN optional THEN '' ELSE 'REQUIRED' END as required,
CASE type
CASE type
WHEN 'COLOR' THEN printf('[%s](/colors.sql)', type)
WHEN 'ICON' THEN printf('[%s](https://tabler-icons.io/?ref=sqlpage)', type)
ELSE type
END AS type,
description
coalesce(description_md, description) as description
from parameter where component = $component AND top_level
ORDER BY optional, name;


select 'title' as component, 3 as level, 'Row-level parameters' as contents
WHERE $component IS NOT NULL AND EXISTS (SELECT 1 from parameter where component = $component AND NOT top_level);
select 'table' as component, true as striped, true as hoverable, true as freeze_columns,
'type' as markdown
'type' as markdown, 'description' as markdown
where $component IS NOT NULL;
select
name,
CASE WHEN optional THEN '' ELSE 'REQUIRED' END as required,
CASE type
CASE type
WHEN 'COLOR' THEN printf('[%s](/colors.sql)', type)
WHEN 'ICON' THEN printf('[%s](https://tabler-icons.io/?ref=sqlpage)', type)
ELSE type
END AS type,
description
coalesce(description_md, description) as description
from parameter where component = $component AND NOT top_level
ORDER BY optional, name;

Expand Down
24 changes: 19 additions & 5 deletions examples/official-site/sqlpage/migrations/01_documentation.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
-- item level
('title', 'Name of the list item, displayed prominently.', 'TEXT', FALSE, FALSE),
('description', 'A description of the list item, displayed as greyed-out text.', 'TEXT', FALSE, TRUE),
('description_md', 'A description of the list item, displayed as greyed-out text, in Markdown format, allowing you to use rich text formatting, including **bold** and *italic* text.', 'TEXT', FALSE, TRUE),
('description_md', 'A description of the list item, displayed as greyed-out text, in Markdown format, allowing you to use rich text formatting, including `**bold**` and `*italic*` text.', 'TEXT', FALSE, TRUE),
('link', 'An URL to which the user should be taken when they click on the list item.', 'URL', FALSE, TRUE),
('icon', 'Name of an icon to display on the left side of the item.', 'ICON', FALSE, TRUE),
('image_url', 'The URL of a small image to display on the left side of the item.', 'URL', FALSE, TRUE),
Expand Down Expand Up @@ -146,14 +146,13 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
-- top level
('title', 'Text header before the paragraph.', 'TEXT', TRUE, TRUE),
('center', 'Whether to center the title.', 'BOOLEAN', TRUE, TRUE),
('width', 'How wide the paragraph should be, in characters.', 'INTEGER', TRUE, TRUE),
('html', 'Raw html code to include on the page. Don''t use that if you are not sure what you are doing, it may have security implications.', 'TEXT', TRUE, TRUE),
('contents', 'A top-level paragraph of text to display, without any formatting, without having to make additional queries.', 'TEXT', TRUE, TRUE),
('contents_md', 'Rich text in the markdown format. Among others, this allows you to write bold text using **bold**, italics using *italics*, and links using [text](https://example.com).', 'TEXT', TRUE, TRUE),
('contents_md', 'Rich text in the markdown format. Among others, this allows you to write bold text using `**bold**`, italics using `*italics*`, and links using `[text](https://example.com)`.', 'TEXT', TRUE, TRUE),
('article', 'Makes long texts more readable by increasing the line height, adding margins, using a serif font, and decorating the initial letter.', 'BOOLEAN', TRUE, TRUE),
-- item level
('contents', 'A span of text to display', 'TEXT', FALSE, FALSE),
('contents_md', 'Rich text in the markdown format. Among others, this allows you to write bold text using **bold**, italics using *italics*, and links using [text](https://example.com).', 'TEXT', FALSE, TRUE),
('contents_md', 'Rich text in the markdown format. Among others, this allows you to write bold text using `**bold**`, italics using `*italics*`, and links using `[text](https://example.com)`.', 'TEXT', FALSE, TRUE),
('link', 'An URL to which the user should be taken when they click on this span of text.', 'URL', FALSE, TRUE),
('color', 'The name of a color for this span of text.', 'COLOR', FALSE, TRUE),
('underline', 'Whether the span of text should be underlined.', 'BOOLEAN', FALSE, TRUE),
Expand Down Expand Up @@ -264,12 +263,18 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
('validate', 'The text to display in the button at the bottom of the form that submits the values. Omit this property to let the browser display the default form validation text, or set it to the empty string to remove the button completely.', 'TEXT', TRUE, TRUE),
('validate_color', 'The color of the button at the bottom of the form that submits the values. Omit this property to use the default color.', 'COLOR', TRUE, TRUE),
('validate_outline', 'A color to outline the validation button.', 'COLOR', TRUE, TRUE),
('validate_shape', 'The shape of the validation button (e.g., pill, square).', 'TEXT', TRUE, TRUE),
('validate_size', 'The size of the validation button (e.g., sm, lg).', 'TEXT', TRUE, TRUE),
Comment on lines +266 to +267

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{#if validate_shape}} btn-{{validate_shape}} {{/if}}
{{#if validate_outline}} btn-outline-{{validate_outline}} {{/if}}
{{#if validate_size}} btn-{{validate_size}} {{/if}}"

('reset', 'The text to display in the button at the bottom of the form that resets the form to its original state. Omit this property not to show a reset button at all.', 'TEXT', TRUE, TRUE),
('id', 'A unique identifier for the form, which can then be used to validate the form from a button outside of the form.', 'TEXT', TRUE, TRUE),
('auto_submit', 'Automatically submit the form when the user changes any of its fields, and remove the validation button.', 'BOOLEAN', TRUE, TRUE),
('validate_icon', 'Name of an icon to be displayed on the left side of the submit button.', 'ICON', TRUE, TRUE),
('reset_icon', 'Name of an icon to be displayed on the left side of the reset button.', 'ICON', TRUE, TRUE),
('reset_color', 'The color of the button at the bottom of the form that resets the form to its original state. Omit this property to use the default color.', 'COLOR', TRUE, TRUE),
('reset_outline', 'A color to outline the reset button.', 'COLOR', TRUE, TRUE),
('reset_shape', 'The shape of the reset button (e.g., pill, square).', 'TEXT', TRUE, TRUE),
('reset_size', 'The size of the reset button (e.g., sm, lg).', 'TEXT', TRUE, TRUE),
Comment on lines +274 to +276

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{#if reset_color}} btn-{{reset_color}} {{/if}}
{{#if reset_shape}} btn-{{reset_shape}} {{/if}}
{{#if reset_outline}} btn-outline-{{reset_outline}} {{/if}}
{{#if reset_size}} btn-{{reset_size}} {{/if}}"

('narrow', 'Whether to trim the horizontal padding between the icon and the label of the validation and reset buttons.', 'BOOLEAN', TRUE, TRUE),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<span {{~#if (not narrow)}} class="me-1"{{/if}}>{{~icon_img validate_icon~}}</span>

<span {{~#if (not narrow)}} class="me-1"{{/if}}>{{~icon_img reset_icon~}}</span>

-- item level
('type', 'Declares input control behavior and expected format. All HTML input types are supported (text, number, date, file, checkbox, radio, hidden, ...). SQLPage adds some custom types: textarea, switch, header. text by default. See https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#input_types', 'TEXT', FALSE, TRUE),
('name', 'The name of the input field, that you can use in the target page to get the value the user entered for the field.', 'TEXT', FALSE, FALSE),
Expand Down Expand Up @@ -297,6 +302,11 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
('minlength', 'Minimum length of text allowed in the field.', 'INTEGER', FALSE, TRUE),
('maxlength', 'Maximum length of text allowed in the field.', 'INTEGER', FALSE, TRUE),
('formaction', 'When type is "submit", this specifies the URL of the file that will handle the form submission. Useful when you need multiple submit buttons.', 'TEXT', FALSE, TRUE),
('formmethod', 'When type is "submit", the HTTP method to submit the form with. Takes precedence over the form''s own "method".', 'TEXT', FALSE, TRUE),
('formnovalidate', 'When type is "submit", skips the browser''s validation of the other fields when this button submits the form.', 'BOOLEAN', FALSE, TRUE),
('formtarget', 'When type is "submit", where to display the response. Takes the same values as a link target: "_blank" to open a new tab, "_self" to stay in the same one.', 'TEXT', FALSE, TRUE),
Comment on lines +305 to +307

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~#if formenctype}}formenctype="{{formenctype}}" {{/if~}}
{{~#if formmethod}}formmethod="{{formmethod}}" {{/if~}}
{{~#if formnovalidate}}formnovalidate="{{formnovalidate}}" {{/if~}}

('accept', 'Used only for inputs of type "file". A comma-separated list of the file types the user can pick, given as extensions (".pdf,.png") or as MIME types ("image/*").', 'TEXT', FALSE, TRUE),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~#if accept}}accept="{{accept}}" {{/if~}}

('list', 'The id of a datalist element holding the suggestions to show for this field. The datalist itself has to be rendered by the "html" component.', 'TEXT', FALSE, TRUE),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~#if list}}list="{{list}}" {{/if~}}

('class', 'A CSS class to apply to the form element.', 'TEXT', FALSE, TRUE),
('prefix_icon','Icon to display on the left side of the input field, on the same line.','ICON',FALSE,TRUE),
('prefix','Text to display on the left side of the input field, on the same line.','TEXT',FALSE,TRUE),
Expand Down Expand Up @@ -660,6 +670,7 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
('ytitle', 'Title of the y axis, displayed to its left.', 'TEXT', TRUE, TRUE),
('ztitle', 'Title of the z axis, displayed in tooltips.', 'TEXT', TRUE, TRUE),
('xticks', 'Number of ticks on the x axis.', 'INTEGER', TRUE, TRUE),
('yticks', 'Number of ticks on the y axis.', 'INTEGER', TRUE, TRUE),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"yticks": {{stringify yticks}},

('ystep', 'Step between ticks on the y axis.', 'REAL', TRUE, TRUE),
('marker', 'Marker size', 'REAL', TRUE, TRUE),
('labels', 'Whether to show the data labels on the chart or not.', 'BOOLEAN', TRUE, TRUE),
Expand All @@ -673,6 +684,7 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
-- item level
('x', 'The value of the point on the horizontal axis', 'REAL', FALSE, FALSE),
('y', 'The value of the point on the vertical axis', 'REAL', FALSE, FALSE),
('z', 'A third value carried by the point. Used as the bubble radius in a bubble chart, and shown in the tooltip under the name given by the top-level "ztitle".', 'REAL', FALSE, TRUE),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~#if z}}, {{~ stringify z ~}} {{~/if~}}

('label', 'An alias for parameter "x"', 'REAL', FALSE, TRUE),
('value', 'An alias for parameter "y"', 'REAL', FALSE, TRUE),
('series', 'If multiple series are represented and share the same y-axis, this parameter can be used to distinguish between them.', 'TEXT', FALSE, TRUE)
Expand Down Expand Up @@ -829,6 +841,7 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
('money', 'Name of a numeric column whose values should be displayed as currency amounts, in the currency defined by the `currency` property. This argument can be repeated multiple times.', 'TEXT', TRUE, TRUE),
('currency', 'The ISO 4217 currency code (e.g., USD, EUR, GBP, etc.) to use when formatting monetary values.', 'TEXT', TRUE, TRUE),
('number_format_digits', 'Maximum number of decimal digits to display for numeric values.', 'INTEGER', TRUE, TRUE),
('number_format_locale', 'A BCP 47 language tag (e.g. "de-DE", "en-IN") deciding how numbers and monetary values are formatted. Defaults to the locale of the visitor''s browser.', 'TEXT', TRUE, TRUE),

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~#if number_format_locale}} data-number_format_locale="{{number_format_locale}}"{{/if~}}

('edit_url', 'If set, an edit button will be added to each row. The value of this property should be a URL, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row. Clicking the edit button will take the user to that URL. Added in v0.39.0', 'TEXT', TRUE, TRUE),
('delete_url', 'If set, a delete button will be added to each row. The value of this property should be a URL, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row. Clicking the delete button will take the user to that URL. Added in v0.39.0', 'TEXT', TRUE, TRUE),
('custom_actions', 'If set, a column of custom action buttons will be added to each row. The value of this property should be a JSON array of objects, each object defining a button with the following properties: `name` (the text to display on the button), `icon` (the tabler icon name or image link to display on the button), `link` (the URL to navigate to when the button is clicked, possibly containing the `{id}` placeholder that will be replaced by the value of the `_sqlpage_id` property for that row), and `tooltip` (optional text to display when hovering over the button). Added in v0.39.0', 'JSON', TRUE, TRUE),
Expand Down Expand Up @@ -1367,7 +1380,8 @@ INSERT INTO parameter(component, name, description, type, top_level, optional) S
('footer', 'Muted text to display in the footer of the page. This can be used to display a link to the terms and conditions of your application, for instance. By default, shows "Built with SQLPage". Supports links with markdown.', 'TEXT', TRUE, TRUE),
('preview_image', 'The URL of an image to display as a link preview when the page is shared on social media', 'URL', TRUE, TRUE),
('navbar_title', 'The title to display in the top navigation bar. Used to display a different title in the top menu than the one that appears in the tab of the browser.', 'TEXT', TRUE, TRUE),
('target', '"_blank" to open the link in a new tab, "_self" to open it in the same tab, "_parent" to open it in the parent frame, or "_top" to open it in the full body of the window', 'TEXT', TRUE, TRUE)
('target', 'Where the menu items should open: "_blank" for a new tab, "_self" for the same tab, "_parent" for the parent frame, or "_top" for the full body of the window. Set it inside a "menu_item" json object; it has no effect when set directly on the shell.', 'TEXT', TRUE, TRUE),
('class', 'class attribute added to the page''s html element. It can be used to apply custom styling to the whole page through css.', 'TEXT', TRUE, TRUE)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~#if number_format_locale}} data-number_format_locale="{{number_format_locale}}"{{/if~}}

) x;

INSERT INTO example(component, description, properties) VALUES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ FROM
FALSE,
TRUE
),
(
'color',
'Color of the badge behind the feature section''s icon. Defaults to "success".',
'COLOR',
FALSE,
TRUE
),
Comment on lines +129 to +135

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<div style="margin-top: -1.5rem;" class="badge bg-{{default color 'success'}} text-{{default color 'success'}}-fg fs-1 mb-4 p-2">

(
'link',
'An URL to which the user should be taken when they click on the section title.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ VALUES (
(
'alert',
'description_md',
'Detailed description or content of the alert message, in Markdown format, allowing you to use rich text formatting, including **bold** and *italic* text.',
'Detailed description or content of the alert message, in Markdown format, allowing you to use rich text formatting, including `**bold**` and `*italic*` text.',
'TEXT',
TRUE,
TRUE
Expand Down
8 changes: 8 additions & 0 deletions examples/official-site/sqlpage/migrations/10_map.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ INSERT INTO
optional
)
VALUES
(
'map',
'title',
'A text header displayed above the map.',
'TEXT',
TRUE,
TRUE
),
Comment on lines +40 to +47

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<h3 class="card-title">{{title}}</h3>

(
'map',
'latitude',
Expand Down
8 changes: 8 additions & 0 deletions examples/official-site/sqlpage/migrations/13_tab.sql
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ VALUES (
'BOOLEAN',
TRUE,
TRUE
),
(
'tab',
'center',
'Whether this individual tab''s label should be centered inside the tab. Defaults to false.',
'BOOLEAN',
FALSE,
TRUE
Comment on lines +72 to +78

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{~/if}} {{#if center~}}

)
;

Expand Down
Loading