navigation_views: Add backend for navigation views in left sidebar.

Fixes part of #32077.
This commit is contained in:
Aditya Kumar Kasaudhan
2024-12-17 23:40:36 +05:30
committed by Tim Abbott
parent 0dfb709152
commit c5f126c6ff
25 changed files with 1221 additions and 5 deletions

View File

@@ -1160,6 +1160,74 @@ def remove_attachment(client: Client, attachment_id: int) -> None:
validate_against_openapi_schema(result, "/attachments/{attachment_id}", "delete", "200")
@openapi_test_function("/navigation_views:get")
def get_navigation_views(client: Client) -> None:
# {code_example|start}
# Get all navigation views for the user
result = client.call_endpoint(
url="navigation_views",
method="GET",
)
# {code_example|end}
assert_success_response(result)
validate_against_openapi_schema(result, "/navigation_views", "get", "200")
@openapi_test_function("/navigation_views:post")
def add_navigation_views(client: Client) -> None:
# {code_example|start}
# Add a navigation view
request = {
"fragment": "narrow/is/alerted",
"is_pinned": True,
"name": "Alert Word",
}
result = client.call_endpoint(
url="navigation_views",
method="POST",
request=request,
)
# {code_example|end}
assert_success_response(result)
validate_against_openapi_schema(result, "/navigation_views", "post", "200")
@openapi_test_function("/navigation_views/{fragment}:patch")
def update_navigation_views(client: Client) -> None:
# Fetch navigation views for updating
result = client.call_endpoint(url="navigation_views", method="GET")
fragment = result["navigation_views"][0]["fragment"]
# {code_example|start}
# Update a navigation view's location
request = {
"is_pinned": True,
}
result = client.call_endpoint(
url=f"navigation_views/{fragment}",
method="PATCH",
request=request,
)
# {code_example|end}
assert_success_response(result)
validate_against_openapi_schema(result, "/navigation_views/{fragment}", "patch", "200")
@openapi_test_function("/navigation_views/{fragment}:delete")
def remove_navigation_views(client: Client) -> None:
# Fetch navigation views for deletion
result = client.call_endpoint(url="navigation_views", method="GET")
fragment = result["navigation_views"][0]["fragment"]
# {code_example|start}
# Remove a navigation views
result = client.call_endpoint(
url=f"navigation_views/{fragment}",
method="DELETE",
)
# {code_example|end}
assert_success_response(result)
validate_against_openapi_schema(result, "/navigation_views/{fragment}", "delete", "200")
@openapi_test_function("/saved_snippets:post")
def create_saved_snippet(client: Client) -> None:
# {code_example|start}
@@ -1901,6 +1969,10 @@ def test_users(client: Client, owner_client: Client) -> None:
remove_user_mute(client)
get_alert_words(client)
add_alert_words(client)
add_navigation_views(client)
get_navigation_views(client)
update_navigation_views(client)
remove_navigation_views(client)
create_saved_snippet(client)
# Calling this again to pass the curl examples tests as the
# `delete-saved-snippet` endpoint is called before `edit-saved-snippet`

View File

