mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 23:40:13 +01:00
v7.00
This commit is contained in:
parent
588e051f0f
commit
1892a17855
8 changed files with 25 additions and 4311 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -18,15 +18,18 @@ Note:
|
|||
|
||||
[How to upgrade WeKan](https://github.com/wekan/wekan/issues/4585)
|
||||
|
||||
# Upcoming v7.00 WeKan ® release
|
||||
|
||||
This version number and and some before it is reserved for upcoming PR from mfilser.
|
||||
# v7.00 2023-07-19 WeKan ® release
|
||||
|
||||
This release adds the following new features:
|
||||
|
||||
- Speed improvements to Board and List loading.
|
||||
- [Speed improvements to Board and List loading](https://github.com/wekan/wekan/pull/5014).
|
||||
Thanks to mfilser.
|
||||
|
||||
and adds the following updates:
|
||||
|
||||
- [Forked meteor-globals and meteor-reactive-cache to @wekanteam/meteor-globals and @wekanteam/meteor-reactive-cache to update to newest dependencies](https://github.com/wekan/wekan/commit/1c5857f0646658b121d7612b6176ec5e09c68592).
|
||||
Thanks to xet7.
|
||||
|
||||
Thanks to above GitHub users for their contributions and translators for their translations.
|
||||
|
||||
# v6.99.9 2023-07-18 WeKan ® release
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
appId: wekan-public/apps/77b94f60-dec9-0136-304e-16ff53095928
|
||||
appVersion: "v6.99.9"
|
||||
appVersion: "v7.00"
|
||||
files:
|
||||
userUploads:
|
||||
- README.md
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wekan",
|
||||
"version": "v6.99.9",
|
||||
"version": "v7.00",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wekan",
|
||||
"version": "v6.99.9",
|
||||
"version": "v7.00",
|
||||
"description": "Open-Source kanban",
|
||||
"private": true,
|
||||
"repository": {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
swagger: '2.0'
|
||||
info:
|
||||
title: Wekan REST API
|
||||
version: v6.99.9
|
||||
version: v7.00
|
||||
description: |
|
||||
The REST API allows you to control and extend Wekan with ease.
|
||||
|
||||
|
|
@ -2277,125 +2277,6 @@ paths:
|
|||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
/api/boards/{board}/members/{user}/add:
|
||||
post:
|
||||
operationId: add_board_member
|
||||
summary: Add New Board Member with Role
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
|
||||
**Note**: see [Boards.set_board_member_permission](#set_board_member_permission)
|
||||
to later change the permissions.
|
||||
tags:
|
||||
- Users
|
||||
- Boards
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: action
|
||||
in: formData
|
||||
description: |
|
||||
the action (needs to be `add`)
|
||||
type: string
|
||||
required: true
|
||||
- name: isAdmin
|
||||
in: formData
|
||||
description: |
|
||||
is the user an admin of the board
|
||||
type: boolean
|
||||
required: true
|
||||
- name: isNoComments
|
||||
in: formData
|
||||
description: |
|
||||
disable comments
|
||||
type: boolean
|
||||
required: true
|
||||
- name: isCommentOnly
|
||||
in: formData
|
||||
description: |
|
||||
only enable comments
|
||||
type: boolean
|
||||
required: true
|
||||
- name: isWorker
|
||||
in: formData
|
||||
description: |
|
||||
is the user a board worker
|
||||
type: boolean
|
||||
required: true
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the board ID
|
||||
type: string
|
||||
required: true
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the user ID
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
/api/boards/{board}/members/{user}/remove:
|
||||
post:
|
||||
operationId: remove_board_member
|
||||
summary: Remove Member from Board
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
- Boards
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: action
|
||||
in: formData
|
||||
description: |
|
||||
the action (needs to be `remove`)
|
||||
type: string
|
||||
required: true
|
||||
- name: board
|
||||
in: path
|
||||
description: |
|
||||
the board ID
|
||||
type: string
|
||||
required: true
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the user ID
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
/api/boards/{board}/swimlanes:
|
||||
get:
|
||||
operationId: get_all_swimlanes
|
||||
|
|
@ -2623,252 +2504,6 @@ paths:
|
|||
type: integer
|
||||
public:
|
||||
type: integer
|
||||
/api/createtoken/{user}:
|
||||
post:
|
||||
operationId: create_user_token
|
||||
summary: Create a user token
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the ID of the user to create token for.
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/deletetoken:
|
||||
post:
|
||||
operationId: delete_user_token
|
||||
summary: Delete one or all user token.
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: userId
|
||||
in: formData
|
||||
description: |
|
||||
the user ID
|
||||
type: string
|
||||
required: true
|
||||
- name: token
|
||||
in: formData
|
||||
description: |
|
||||
the user hashedToken
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
/api/user:
|
||||
get:
|
||||
operationId: get_current_user
|
||||
summary: returns the current user
|
||||
tags:
|
||||
- Users
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
$ref: "#/definitions/Users"
|
||||
/api/users:
|
||||
get:
|
||||
operationId: get_all_users
|
||||
summary: return all the users
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
post:
|
||||
operationId: new_user
|
||||
summary: Create a new user
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: username
|
||||
in: formData
|
||||
description: |
|
||||
the new username
|
||||
type: string
|
||||
required: true
|
||||
- name: email
|
||||
in: formData
|
||||
description: |
|
||||
the email of the new user
|
||||
type: string
|
||||
required: true
|
||||
- name: password
|
||||
in: formData
|
||||
description: |
|
||||
the password of the new user
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/users/{user}:
|
||||
get:
|
||||
operationId: get_user
|
||||
summary: get a given user
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
parameters:
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the user ID or username
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
$ref: "#/definitions/Users"
|
||||
put:
|
||||
operationId: edit_user
|
||||
summary: edit a given user
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
|
||||
Possible values for *action*:
|
||||
- `takeOwnership`: The admin takes the ownership of ALL boards of the user (archived and not archived) where the user is admin on.
|
||||
- `disableLogin`: Disable a user (the user is not allowed to login and his login tokens are purged)
|
||||
- `enableLogin`: Enable a user
|
||||
tags:
|
||||
- Users
|
||||
consumes:
|
||||
- multipart/form-data
|
||||
- application/json
|
||||
parameters:
|
||||
- name: action
|
||||
in: formData
|
||||
description: |
|
||||
the action
|
||||
type: string
|
||||
required: true
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the user ID
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
title:
|
||||
type: string
|
||||
delete:
|
||||
operationId: delete_user
|
||||
summary: Delete a user
|
||||
description: |
|
||||
Only the admin user (the first user) can call the REST API.
|
||||
tags:
|
||||
- Users
|
||||
parameters:
|
||||
- name: user
|
||||
in: path
|
||||
description: |
|
||||
the ID of the user to delete
|
||||
type: string
|
||||
required: true
|
||||
produces:
|
||||
- application/json
|
||||
security:
|
||||
- UserSecurity: []
|
||||
responses:
|
||||
'200':
|
||||
description: |-
|
||||
200 response
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
_id:
|
||||
type: string
|
||||
/api/users/{user}/boards:
|
||||
get:
|
||||
operationId: get_boards_from_user
|
||||
|
|
@ -4122,361 +3757,3 @@ definitions:
|
|||
- createdAt
|
||||
- modifiedAt
|
||||
- type
|
||||
Users:
|
||||
type: object
|
||||
description: A User in wekan
|
||||
properties:
|
||||
username:
|
||||
description: |
|
||||
the username of the user
|
||||
type: string
|
||||
x-nullable: true
|
||||
orgs:
|
||||
description: |
|
||||
the list of organizations that a user belongs to
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/UsersOrgs"
|
||||
x-nullable: true
|
||||
teams:
|
||||
description: |
|
||||
the list of teams that a user belongs to
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/UsersTeams"
|
||||
x-nullable: true
|
||||
emails:
|
||||
description: |
|
||||
the list of emails attached to a user
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/UsersEmails"
|
||||
x-nullable: true
|
||||
createdAt:
|
||||
description: |
|
||||
creation date of the user
|
||||
type: string
|
||||
modifiedAt:
|
||||
type: string
|
||||
profile:
|
||||
description: |
|
||||
profile settings
|
||||
$ref: "#/definitions/UsersProfile"
|
||||
x-nullable: true
|
||||
services:
|
||||
description: |
|
||||
services field of the user
|
||||
type: object
|
||||
x-nullable: true
|
||||
heartbeat:
|
||||
description: |
|
||||
last time the user has been seen
|
||||
type: string
|
||||
x-nullable: true
|
||||
isAdmin:
|
||||
description: |
|
||||
is the user an admin of the board?
|
||||
type: boolean
|
||||
x-nullable: true
|
||||
createdThroughApi:
|
||||
description: |
|
||||
was the user created through the API?
|
||||
type: boolean
|
||||
x-nullable: true
|
||||
loginDisabled:
|
||||
description: |
|
||||
loginDisabled field of the user
|
||||
type: boolean
|
||||
x-nullable: true
|
||||
authenticationMethod:
|
||||
description: |
|
||||
authentication method of the user
|
||||
type: string
|
||||
sessionData:
|
||||
description: |
|
||||
profile settings
|
||||
$ref: "#/definitions/UsersSessiondata"
|
||||
x-nullable: true
|
||||
importUsernames:
|
||||
description: |
|
||||
username for imported
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
x-nullable: true
|
||||
lastConnectionDate:
|
||||
type: string
|
||||
x-nullable: true
|
||||
required:
|
||||
- createdAt
|
||||
- modifiedAt
|
||||
- authenticationMethod
|
||||
UsersProfile:
|
||||
type: object
|
||||
properties:
|
||||
avatarUrl:
|
||||
description: |
|
||||
URL of the avatar of the user
|
||||
type: string
|
||||
emailBuffer:
|
||||
description: |
|
||||
list of email buffers of the user
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
fullname:
|
||||
description: |
|
||||
full name of the user
|
||||
type: string
|
||||
showDesktopDragHandles:
|
||||
description: |
|
||||
does the user want to show desktop drag handles?
|
||||
type: boolean
|
||||
hideCheckedItems:
|
||||
description: |
|
||||
does the user want to hide checked checklist items?
|
||||
type: boolean
|
||||
cardMaximized:
|
||||
description: |
|
||||
has user clicked maximize card?
|
||||
type: boolean
|
||||
customFieldsGrid:
|
||||
description: |
|
||||
has user at card Custom Fields have Grid (false) or one per row (true) layout?
|
||||
type: boolean
|
||||
hiddenSystemMessages:
|
||||
description: |
|
||||
does the user want to hide system messages?
|
||||
type: boolean
|
||||
hiddenMinicardLabelText:
|
||||
description: |
|
||||
does the user want to hide minicard label texts?
|
||||
type: boolean
|
||||
initials:
|
||||
description: |
|
||||
initials of the user
|
||||
type: string
|
||||
invitedBoards:
|
||||
description: |
|
||||
board IDs the user has been invited to
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
language:
|
||||
description: |
|
||||
language of the user
|
||||
type: string
|
||||
moveAndCopyDialog:
|
||||
description: |
|
||||
move and copy card dialog
|
||||
type: object
|
||||
moveChecklistDialog:
|
||||
description: |
|
||||
move checklist dialog
|
||||
type: object
|
||||
copyChecklistDialog:
|
||||
description: |
|
||||
copy checklist dialog
|
||||
type: object
|
||||
notifications:
|
||||
description: |
|
||||
enabled notifications for the user
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/UsersProfileNotifications"
|
||||
rescueCardDescription:
|
||||
description: |
|
||||
show dialog for saving card description on unintentional card closing
|
||||
type: boolean
|
||||
showCardsCountAt:
|
||||
description: |
|
||||
showCardCountAt field of the user
|
||||
type: number
|
||||
startDayOfWeek:
|
||||
description: |
|
||||
startDayOfWeek field of the user
|
||||
type: number
|
||||
starredBoards:
|
||||
description: |
|
||||
list of starred board IDs
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
x-nullable: true
|
||||
icode:
|
||||
description: |
|
||||
icode
|
||||
type: string
|
||||
boardView:
|
||||
description: |
|
||||
boardView field of the user
|
||||
type: string
|
||||
enum:
|
||||
- board-view-swimlanes
|
||||
- board-view-lists
|
||||
- board-view-cal
|
||||
listSortBy:
|
||||
description: |
|
||||
default sort list for user
|
||||
type: string
|
||||
enum:
|
||||
- -modifiedat
|
||||
- modifiedat
|
||||
- -title
|
||||
- title
|
||||
- -sort
|
||||
- sort
|
||||
templatesBoardId:
|
||||
description: |
|
||||
Reference to the templates board
|
||||
type: string
|
||||
cardTemplatesSwimlaneId:
|
||||
description: |
|
||||
Reference to the card templates swimlane Id
|
||||
type: string
|
||||
listTemplatesSwimlaneId:
|
||||
description: |
|
||||
Reference to the list templates swimlane Id
|
||||
type: string
|
||||
boardTemplatesSwimlaneId:
|
||||
description: |
|
||||
Reference to the board templates swimlane Id
|
||||
type: string
|
||||
required:
|
||||
- templatesBoardId
|
||||
- cardTemplatesSwimlaneId
|
||||
- listTemplatesSwimlaneId
|
||||
- boardTemplatesSwimlaneId
|
||||
UsersSessiondata:
|
||||
type: object
|
||||
properties:
|
||||
totalHits:
|
||||
description: |
|
||||
Total hits from last searchquery['members.userId'] = Meteor.userId();
|
||||
last hit that was returned
|
||||
type: number
|
||||
UsersOrgs:
|
||||
type: object
|
||||
properties:
|
||||
orgId:
|
||||
description: |
|
||||
The uniq ID of the organization
|
||||
type: string
|
||||
orgDisplayName:
|
||||
description: |
|
||||
The display name of the organization
|
||||
type: string
|
||||
required:
|
||||
- orgId
|
||||
- orgDisplayName
|
||||
UsersTeams:
|
||||
type: object
|
||||
properties:
|
||||
teamId:
|
||||
description: |
|
||||
The uniq ID of the team
|
||||
type: string
|
||||
teamDisplayName:
|
||||
description: |
|
||||
The display name of the team
|
||||
type: string
|
||||
required:
|
||||
- teamId
|
||||
- teamDisplayName
|
||||
UsersEmails:
|
||||
type: object
|
||||
properties:
|
||||
address:
|
||||
description: |
|
||||
The email address
|
||||
type: string
|
||||
verified:
|
||||
description: |
|
||||
Has the email been verified
|
||||
type: boolean
|
||||
required:
|
||||
- address
|
||||
- verified
|
||||
UsersProfileMoveandcopydialog:
|
||||
type: object
|
||||
properties:
|
||||
boardId:
|
||||
description: |
|
||||
last selected board id
|
||||
type: string
|
||||
swimlaneId:
|
||||
description: |
|
||||
last selected swimlane id
|
||||
type: string
|
||||
listId:
|
||||
description: |
|
||||
last selected list id
|
||||
type: string
|
||||
required:
|
||||
- boardId
|
||||
- swimlaneId
|
||||
- listId
|
||||
UsersProfileMovechecklistdialog:
|
||||
type: object
|
||||
properties:
|
||||
boardId:
|
||||
description: |
|
||||
last selected board id
|
||||
type: string
|
||||
swimlaneId:
|
||||
description: |
|
||||
last selected swimlane id
|
||||
type: string
|
||||
listId:
|
||||
description: |
|
||||
last selected list id
|
||||
type: string
|
||||
cardId:
|
||||
description: |
|
||||
last selected card id
|
||||
type: string
|
||||
required:
|
||||
- boardId
|
||||
- swimlaneId
|
||||
- listId
|
||||
- cardId
|
||||
UsersProfileCopychecklistdialog:
|
||||
type: object
|
||||
properties:
|
||||
boardId:
|
||||
description: |
|
||||
last selected board id
|
||||
type: string
|
||||
swimlaneId:
|
||||
description: |
|
||||
last selected swimlane id
|
||||
type: string
|
||||
listId:
|
||||
description: |
|
||||
last selected list id
|
||||
type: string
|
||||
cardId:
|
||||
description: |
|
||||
last selected card id
|
||||
type: string
|
||||
required:
|
||||
- boardId
|
||||
- swimlaneId
|
||||
- listId
|
||||
- cardId
|
||||
UsersProfileNotifications:
|
||||
type: object
|
||||
properties:
|
||||
activity:
|
||||
description: |
|
||||
The id of the activity this notification references
|
||||
type: string
|
||||
read:
|
||||
description: |
|
||||
the date on which this notification was read
|
||||
type: string
|
||||
required:
|
||||
- activity
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ const pkgdef :Spk.PackageDefinition = (
|
|||
appTitle = (defaultText = "Wekan"),
|
||||
# The name of the app as it is displayed to the user.
|
||||
|
||||
appVersion = 699,
|
||||
appVersion = 700,
|
||||
# Increment this for every release.
|
||||
|
||||
appMarketingVersion = (defaultText = "6.99.9~2023-07-18"),
|
||||
appMarketingVersion = (defaultText = "7.00~2023-07-19"),
|
||||
# Human-readable presentation of the app version.
|
||||
|
||||
minUpgradableAppVersion = 0,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
name: wekan
|
||||
version: '6.99.9'
|
||||
version: '7.00'
|
||||
base: core20
|
||||
summary: Open Source kanban
|
||||
description: |
|
||||
|
|
@ -168,9 +168,9 @@ parts:
|
|||
# Cleanup
|
||||
mkdir .build
|
||||
cd .build
|
||||
wget https://github.com/wekan/wekan/releases/download/v6.99.9/wekan-6.99.9-amd64.zip
|
||||
unzip wekan-6.99.9-amd64.zip
|
||||
rm wekan-6.99.9-amd64.zip
|
||||
wget https://github.com/wekan/wekan/releases/download/v7.00/wekan-7.00-amd64.zip
|
||||
unzip wekan-7.00-amd64.zip
|
||||
rm wekan-7.00-amd64.zip
|
||||
cd ..
|
||||
##cd .build/bundle
|
||||
##find . -type d -name '*-garbage*' | xargs rm -rf
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue