Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add enhancements for legacy URL aliases #125960

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
25 changes: 18 additions & 7 deletions docs/api/saved-objects/bulk_resolve.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,24 @@ The API returns the following:

Only the index pattern exists, the dashboard was not found.

The `outcome` field may be any of the following:

* `"exactMatch"` -- One document exactly matched the given ID, *or* {kib} failed to find this object.
* `"aliasMatch"` -- One document with a legacy URL alias matched the given ID; in this case the `saved_object.id` field is different than the given ID.
* `"conflict"` -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the `saved_object` object is the exact match, and the `saved_object.id` field is the same as the given ID.

If the outcome is `"aliasMatch"` or `"conflict"`, the response will also include an `alias_target_id` field. This means that an alias was found for another object, and it describes that other object's ID.
[NOTE]
====
In addition to `saved_object`, several fields can be returned:

* `outcome` (required string) -- One of the following values:
- `"exactMatch"` -- One document exactly matched the given ID.
- `"aliasMatch"` -- One document with a legacy URL alias matched the given ID; in this case the `saved_object.id` field is different than
the given ID.
- `"conflict"` -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the
`saved_object` object is the exact match, and the `saved_object.id` field is the same as the given ID.
* `alias_target_id` (optional string) -- If the `outcome` is `"aliasMatch"` or `"conflict"`, the response will also include the
`alias_target_id` field. This means that an alias was found for another object, and it describes that other object's ID.
* `alias_purpose` (optional string) -- If the `outcome` is `"aliasMatch"` or `"conflict"`, the response will also include the
`alias_purpose` field. This indicates why the alias was created, and it can be used to change the client behavior accordingly. One of the
following values: `"savedObjectConversion"`, `"savedObjectImport"`

Client-side code uses these fields to behave differently depending on the `outcome` -- <<sharing-saved-objects-step-3,learn more>>.
====

Retrieve a dashboard object in the `testspace` by ID:

Expand Down
25 changes: 18 additions & 7 deletions docs/api/saved-objects/resolve.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,24 @@ The API returns the following:
}
--------------------------------------------------

The `outcome` field may be any of the following:

* `"exactMatch"` -- One document exactly matched the given ID.
* `"aliasMatch"` -- One document with a legacy URL alias matched the given ID; in this case the `saved_object.id` field is different than the given ID.
* `"conflict"` -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the `saved_object` object is the exact match, and the `saved_object.id` field is the same as the given ID.

If the outcome is `"aliasMatch"` or `"conflict"`, the response will also include an `alias_target_id` field. This means that an alias was found for another object, and it describes that other object's ID.
[NOTE]
====
In addition to `saved_object`, several fields can be returned:

* `outcome` (required string) -- One of the following values:
- `"exactMatch"` -- One document exactly matched the given ID.
- `"aliasMatch"` -- One document with a legacy URL alias matched the given ID; in this case the `saved_object.id` field is different than
the given ID.
- `"conflict"` -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the
`saved_object` object is the exact match, and the `saved_object.id` field is the same as the given ID.
* `alias_target_id` (optional string) -- If the `outcome` is `"aliasMatch"` or `"conflict"`, the response will also include the
`alias_target_id` field. This means that an alias was found for another object, and it describes that other object's ID.
* `alias_purpose` (optional string) -- If the `outcome` is `"aliasMatch"` or `"conflict"`, the response will also include the
`alias_purpose` field. This indicates why the alias was created, and it can be used to change the client behavior accordingly. One of the
following values: `"savedObjectConversion"`, `"savedObjectImport"`

Client-side code uses these fields to behave differently depending on the `outcome` -- <<sharing-saved-objects-step-3,learn more>>.
====

Retrieve a dashboard object in the `testspace` by ID:

Expand Down
15 changes: 11 additions & 4 deletions docs/developer/advanced/sharing-saved-objects.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,13 @@ TIP: See an example of this in https://github.com/elastic/kibana/pull/107256#use

The
https://github.com/elastic/kibana/blob/main/docs/development/core/server/kibana-plugin-core-server.savedobjectsresolveresponse.md[SavedObjectsResolveResponse
interface] has three fields, summarized below:
interface] has four fields, summarized below:

* `saved_object` - The saved object that was found.
* `outcome` - One of the following values: `'exactMatch' | 'aliasMatch' | 'conflict'`
* `alias_target_id` - This is defined if the outcome is `'aliasMatch'` or `'conflict'`. It means that a legacy URL alias with this ID points
to an object with a _different_ ID.
* `alias_purpose` - This is defined if the outcome is `'aliasMatch'` or `'conflict'`. It describes why the legacy URL alis was created.

The SavedObjectsClient is available both on the server-side and the client-side. You may be fetching the object on the server-side via a
custom HTTP route, or you may be fetching it on the client-side directly. Either way, the `outcome` and `alias_target_id` fields need to be
Expand Down Expand Up @@ -236,12 +237,18 @@ if (spacesApi && resolveResult.outcome === 'aliasMatch') {
// We found this object by a legacy URL alias from its old ID; redirect the user to the page with its new ID, preserving any URL hash
const newObjectId = resolveResult.alias_target_id!; // This is always defined if outcome === 'aliasMatch'
const newPath = `/this/page/${newObjectId}${window.location.hash}`; // Use the *local* path within this app (do not include the "/app/appId" prefix)
await spacesApi.ui.redirectLegacyUrl(newPath, OBJECT_NOUN);
await spacesApi.ui.redirectLegacyUrl({
path: newPath,
aliasPurpose: resolveResult.alias_purpose, <1>
objectNoun: OBJECT_NOUN <2>
});
return;
}
```
_Note that `OBJECT_NOUN` is optional, it just changes "object" in the toast to whatever you specify -- you may want the toast to say
"dashboard" or "index pattern" instead!_
<1> The `aliasPurpose` field is required as of 8.2, because the API response now includes the reason the alias was created to inform the
client whether a toast should be shown or not.
<2> The `objectNoun` field is optional, it just changes "object" in the toast to whatever you specify -- you may want the toast to say
"dashboard" or "index pattern" instead!

5. And finally, in your deep link page, add a function that will create a callout in the case of a `'conflict'` outcome:
+
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [ResolvedSimpleSavedObject](./kibana-plugin-core-public.resolvedsimplesavedobject.md) &gt; [alias\_purpose](./kibana-plugin-core-public.resolvedsimplesavedobject.alias_purpose.md)

## ResolvedSimpleSavedObject.alias\_purpose property

The reason this alias was created.

Currently this is used to determine whether or not a toast should be shown when a user is redirected from a legacy URL; if the alias was created because of saved object conversion, then we will display a toast telling the user that the object has a new URL.

\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->).

<b>Signature:</b>

```typescript
alias_purpose?: SavedObjectsResolveResponse['alias_purpose'];
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

## ResolvedSimpleSavedObject.alias\_target\_id property

The ID of the object that the legacy URL alias points to. This is only defined when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->.
The ID of the object that the legacy URL alias points to.

\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->).

<b>Signature:</b>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export interface ResolvedSimpleSavedObject<T = unknown>

| Property | Type | Description |
| --- | --- | --- |
| [alias\_target\_id?](./kibana-plugin-core-public.resolvedsimplesavedobject.alias_target_id.md) | SavedObjectsResolveResponse\['alias\_target\_id'\] | <i>(Optional)</i> The ID of the object that the legacy URL alias points to. This is only defined when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>. |
| [alias\_purpose?](./kibana-plugin-core-public.resolvedsimplesavedobject.alias_purpose.md) | SavedObjectsResolveResponse\['alias\_purpose'\] | <i>(Optional)</i> The reason this alias was created.<!-- -->Currently this is used to determine whether or not a toast should be shown when a user is redirected from a legacy URL; if the alias was created because of saved object conversion, then we will display a toast telling the user that the object has a new URL.<!-- -->\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>). |
| [alias\_target\_id?](./kibana-plugin-core-public.resolvedsimplesavedobject.alias_target_id.md) | SavedObjectsResolveResponse\['alias\_target\_id'\] | <i>(Optional)</i> The ID of the object that the legacy URL alias points to.<!-- -->\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>). |
| [outcome](./kibana-plugin-core-public.resolvedsimplesavedobject.outcome.md) | SavedObjectsResolveResponse\['outcome'\] | The outcome for a successful <code>resolve</code> call is one of the following values:<!-- -->\* <code>'exactMatch'</code> -- One document exactly matched the given ID. \* <code>'aliasMatch'</code> -- One document with a legacy URL alias matched the given ID; in this case the <code>saved_object.id</code> field is different than the given ID. \* <code>'conflict'</code> -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the <code>saved_object</code> object is the exact match, and the <code>saved_object.id</code> field is the same as the given ID. |
| [saved\_object](./kibana-plugin-core-public.resolvedsimplesavedobject.saved_object.md) | SimpleSavedObject&lt;T&gt; | The saved object that was found. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [SavedObjectsResolveResponse](./kibana-plugin-core-public.savedobjectsresolveresponse.md) &gt; [alias\_purpose](./kibana-plugin-core-public.savedobjectsresolveresponse.alias_purpose.md)

## SavedObjectsResolveResponse.alias\_purpose property

The reason this alias was created.

Currently this is used to determine whether or not a toast should be shown when a user is redirected from a legacy URL; if the alias was created because of saved object conversion, then we will display a toast telling the user that the object has a new URL.

\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->).

<b>Signature:</b>

```typescript
alias_purpose?: 'savedObjectConversion' | 'savedObjectImport';
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

## SavedObjectsResolveResponse.alias\_target\_id property

The ID of the object that the legacy URL alias points to. This is only defined when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->.
The ID of the object that the legacy URL alias points to.

\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->).

<b>Signature:</b>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export interface SavedObjectsResolveResponse<T = unknown>

| Property | Type | Description |
| --- | --- | --- |
| [alias\_target\_id?](./kibana-plugin-core-public.savedobjectsresolveresponse.alias_target_id.md) | string | <i>(Optional)</i> The ID of the object that the legacy URL alias points to. This is only defined when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>. |
| [alias\_purpose?](./kibana-plugin-core-public.savedobjectsresolveresponse.alias_purpose.md) | 'savedObjectConversion' \| 'savedObjectImport' | <i>(Optional)</i> The reason this alias was created.<!-- -->Currently this is used to determine whether or not a toast should be shown when a user is redirected from a legacy URL; if the alias was created because of saved object conversion, then we will display a toast telling the user that the object has a new URL.<!-- -->\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>). |
| [alias\_target\_id?](./kibana-plugin-core-public.savedobjectsresolveresponse.alias_target_id.md) | string | <i>(Optional)</i> The ID of the object that the legacy URL alias points to.<!-- -->\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>). |
| [outcome](./kibana-plugin-core-public.savedobjectsresolveresponse.outcome.md) | 'exactMatch' \| 'aliasMatch' \| 'conflict' | The outcome for a successful <code>resolve</code> call is one of the following values:<!-- -->\* <code>'exactMatch'</code> -- One document exactly matched the given ID. \* <code>'aliasMatch'</code> -- One document with a legacy URL alias matched the given ID; in this case the <code>saved_object.id</code> field is different than the given ID. \* <code>'conflict'</code> -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the <code>saved_object</code> object is the exact match, and the <code>saved_object.id</code> field is the same as the given ID. |
| [saved\_object](./kibana-plugin-core-public.savedobjectsresolveresponse.saved_object.md) | SavedObject&lt;T&gt; | The saved object that was found. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsResolveResponse](./kibana-plugin-core-server.savedobjectsresolveresponse.md) &gt; [alias\_purpose](./kibana-plugin-core-server.savedobjectsresolveresponse.alias_purpose.md)

## SavedObjectsResolveResponse.alias\_purpose property

The reason this alias was created.

Currently this is used to determine whether or not a toast should be shown when a user is redirected from a legacy URL; if the alias was created because of saved object conversion, then we will display a toast telling the user that the object has a new URL.

\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->).

<b>Signature:</b>

```typescript
alias_purpose?: 'savedObjectConversion' | 'savedObjectImport';
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

## SavedObjectsResolveResponse.alias\_target\_id property

The ID of the object that the legacy URL alias points to. This is only defined when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->.
The ID of the object that the legacy URL alias points to.

\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is `'aliasMatch'` or `'conflict'`<!-- -->).

<b>Signature:</b>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export interface SavedObjectsResolveResponse<T = unknown>

| Property | Type | Description |
| --- | --- | --- |
| [alias\_target\_id?](./kibana-plugin-core-server.savedobjectsresolveresponse.alias_target_id.md) | string | <i>(Optional)</i> The ID of the object that the legacy URL alias points to. This is only defined when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>. |
| [alias\_purpose?](./kibana-plugin-core-server.savedobjectsresolveresponse.alias_purpose.md) | 'savedObjectConversion' \| 'savedObjectImport' | <i>(Optional)</i> The reason this alias was created.<!-- -->Currently this is used to determine whether or not a toast should be shown when a user is redirected from a legacy URL; if the alias was created because of saved object conversion, then we will display a toast telling the user that the object has a new URL.<!-- -->\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>). |
| [alias\_target\_id?](./kibana-plugin-core-server.savedobjectsresolveresponse.alias_target_id.md) | string | <i>(Optional)</i> The ID of the object that the legacy URL alias points to.<!-- -->\*\*Note:\*\* this field is \*only\* included when an alias was found (in other words, when the outcome is <code>'aliasMatch'</code> or <code>'conflict'</code>). |
| [outcome](./kibana-plugin-core-server.savedobjectsresolveresponse.outcome.md) | 'exactMatch' \| 'aliasMatch' \| 'conflict' | The outcome for a successful <code>resolve</code> call is one of the following values:<!-- -->\* <code>'exactMatch'</code> -- One document exactly matched the given ID. \* <code>'aliasMatch'</code> -- One document with a legacy URL alias matched the given ID; in this case the <code>saved_object.id</code> field is different than the given ID. \* <code>'conflict'</code> -- Two documents matched the given ID, one was an exact match and another with a legacy URL alias; in this case the <code>saved_object</code> object is the exact match, and the <code>saved_object.id</code> field is the same as the given ID. |
| [saved\_object](./kibana-plugin-core-server.savedobjectsresolveresponse.saved_object.md) | SavedObject&lt;T&gt; | The saved object that was found. |

Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ Given a saved object type and id, generates the compound id that is stored in th
<b>Signature:</b>

```typescript
generateRawLegacyUrlAliasId(namespace: string, type: string, id: string): string;
generateRawLegacyUrlAliasId(namespace: string | undefined, type: string, id: string): string;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| namespace | string | The namespace of the saved object |
| namespace | string \| undefined | The namespace of the saved object |
| type | string | The saved object type |
| id | string | The id of the saved object |

Expand Down
2 changes: 2 additions & 0 deletions src/core/public/public.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,7 @@ export type ResolveDeprecationResponse = {

// @public
export interface ResolvedSimpleSavedObject<T = unknown> {
alias_purpose?: SavedObjectsResolveResponse['alias_purpose'];
alias_target_id?: SavedObjectsResolveResponse['alias_target_id'];
outcome: SavedObjectsResolveResponse['outcome'];
saved_object: SimpleSavedObject<T>;
Expand Down Expand Up @@ -1347,6 +1348,7 @@ export type SavedObjectsNamespaceType = 'single' | 'multiple' | 'multiple-isolat

// @public (undocumented)
export interface SavedObjectsResolveResponse<T = unknown> {
alias_purpose?: 'savedObjectConversion' | 'savedObjectImport';
alias_target_id?: string;
outcome: 'exactMatch' | 'aliasMatch' | 'conflict';
saved_object: SavedObject<T>;
Expand Down
1 change: 1 addition & 0 deletions src/core/public/saved_objects/saved_objects_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ export class SavedObjectsClient {
saved_object: simpleSavedObject,
outcome: resolveResponse.outcome,
alias_target_id: resolveResponse.alias_target_id,
alias_purpose: resolveResponse.alias_purpose,
};
}

Expand Down
Loading