@@ -5517,6 +5517,110 @@ paths:
"op": "remove",
"draft_id": 17,
}
- type: object
additionalProperties: false
description: |
Event containing details of a newly configured navigation view.
**Changes**: New in Zulip 11.0 (feature level 390).
properties:
id:
$ref: "#/components/schemas/EventIdSchema"
type:
allOf:
- $ref: "#/components/schemas/EventTypeSchema"
- enum:
- navigation_view
op:
type: string
enum:
- add
navigation_view:
$ref: "#/components/schemas/NavigationView"
example:
{
"type": "navigation_view",
"op": "add",
"navigation_view":
{
"fragment": "narrow/is/alerted",
"is_pinned": true,
"name": "Alert Words",
},
}
- type: object
additionalProperties: false
description: |
Event containing details of an update to an existing navigation view.
**Changes**: New in Zulip 11.0 (feature level 390).
properties:
id:
$ref: "#/components/schemas/EventIdSchema"
type:
allOf:
- $ref: "#/components/schemas/EventTypeSchema"
- enum:
- navigation_view
op:
type: string
enum:
- update
fragment:
type: string
description: |
The unique URL hash of the navigation view being updated.
data:
type: object
additionalProperties: false
description: |
A dictionary containing the updated properties of the navigation view.
properties:
name:
type: string
nullable: true
description: |
The user-facing name for custom navigation views. Omit this field for built-in views.
is_pinned:
type: boolean
nullable: true
description: |
Determines whether the view is pinned (true) or hidden in the menu (false).
example:
{
"type": "navigation_view",
"op": "update",
"fragment": "narrow/is/alerted",
"data": {"is_pinned": false},
}
- type: object
additionalProperties: false
description: |
Event containing the fragment of a deleted navigation view.
**Changes**: New in Zulip 11.0 (feature level 390).
properties:
id:
$ref: "#/components/schemas/EventIdSchema"
type:
allOf:
- $ref: "#/components/schemas/EventTypeSchema"
- enum:
- navigation_view
op:
type: string
enum:
- remove
fragment:
type: string
description: |
The unique URL hash of the navigation view that was just deleted.
example:
{
"type": "navigation_view",
"op": "remove",
"fragment": "narrow/is/mentioned",
}
- type: object
additionalProperties: false
description: |
@@ -6456,6 +6560,217 @@ paths:
"result": "error",
"msg": "Draft does not exist",
}
/navigation_views:
get:
operationId: get-navigation-views
tags: ["navigation_views"]
summary: Get all navigation views
description: |
Fetch all configured custom navigation views for the current user.
**Changes**: New in Zulip 11.0 (feature level 390).
responses:
"200":
description: Success.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/JsonSuccessBase"
- additionalProperties: false
properties:
result: {}
msg: {}
navigation_views:
type: array
description: |
An array of dictionaries containing the user's navigation views.
items:
$ref: "#/components/schemas/NavigationView"
example:
{
"result": "success",
"msg": "",
"navigation_views":
[
{
"fragment": "narrow/is/alerted",
"is_pinned": false,
"name": "Alert Words",
},
],
}
post:
operationId: add-navigation-view
tags: ["navigation_views"]
summary: Add a navigation view
description: |
Adds a new custom left sidebar navigation view configuration
for the current user.
This can be used both to configure built-in navigation views,
or to add new navigation views.
**Changes**: New in Zulip 11.0 (feature level 390).
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
$ref: "#/components/schemas/NavigationView"
responses:
"200":
description: Request succeeded.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/JsonSuccessBase"
- type: object
additionalProperties: false
properties:
result: {}
msg: {}
example: {"result": "success", "msg": ""}
"400":
description: Bad request.
content:
application/json:
schema:
$ref: "#/components/schemas/CodedError"
examples:
invalid_parameters:
value:
code: "BAD_REQUEST"
msg: "fragment cannot be blank"
result: "error"
/navigation_views/{fragment}:
patch:
operationId: edit-navigation-view
tags: ["navigation_views"]
summary: Update the navigation view
description: |
Update the details of an existing configured navigation view,
such as its name or whether it's pinned.
**Changes**: New in Zulip 11.0 (feature level 390).
parameters:
- name: fragment
in: path
required: true
schema:
type: string
description: |
The unique URL hash of the navigation view to be updated.
This also serves as the identifier for the navigation view.
example: "narrow/is/alerted"
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
is_pinned:
type: boolean
description: |
Determines whether the view is pinned (true) or hidden in
the menu (false).
example: true
name:
type: string
description: |
The user-facing name for custom navigation views. Omit this
field for built-in views.
example: "Watched Phrases"
anyOf:
- required:
- is_pinned
- required:
- name
responses:
"200":
description: Success.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/JsonSuccessBase"
- additionalProperties: false
properties:
result: {}
msg: {}
example: {"result": "success", "msg": ""}
"400":
description: Bad request.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/CodedError"
- example:
{
"code": "BAD_REQUEST",
"msg": "Built-in views cannot have a custom name",
"result": "error",
}
description: |
A typical failed JSON response for invalid parameters.
"404":
description: Not Found.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/CodedError"
- description: |
A typical failed JSON response when no navigation view
exists with the provided fragment:
example:
{
"code": "NOT_FOUND",
"result": "error",
"msg": "Navigation view does not exist.",
}
delete:
operationId: remove-navigation-view
tags: ["navigation_views"]
summary: Remove a navigation view
description: |
Remove a navigation view.
**Changes**: New in Zulip 11.0 (feature level 390).
parameters:
- name: fragment
in: path
schema:
type: string
description: |
The unique URL hash of the navigation view to be removed.
This also serves as the identifier for the navigation view.
example: "narrow/is/alerted"
required: true
responses:
"200":
$ref: "#/components/responses/SimpleSuccess"
"404":
description: Not Found.
content:
application/json:
schema:
allOf:
- $ref: "#/components/schemas/CodedError"
- description: |
A typical failed JSON response for when no navigation
view exists with the provided fragment:
example:
{
"code": "BAD_REQUEST",
"result": "error",
"msg": "Navigation view does not exist.",
}
/saved_snippets:
get:
operationId: get-saved-snippets
@@ -15782,6 +16097,16 @@ paths:
The list of users other than the current user in the direct message
conversation. This will be an empty list for direct messages sent to
oneself.
navigation_views:
type: array
items:
$ref: "#/components/schemas/NavigationView"
description: |
Present if `navigation_views` is present in `fetch_event_types`.
An array of dictionaries containing data on all of the current user's
navigation views.
**Changes**: New in Zulip 11.0 (feature level 390).
saved_snippets:
type: array
items:
@@ -25489,6 +25814,46 @@ components:
- to
- topic
- content
NavigationView:
type: object
description: |
Represents a user's personal configuration for a specific
navigation view (displayed most visibly at the top of the web
application's left sidebar).
Navigation views can be either an override to the default
behavior of a built-in view, or a custom view.
**Changes**: New in Zulip 11.0 (feature level 390).
additionalProperties: false
required:
- fragment
- is_pinned
properties:
fragment:
type: string
description: |
A unique identifier for the view, used to determine navigation
behavior when clicked.
Clients should use this value to navigate to the corresponding URL hash.
example: "narrow/is/alerted"
is_pinned:
type: boolean
description: |
Determines whether the view appears directly in the sidebar or
is hidden in the "More Views" menu.
- `true` - Pinned and visible in the sidebar.
- `false` - Hidden and accessible via the "More Views" menu.
example: true
name:
type: string
nullable: true
description: |
The user-facing name for custom navigation views. Omit this
field for built-in views.
example: "Alert Words"
SavedSnippet:
type: object
description: |