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
9 changes: 5 additions & 4 deletions scripts/plugin-jsdocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ const methodsOutput = pluginRegistryClassMethods.map((statement) => {
s => s.type === "ArrowFunctionExpression"
);
if (funcExpr && funcExpr[0]) {
params = funcExpr[0].params.map(param => {
return param.properties.map(prop => {
return prop.key.name;
});
params = funcExpr[0].params.flatMap(param => {
if (param.properties) {
return param.properties.map(prop => prop.key.name);
}
return param.name ? [param.name] : [];
});
Comment on lines +57 to 62

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm RestElement and other pattern node structures in the parser output.
# Requires the package installed in scripts/ (Makefile runs `cd scripts && npm install`).
node -e "
const { parse } = require('./scripts/node_modules/@typescript-eslint/typescript-estree');
const code = 'const fn = ({ a, ...rest }, [b], c = 1, ...args) => {};';
const ast = parse(code, { comment: true, loc: true });
const arrow = ast.body[0].declarations[0].init;
arrow.params.forEach(p => {
  console.log(p.type, '→ properties:', !!p.properties, '| name:', p.name || '(none)', '| key:', p.key || '(none)');
  if (p.properties) {
    p.properties.forEach(prop => {
      console.log('  prop:', prop.type, '| key:', prop.key?.name || '(none)', '| argument:', prop.argument?.name || '(none)');
    });
  }
});
"

Repository: mattermost/mattermost-developer-documentation

Length of output: 1088


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== scripts/plugin-jsdocs.js ==\n'
cat -n scripts/plugin-jsdocs.js | sed -n '1,140p'

printf '\n== scripts/package.json (if present) ==\n'
if [ -f scripts/package.json ]; then
  cat -n scripts/package.json | sed -n '1,220p'
fi

printf '\n== dependency references ==\n'
rg -n "`@typescript-eslint/typescript-estree`|typescript-estree" -S . --glob '!**/node_modules/**'

Repository: mattermost/mattermost-developer-documentation

Length of output: 4542


Handle destructured params before reading prop.key.name ObjectPattern.properties can include RestElement nodes, so this branch can throw on { ...rest } and stop docs generation. The fallback also drops non-Identifier params like array patterns and defaults.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/plugin-jsdocs.js` around lines 57 - 62, The parameter extraction in
the docs generation logic is assuming every destructured property has
prop.key.name, which breaks on ObjectPattern entries like RestElement and misses
other non-Identifier params. Update the funcExpr[0].params.flatMap handling to
explicitly branch on param.type and safely handle destructured object/array
patterns, defaults, and rest elements without reading key.name blindly. Use the
existing params extraction block in the JSDoc script to keep all parameter
shapes supported while avoiding crashes on { ...rest }.

}
} else {
Expand Down
45 changes: 44 additions & 1 deletion site/content/integrate/plugins/interactive-dialogs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ Each dialog supports elements for users to enter information.
- `radio`: Radio button option. Use this to quickly select an option from pre-selected choices.
- `date`: Date picker field. Use this for selecting dates without time information.
- `datetime`: Date and time picker field. Use this for selecting both date and time with timezone support.
- `collapsible`: A section that groups child elements under a toggleable header. Use this to organize long forms; sections can be nested and can start expanded or collapsed.

Each element is required by default, otherwise the client will return an error as shown below. Note that the error message will appear below the help text, if one is specified. To make an element optional, set the field `"optional": "true"`.
Each element is required by default, otherwise the client will return an error as shown below. Note that the error message will appear below the help text, if one is specified. To make an element optional, set the field `"optional": true`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Reword this sentence for clarity.

The otherwise clause reads awkwardly, and the comma before if is unnecessary. A small rewrite will make the requirement easier to scan.

♻️ Proposed fix
-Each element is required by default, otherwise the client will return an error as shown below. Note that the error message will appear below the help text, if one is specified. To make an element optional, set the field `"optional": true`.
+Each element is required by default; otherwise, the client will return an error as shown below. Note that the error message will appear below the help text if one is specified. To make an element optional, set the field `"optional": true`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Each element is required by default, otherwise the client will return an error as shown below. Note that the error message will appear below the help text, if one is specified. To make an element optional, set the field `"optional": true`.
Each element is required by default; otherwise, the client will return an error as shown below. Note that the error message will appear below the help text if one is specified. To make an element optional, set the field `"optional": true`.
🧰 Tools
🪛 LanguageTool

[typographical] ~73-~73: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...collapsed. Each element is required by default, otherwise the client will return an error as show...

(THUS_SENTENCE)


[typographical] ~73-~73: Usually, there’s no comma before “if”.
Context: ... message will appear below the help text, if one is specified. To make an element op...

(IF_NO_COMMA)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/content/integrate/plugins/interactive-dialogs/_index.md` at line 73, The
sentence in the interactive dialogs docs reads awkwardly around the “otherwise”
clause and the “if” comma, so rewrite the copy in place for clarity. Update the
wording in the content block that mentions optional elements so it flows more
naturally, keeps the same meaning about client errors and help text placement,
and remains easy to scan.

Source: Linters/SAST tools


![image](interactive-dialog-error.png)

Expand Down Expand Up @@ -621,6 +622,48 @@ The `datetime_config` object groups date/datetime configuration into a single ne
- `"time_interval": 60` creates options: 00:00, 01:00, 02:00, 03:00, etc.
- Invalid: `"time_interval": 7` (7 is not a divisor of 1440)

### Collapsible elements
##### Minimum Server Version: 11.10
Comment on lines +625 to +626

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the next heading level here.

This jumps from ### to #####, which breaks the Markdown hierarchy. #### keeps the section structure consistent and satisfies the linter.

♻️ Proposed fix
-##### Minimum Server Version: 11.10
+#### Minimum Server Version: 11.10
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Collapsible elements
##### Minimum Server Version: 11.10
### Collapsible elements
#### Minimum Server Version: 11.10
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 626-626: Heading levels should only increment by one level at a time
Expected: h4; Actual: h5

(MD001, heading-increment)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/content/integrate/plugins/interactive-dialogs/_index.md` around lines
625 - 626, The heading hierarchy in the Collapsible elements section is skipping
a level, so update the heading after the `### Collapsible elements` entry to use
the next level heading instead of jumping to a deeper one. Adjust the Markdown
in `_index.md` so this section stays consistent with the surrounding structure
and satisfies the linter, using the same section labels already present.

Source: Linters/SAST tools


Collapsible elements group other elements under a toggleable header, letting you organize long forms into sections. Sections start expanded by default; set `collapsed` to `true` to have a section start closed. By default a section renders with a box outline; set `borderless` to `true` to remove it. A `collapsible` element does not submit a value itself — only its child `elements` appear in the submission payload. There can be, at most, 3 levels of nesting.

```json
{
"display_name": "Contact Details",
"name": "contact_section",
"type": "collapsible",
"collapsed": true,
"borderless": true,
"elements": [
{
"display_name": "Email",
"name": "email",
"type": "text",
"subtype": "email",
"placeholder": "you@example.com"
},
{
"display_name": "Phone",
"name": "phone",
"type": "text",
"optional": true
}
]
}
```

The full list of supported fields is included below:

| Field | Type | Description |
|----------------|---------|------------------------------------------------------------------------------------------------------------------------------------|
| `display_name` | String | Header text shown for the section. Maximum 24 characters. |
| `name` | String | Name of the section element used by the integration. Maximum 300 characters. You should use unique `name` fields in the same dialog. |
| `type` | String | Set this value to `collapsible` for a collapsible section. |
| `collapsed` | Boolean | (Optional) When `true`, the section starts collapsed. Default is `false` (expanded). |
| `borderless` | Boolean | (Optional) When `true`, the section renders without a box outline. Default is `false` (bordered). |
| `elements` | Array | Child elements rendered inside the section. May include other `collapsible` elements to create nested sections (up to 3 levels deep). Note that each collapsible element must have at least one child, or validation will fail.|


## Dialog submission

When a user submits a dialog, Mattermost will perform client-side input validation to make sure:
Expand Down
Loading