2021-11-29 16:33:06 -06:00
# Changelog
All notable changes to the Discourse JavaScript plugin API located at
app/assets/javascripts/discourse/app/lib/plugin-api.js will be described
2022-03-23 12:34:17 -05:00
in this file.
2021-11-29 16:33:06 -06:00
The format is based on [Keep a Changelog ](https://keepachangelog.com/en/1.0.0/ ),
and this project adheres to [Semantic Versioning ](https://semver.org/spec/v2.0.0.html ).
2023-12-01 10:29:12 -06:00
## [1.18.0] - 2023-12-1
### Added
- Added `setDesktopTopicTimelineScrollAreaHeight` function, which takes an object with min/max key value pairs as an argument. This is used to adjust the height of the topic timeline on desktop without CSS hacks that break the functionality of the topic timeline.
2023-11-30 16:26:13 -06:00
## [1.17.0] - 2023-11-30
### Added
- Introduces `forceDropdownAnimationForMenuPanels` API for forcing one or many Menu Panels (search-menu, user-menu, etc) to be rendered as a dropdown. This can be useful for plugins as the default behavior is to add a 'slide-in' behavior to a menu panel if you are viewing on a small screen. eg. mobile.
2023-11-29 20:56:22 -06:00
## [1.16.0] - 2023-11-17
### Added
- Added `recurrenceRule` option to `downloadCalendar` , this can be used to set recurring events in the calendar. Rule syntax can be found at https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10.
2023-10-18 23:23:41 -05:00
## [1.15.0] - 2023-10-18
### Added
- Added `hidden` option to `addSidebarPanel` , this can be used to remove the panel from combined sidebar mode as well as hiding its switch button. Useful for cases where only one sidebar should be shown at a time regardless of other panels.
- Added `getSidebarPanel` function, which returns the current sidebar panel object for comparison.
2023-10-05 18:43:40 -05:00
## [1.14.0] - 2023-10-06
### Added
- Added `addComposerToolbarPopupMenuOption` as a replacement for `addToolbarPopupMenuOptionsCallback` with new changes
introduced to the method's signature.
### Changed
- Deprecate `addToolbarPopupMenuOptionsCallback` in favor of `addComposerToolbarPopupMenuOption` .
2023-10-05 05:56:55 -05:00
## [1.13.0] - 2023-10-05
### Added
- Introduces `renderInOutlet` API for rendering components into plugin outlets
DEV: FloatKit (#23650)
This PR introduces three new concepts to Discourse codebase through an addon called "FloatKit":
- menu
- tooltip
- toast
## Tooltips
### Component
Simple cases can be express with an API similar to DButton:
```hbs
<DTooltip
@Label={{i18n "foo.bar"}}
@ICON="check"
@content="Something"
/>
```
More complex cases can use blocks:
```hbs
<DTooltip>
<:trigger>
{{d-icon "check"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
Something
</:content>
</DTooltip>
```
### Service
You can manually show a tooltip using the `tooltip` service:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();
// you can also just close any open tooltip through the service
this.tooltip.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const tooltipInstance = this.tooltip.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Menus
Menus are very similar to tooltips and provide the same kind of APIs:
### Component
```hbs
<DMenu @ICON="plus" @Label={{i18n "foo.bar"}}>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</DMenu>
```
They also support blocks:
```hbs
<DMenu>
<:trigger>
{{d-icon "plus"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</:content>
</DMenu>
```
### Service
You can manually show a menu using the `menu` service:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
menuInstance.close();
menuInstance.destroy();
// you can also just close any open tooltip through the service
this.menu.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const menuInstance = this.menu.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Toasts
Interacting with toasts is made only through the `toasts` service.
A default component is provided (DDefaultToast) and can be used through dedicated service methods:
- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });
```javascript
this.toasts.success({
data: {
title: "Foo",
message: "Bar",
actions: [
{
label: "Ok",
class: "btn-primary",
action: (componentArgs) => {
// eslint-disable-next-line no-alert
alert("Closing toast:" + componentArgs.data.title);
componentArgs.close();
},
}
]
},
});
```
You can also provide your own component:
```javascript
this.toasts.show(MyComponent, {
autoClose: false,
class: "foo",
data: { baz: 1 },
})
```
Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-26 06:39:52 -05:00
## [1.12.0] - 2023-09-06
### Added
- Adds `addPostAdminMenuButton` which allows to register a new button in the post admin menu.
2023-09-06 10:48:51 -05:00
## [1.11.0] - 2023-08-30
### Added
DEV: FloatKit (#23650)
This PR introduces three new concepts to Discourse codebase through an addon called "FloatKit":
- menu
- tooltip
- toast
## Tooltips
### Component
Simple cases can be express with an API similar to DButton:
```hbs
<DTooltip
@Label={{i18n "foo.bar"}}
@ICON="check"
@content="Something"
/>
```
More complex cases can use blocks:
```hbs
<DTooltip>
<:trigger>
{{d-icon "check"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
Something
</:content>
</DTooltip>
```
### Service
You can manually show a tooltip using the `tooltip` service:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();
// you can also just close any open tooltip through the service
this.tooltip.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const tooltipInstance = this.tooltip.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Menus
Menus are very similar to tooltips and provide the same kind of APIs:
### Component
```hbs
<DMenu @ICON="plus" @Label={{i18n "foo.bar"}}>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</DMenu>
```
They also support blocks:
```hbs
<DMenu>
<:trigger>
{{d-icon "plus"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</:content>
</DMenu>
```
### Service
You can manually show a menu using the `menu` service:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
menuInstance.close();
menuInstance.destroy();
// you can also just close any open tooltip through the service
this.menu.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const menuInstance = this.menu.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Toasts
Interacting with toasts is made only through the `toasts` service.
A default component is provided (DDefaultToast) and can be used through dedicated service methods:
- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });
```javascript
this.toasts.success({
data: {
title: "Foo",
message: "Bar",
actions: [
{
label: "Ok",
class: "btn-primary",
action: (componentArgs) => {
// eslint-disable-next-line no-alert
alert("Closing toast:" + componentArgs.data.title);
componentArgs.close();
},
}
]
},
});
```
You can also provide your own component:
```javascript
this.toasts.show(MyComponent, {
autoClose: false,
class: "foo",
data: { baz: 1 },
})
```
Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-26 06:39:52 -05:00
- Adds `addBeforeAuthCompleteCallback` which allows plugins and themes to add functions to be
evaluated before the auth-complete logic is run. If any of these callbacks return false, the
2023-09-06 10:48:51 -05:00
auth-complete logic will be aborted.
2023-08-28 23:36:20 -05:00
## [1.10.0] - 2023-08-25
### Added
- Adds `registerReviewableActionModal` which allows core and plugins to register a modal component class
which is used to show a modal for certain reviewable actions.
2023-08-09 17:43:35 -05:00
## [1.9.0] - 2023-08-09
### Added
- Adds `showSidebarSwitchPanelButtons` which is experimental, and allows plugins to show sidebar switch panel buttons in separated mode
- Adds `hideSidebarSwitchPanelButtons` which is experimental, and allows plugins to hide sidebar switch panel buttons in separated mode
2023-08-08 14:00:45 -05:00
## [1.8.1] - 2023-08-08
### Added
- Adds `replacePostMenuButton` which allows plugins to replace a post menu button with a widget.
## [1.8.0] - 2023-07-18
### Added
DEV: FloatKit (#23650)
This PR introduces three new concepts to Discourse codebase through an addon called "FloatKit":
- menu
- tooltip
- toast
## Tooltips
### Component
Simple cases can be express with an API similar to DButton:
```hbs
<DTooltip
@Label={{i18n "foo.bar"}}
@ICON="check"
@content="Something"
/>
```
More complex cases can use blocks:
```hbs
<DTooltip>
<:trigger>
{{d-icon "check"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
Something
</:content>
</DTooltip>
```
### Service
You can manually show a tooltip using the `tooltip` service:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
tooltipInstance.close();
tooltipInstance.destroy();
// you can also just close any open tooltip through the service
this.tooltip.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const tooltipInstance = this.tooltip.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
tooltipInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const tooltipInstance = await this.tooltip.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Menus
Menus are very similar to tooltips and provide the same kind of APIs:
### Component
```hbs
<DMenu @ICON="plus" @Label={{i18n "foo.bar"}}>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</DMenu>
```
They also support blocks:
```hbs
<DMenu>
<:trigger>
{{d-icon "plus"}}
<span>{{i18n "foo.bar"}}</span>
</:trigger>
<:content>
<ul>
<li>Foo</li>
<li>Bat</li>
<li>Baz</li>
</ul>
</:content>
</DMenu>
```
### Service
You can manually show a menu using the `menu` service:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
options
)
// and later manual close or destroy it
menuInstance.close();
menuInstance.destroy();
// you can also just close any open tooltip through the service
this.menu.close();
```
The service also allows you to register event listeners on a trigger, it removes the need for you to manage open/close of a tooltip started through the service:
```javascript
const menuInstance = this.menu.register(
document.querySelector(".my-span"),
options
)
// when done you can destroy the instance to remove the listeners
menuInstance.destroy();
```
Note that the service also allows you to use a custom component as content which will receive `@data` and `@close` as args:
```javascript
const menuInstance = await this.menu.show(
document.querySelector(".my-span"),
{
component: MyComponent,
data: { foo: 1 }
}
)
```
## Toasts
Interacting with toasts is made only through the `toasts` service.
A default component is provided (DDefaultToast) and can be used through dedicated service methods:
- this.toasts.success({ ... });
- this.toasts.warning({ ... });
- this.toasts.info({ ... });
- this.toasts.error({ ... });
- this.toasts.default({ ... });
```javascript
this.toasts.success({
data: {
title: "Foo",
message: "Bar",
actions: [
{
label: "Ok",
class: "btn-primary",
action: (componentArgs) => {
// eslint-disable-next-line no-alert
alert("Closing toast:" + componentArgs.data.title);
componentArgs.close();
},
}
]
},
});
```
You can also provide your own component:
```javascript
this.toasts.show(MyComponent, {
autoClose: false,
class: "foo",
data: { baz: 1 },
})
```
Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
Co-authored-by: Isaac Janzen <50783505+janzenisaac@users.noreply.github.com>
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2023-09-26 06:39:52 -05:00
- Adds `addSidebarPanel` which is experimental, and adds a Sidebar panel by returning a class which extends from the
2023-08-08 14:00:45 -05:00
BaseCustomSidebarPanel class.
- Adds `setSidebarPanel` which is experimental, and sets the current sidebar panel.
2023-07-18 13:10:16 -05:00
## [1.7.1] - 2023-07-18
### Added
- Adds `addBulkActionButton` which adds actions to the Bulk Topic modal
2023-07-17 18:29:55 -05:00
## [1.7.0] - 2023-07-17
### Added
- Adds `addCommunitySectionLink` which allows plugins to add a navigation link to the Sidebar community section under
the "More..." links drawer.
- Adds `registerUserCategorySectionLinkCountable` which allows plugins to register a new countable for section links
under Sidebar Categories section on top of the default countables of unread topics count and new topics count.
- Adds `registerCustomCategorySectionLinkLockIcon` which allows plugins to change the lock icon used for a sidebar
category section link to indicate that a category is read restricted.
- Adds `registerCustomCategorySectionLinkPrefix` which allows plugins to register a custom prefix for a sidebar category
section link.
- Adds `registerCustomTagSectionLinkPrefixValue` which allows plugins to register a custom prefix for a sidebar tag
section link.
- Adds `refreshUserSidebarCategoriesSectionCounts` which allows plugins to trigger a refresh of the counts for all
category section links under the categories section for a logged in user.
- Adds `addSidebarSection` which allows plugins to add a Sidebar section.
- Adds `registerNotificationTypeRenderer` which allows plugins to register a custom renderer for a notification type
or override the renderer of an existing type. See lib/notification-types/base.js for documentation and the default
renderer.
- Adds `registerModelTransformer` which allows plugins to apply transformation using a callback on a list of model
instances of a specific type. Currently, this API only works on lists rendered in the user menu such as notifications,
bookmarks and topics (i.e. messages), but it may be extended to other lists in other parts of the app.
- Adds `addUserMessagesNavigationDropdownRow` which allows plugins to add a row to the dropdown used on the
`userPrivateMessages` route used to navigate between the different user messages pages.
2022-12-14 09:30:45 -06:00
## [1.6.0] - 2022-12-13
### Added
- Adds `addPostSmallActionClassesCallback` , which allows users to register a custom
function that adds a class to small action posts (pins, closing topics, etc)
2022-11-21 10:11:29 -06:00
## [1.5.0] - 2022-11-21
### Added
- Adds `addComposerSaveErrorCallback` , which allows users to register custom error handling
for server-side errors when submitting on the composer.
2022-09-27 11:26:52 -05:00
## [1.4.0] - 2022-09-27
### Added
- Adds `registerHighlightJSPlugin` , which allows users to register custom
HighlightJS plugins. See https://highlightjs.readthedocs.io/en/latest/plugin-api.html
for documentation.
2022-05-31 04:06:41 -05:00
## [1.3.0] - 2022-05-29
### Added
2022-06-20 19:07:21 -05:00
- N/A - Mistakenly bumped.
2022-05-31 04:06:41 -05:00
2022-03-23 12:34:17 -05:00
## [1.2.0] - 2022-03-18
### Added
- Adds `registerCustomLastUnreadUrlCallback` , which allows users to register a custom
function that returns a last unread url for a topic list item. When multiple callbacks
are registered, the first non-null value that is returned will be used.
2021-12-15 04:09:26 -06:00
## [1.1.0] - 2021-12-15
2022-03-23 12:34:17 -05:00
2021-12-15 04:09:26 -06:00
### Added
2022-03-23 12:34:17 -05:00
2021-12-15 04:09:26 -06:00
- Adds `addPosterIcons` , which allows users to add multiple icons to a poster. The
2022-03-23 12:34:17 -05:00
addition of this function also makes the existing `addPosterIcon` now an alias to this
function. Users may now just use `addPosterIcons` for both one or many icons. This
function allows users to now return many icons depending on an `attrs` .
2021-12-15 04:09:26 -06:00
2021-11-29 16:33:06 -06:00
## [1.0.0] - 2021-11-25
2022-03-23 12:34:17 -05:00
2021-11-29 16:33:06 -06:00
### Removed
2022-03-23 12:34:17 -05:00
2021-11-29 16:33:06 -06:00
- Removes the `addComposerUploadProcessor` function, which is no longer used in
2022-03-23 12:34:17 -05:00
favour of `addComposerUploadPreProcessor` . The former was used to add preprocessors
for client side uploads via jQuery file uploader (described at
https://github.com/blueimp/jQuery-File-Upload/wiki/Options#file-processing-options).
The new `addComposerUploadPreProcessor` adds preprocessors for client side
uploads in the form of an Uppy plugin. See https://uppy.io/docs/writing-plugins/
for the Uppy documentation, but other examples of preprocessors in core can be found
in the UppyMediaOptimization and UppyChecksum classes. This has been done because
of the overarching move towards Uppy in the Discourse codebase rather than
jQuery fileupload, which will eventually be removed altogether as a broader effort
to remove jQuery from the codebase.
2021-11-29 16:33:06 -06:00
### Changed
2022-03-23 12:34:17 -05:00
2021-11-29 16:33:06 -06:00
- Changes `addComposerUploadHandler` 's behaviour. Instead of being only usable
2022-03-23 12:34:17 -05:00
for single files at a time, now multiple files are sent to the upload handler
at once. These multiple files are sent based on the groups in which they are
added (e.g. multiple files selected from the system upload dialog, or multiple
files dropped in to the composer). Files will be sent in buckets to the handlers
they match.