Skip to main content

Store app settings

  • How-to
  • 13 minutes

This guide shows you how to create a settings schema and consume settings values in your UI.

Note

All authenticated users of the app can read app settings. Read more about the general concept of App settings.

Install the SDK

First, you need to install the required SDK via the terminal as follows:

npm i @dynatrace-sdk/client-app-settings-v2

Migration guide

The @dynatrace-sdk/client-app-settings-v2 SDK replaces @dynatrace-sdk/client-app-settings.

The following methods now only accept a single schemaId, since the schemaIds parameter has been replaced by schemaId:

  • getEffectiveAppSettingsValues
  • getAppSettingsObjects

The AppSettingsErrorEnvelope parameter has been replaced by ErrorResponse.

Only version 2 supports new features such as filtering, sorting, and owner-based access control. We recommend using the @dynatrace-sdk/client-app-settings-v2 SDK.

Define a settings schema

A settings schema is a JSON file that defines the structure of the values stored in the app settings. You can create any number of schemas in your project's /settings/schemas directory, with the only restriction that each schema definition file name must end in .schema.json.

Tip

If you want your IDE to provide autocompletion and detailed documentation, use the $schema keyword in your setting schema to reference the JSON Schema. You can also import it manually if your IDE doesn't support that mechanism.

Here is an example of a schema that allows you to configure connections to a fictional messaging service:

my-example.schema.json
settings/schemas/my-example.schema.json
{
"$schema": "https://developer.dynatrace.com/docs-assets/schema_strict_apps.json",
"dynatrace": "1",
"schemaId": "my-example",
"version": "1.0.0",
"displayName": "Allows you to configure connections to a fictional messaging service",
"description": "",
"multiObject": true,
"maxObjects": 10,
"summaryPattern": "Messaging Service {url} via {tokenType}",
"ordered": false,
"ownerBasedAccessControl": false,
"enums": {
"Type": {
"displayName": "Type",
"description": "",
"documentation": "",
"items": [
{
"value": "basic",
"displayName": "Basic Authentication"
},
{
"value": "pat",
"displayName": "Personal Access Token"
},
{
"value": "cloud-token",
"displayName": "Access Token"
}
],
"type": "enum"
}
},
"properties": {
"url": {
"displayName": "URL",
"description": "The URL of the messaging service",
"type": "text",
"default": "",
"nullable": false,
"constraints": [
{
"type": "PATTERN",
"customMessage": "The URL must be secure (https://) and must not contain a trailing slash",
"pattern": "^https://.*[^/]$"
}
]
},
"token": {
"displayName": "Token",
"description": "A secret token",
"type": "secret",
"default": "",
"nullable": false
},
"tokenType": {
"displayName": "Type",
"description": "Type of authentication method that should be used",
"default": "basic",
"type": {
"$ref": "#/enums/Type"
},
"nullable": false
},
"channels": {
"displayName": "Channels",
"description": "A list of channels on the messaging service",
"type": "list",
"items": {
"type": "text"
}
},
"isEnabled": {
"displayName": "Enabled",
"description": "Enable the integration of the messaging service",
"type": "boolean",
"default": false,
"nullable": false
}
}
}

Use secrets

When you use secrets in your app settings, a default security mechanism protects them from exfiltration.

For example, if you store an access token along with the URL for a service to authenticate, any URL change ideally requires you to resubmit the secret. Otherwise, your app could connect to the changed URL and leak the access token. You can prevent such a leak by resubmitting the secret after changing any properties related to it, such as URLs, IP addresses, port numbers, service names, and others.

To make this easy, app settings have a secret resubmission validation in place, which is achieved and configured with the help of a built-in container constraint.

Suppose the schema has secrets, and you haven't manually added a resubmission constraint. In this case, the schema will behave as if it had a constraint that requires you to resubmit the secret on any property change.

Therefore, by default, you'll have to resubmit the secret after any changes to its related properties. Add a constraint object to the list of constraints to change this default behavior. The constraint object has two mandatory fields, "type": "SECRET_RESUBMISSION", "checkAllProperties": false, and an optional one, "customMessage".

For every property related to the secret, add "forceSecretResubmission": true. The forceSecretResubmission property on an input property is only available if a validator constraint of type SECRET_RESUBMISSION exists. Otherwise, the schema registration will fail with a validation error, which means the automatism fallback always considers all properties and doesn't have to deal with the forceSecretResubmission properties.

Here is an example of a schema with a manually configured resubmission validation:

my-example-secrets.schema.json
settings/schemas/my-example-secrets.schema.json
{
"dynatrace": "1",
"schemaId": "my-example-secrets",
"version": "1.0.0",
"displayName": "Allows you to configure connections to a fictional messaging service",
"description": "",
"multiObject": true,
"maxObjects": 10,
"summaryPattern": "Messaging Service {url}",
"ordered": false,
"properties": {
"isEnabled": {
"displayName": "Enabled",
"description": "Enable the integration of the messaging service",
"type": "boolean",
"default": false,
"nullable": false
},
"description": {
"displayName": "Description of the connection",
"type": "text",
"default": "",
"nullable": false
},
"url": {
"displayName": "URL",
"description": "The URL of the messaging service",
"type": "text",
"default": "",
"nullable": false,
"forceSecretResubmission": true,
"constraints": [
{
"type": "PATTERN",
"customMessage": "The URL must be secure (https://) and must not contain a trailing slash",
"pattern": "^https://.*[^/]$"
}
]
},
"token": {
"displayName": "Token",
"description": "A secret token",
"type": "secret",
"default": "",
"nullable": false
}
},
"constraints": [
{
"type": "SECRET_RESUBMISSION",
"customMessage": "For security reasons, please re-enter the token before saving the settings.",
"checkAllProperties": false
}
]
}

Limitations

  • Each schema can't exceed 100KiB.
  • The settings folder can't exceed 1MiB.

Local development

Caution

The app settings plugin described in this chapter is still experimental and might change.

Although the autogenerated settings UI is available only after you deploy your app, you can mock the settings values locally for easier development. The app settings plugin allows you to provide, access, and update these mocked values during development.

First, install the plugin as a dev dependency:

npm install --save-dev @dynatrace-sdk/dt-app-plugin-client-app-settings-v2

Next, register the plugin in your app configuration file, add the app-settings:objects:read app scope, and configure the file watcher:

{
"environmentUrl": "<Your-Environment-URL>",
"app": {
"id": "<Your-App-ID>",
"name": "<Your-App-Name>",
"version": "0.0.0",
"description": "<Your-App-Description>",
"scopes": [{ "name": "app-settings:objects:read", "comment": "Read app settings" }]
},
"plugins": ["@dynatrace-sdk/dt-app-plugin-client-app-settings-v2"],
"dev": {
"fileWatcher": {
"ignore": ["**/{permissions,secrets,values,values.shadow}.json"]
}
}
}

After you start the development server, the app settings plugin creates some files:

  • settings/local-mock-data/values.json
  • settings/local-mock-data/secrets.json
  • settings/local-mock-data/permissions.json

Let's examine these files in the next sections.

Use local values

The settings/local-mock-data/values.json file allows you to provide the mocked values for your settings schema. When you fetch settings in your app locally, the plugin will handle the request and return the mocked values. Following is an example that shows all the properties you can set (schemaId and value are required; the rest is optional):

values.json
settings/local-mock-data/values.json
[
{
"schemaId": "my-example",
"value": {
"url": "https://foo.bar/messaging",
"token": "a-secret-basic-token",
"tokenType": "basic",
"channels": ["admin-notifications", "user-notifications"],
"isEnabled": true
},
"schemaVersion": "1",
"summary": "Messaging Service https://foo.bar/messaging via Basic Authentication",
"searchSummary": "Messaging Service https://foo.bar/messaging via Basic Authentication",
"modificationInfo": {
"createdBy": "foo",
"createdTime": "2023-10-10T10:00:00.000Z",
"lastModifiedBy": "bar",
"lastModifiedTime": "2023-11-11T11:00:00.000Z"
}
},
{
"schemaId": "my-example",
"value": {
"url": "https://foo.bar/messaging",
"token": "a-secret-personal-access-token",
"tokenType": "pat",
"channels": ["admin-notifications", "user-notifications"],
"isEnabled": true
},
"schemaVersion": "1",
"summary": "Messaging Service https://foo.bar/messaging via Personal Access Token",
"searchSummary": "Messaging Service https://foo.bar/messaging via Personal Access Token",
"modificationInfo": {
"createdBy": "foo",
"createdTime": "2023-08-08T08:00:00.000Z",
"lastModifiedBy": "baz",
"lastModifiedTime": "2023-09-09T09:00:00.000Z"
}
}
]

The above example has one issue: the access tokens are exposed as plain text. The app settings plugin also offers a solution to this problem.

Use local secrets

A common use case for app settings is storing secrets. The app settings plugin provides a way to simulate the same behavior locally by defining them in the settings/local-mock-data/secrets.json file. Following is an example:

settings/local-mock-data/secrets.json
{
"basicToken": "a-secret-basic-token",
"personalAccessToken": "a-secret-personal-access-token"
}

After the secrets are defined, you can now use them in the values.json file:

settings/local-mock-data/values.json
[
{
"schemaId": "my-example",
"value": {
"url": "https://foo.bar/messaging",
"token": "{{basicToken}}",
"tokenType": "basic",
"channels": ["admin-notifications", "user-notifications"],
"isEnabled": true
}
},
{
"schemaId": "my-example",
"value": {
"url": "https://foo.bar/messaging",
"token": "{{personalAccessToken}}",
"tokenType": "pat",
"channels": ["admin-notifications", "user-notifications"],
"isEnabled": true
}
}
]

If the settings are now read via App functions, the secrets are returned in plain text. However, if you read them elsewhere, they will be returned as a masked value, similar to when deploying the app.

Note, however, that when you update a value locally via the SDK, the secrets.json file isn't updated, and the property loses its secret attributes.

Use local permissions

The settings/local-mock-data/permissions.json file allows you to provide the mocked permissions for your settings schema. The plugin will use this to handle requests to resolve effective permissions and to fill the resourceContext field in the response to the fetch settings values request. Following is an example of defining permissions for settings schema with id "my-example":

{
"my-example": [
{
"permission": "app-settings:objects:read",
"granted": "true"
},
{
"permission": "app-settings:objects:write",
"granted": "false"
}
]
}

The plugin considers each of the two possible permissions (app-settings:objects:read, app-settings:objects:write) as granted for the current user unless the permissions.json file contains another value for the "granted" field for the given schema and permission.
For the resourceContext part of the settings values response, only "granted": "false" is treated as if the user wouldn't have the correspondent permission. Any other value (like "true", "condition" or missing value) is considered as "granted": "true". Also, note that the plugin doesn't use the permissions.json file to control user access while performing read or write operations with settings values.

Update local settings

Of course, you can update your values.json file at any point to update the settings for your app, but the plugin also supports modifications. For this purpose, when you execute one such operation, the plugin creates a copy of the values.json file in settings/local-mock-data/persistence/values.shadow.json. If this file exists, all read and write operations will use it instead of the settings/local-mock-data/values.json you created manually.

To restore the state you configured, simply delete the settings/local-mock-data/persistence folder.

Limitations

  • Local settings values aren't validated against the local schemas.
  • Intents to open settings pages don't work.

Get effective settings value

Effective values are the values that are stored in the settings or the default value. Use this method if you want to use settings in your app.

To retrieve the effective values for one or many settings schemas, use the useSettingsV2 React hook from the @dynatrace-sdk/react-hooks package. This hook expects the schema identifier in the schemaId parameter. A single call will get you the effective values for a single schema.

By default, useSettingsV2 only returns the value. The hook can return additional fields when you specify them in a comma-separated string in the addFields parameter.

In the following example, you're getting effective settings values for the my-example schemas:

import React from 'react';
import { useSettingsV2 } from '@dynatrace-sdk/react-hooks';
import { ExternalLink, Paragraph } from '@dynatrace/strato-components/typography';
import { Flex } from '@dynatrace/strato-components/layouts';

export const App = () => {
const { data, isLoading } = useSettingsV2({
schemaId: 'my-example',
addFields: 'summary, schemaId',
});

return (
<Flex>
{!isLoading && data && (
<>
<Paragraph>{data.items[0]?.summary}</Paragraph>
<ExternalLink href={data.items[0]?.value?.url}>My external link</ExternalLink>
</>
)}
</Flex>
);
};

The default value depends on the multiObject property of the schema:

  • false: if it's false, a single default object is created. Its properties are propagated with the default values defined in your schema.
  • true: if it's true, an empty collection is created.
Tip

This operation requires the scope app-settings:objects:read. Read more about scopes in this guide.

Store settings values

To store new values for a settings schema, use the useCreateSettingsV2 hook.

The useCreateSettingsV2 hook returns the objectId and version of the created settings object. You can use them to subsequently update or delete settings.

In the following example, you store a value accessible to the fictional messaging service integration from the my-example schema. The service can now use the specific URL and basic access token:

import React from 'react';
import { useCreateSettingsV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { execute } = useCreateSettingsV2();

const handleOnClick = () => {
execute({
body: {
schemaId: 'my-example',
value: {
url: 'https://foo.bar/messaging',
token: 'a-secret-basic-token',
tokenType: 'basic',
channels: ['admin-notifications', 'user-notifications'],
isEnabled: true,
},
},
});
};

return <Button onClick={handleOnClick}>Create settings</Button>;
};
Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Get stored settings values

To fetch previously stored values for a settings schema, use the useSettingsObjectsV2 hook. Use this and the useUpdateSettingsV2 hook if you want to manage settings in your app.

This hook expects the schema identifier in the schemaId parameter.

By default, useSettingsObjectsV2 only returns the objectId and version parameters. You can define extra fields to return by specifying them in a comma-separated string in the addFields parameter.

By specifying the respective parameters, you can also filter and sort the effective values. You can use the following fields to filter:

  • modificationInfo.createdBy
  • modificationInfo.createdTime
  • modificationInfo.lastModifiedBy
  • modificationInfo.lastModifiedTime
  • value with properties and sub-properties separated by dot. For example, value.isEnabled = true.
  • owner.type
  • owner.id

You can use the following fields to sort:

  • modificationInfo.createdBy
  • modificationInfo.createdTime
  • modificationInfo.lastModifiedBy
  • modificationInfo.lastModifiedTime
  • value with properties and sub-properties separated by dot (for example, value.isEnabled)

Note that only fields included in the response via addFields can be used for filtering and sorting.

import React from 'react';
import { useSettingsObjectsV2 } from '@dynatrace-sdk/react-hooks';
import { ExternalLink, Paragraph } from '@dynatrace/strato-components/typography';
import { Flex } from '@dynatrace/strato-components/layouts';

export const App = () => {
const { data, isLoading } = useSettingsObjectsV2({
schemaId: 'my-example',
addFields: 'value, summary',
});

return (
<Flex>
{!isLoading && data && (
<>
<Paragraph>{data.items[0]?.summary}</Paragraph>
<ExternalLink href={data.items[0]?.value?.url}>My external url</ExternalLink>
</>
)}
</Flex>
);
};
Tip

This operation requires the scope app-settings:objects:read. Read more about scopes in this guide.

Update settings values

To update the value for a settings schema, use the useUpdateSettingsV2 hook.

The useUpdateSettingsV2 hook returns the version of the updated settings object, which you can use to update the object again.

In the following example, you edit a value accessible to the fictional messaging service integration from the my-example schema. The service can now use the personal access token:

import React from 'react';
import { useSettingsObjectsV2, useUpdateSettingsV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
});
const { execute } = useUpdateSettingsV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: data.items[0].objectId,
optimisticLockingVersion: data.items[0].version,
body: {
value: {
url: 'https://foo.bar/messaging',
token: 'a-secret-personal-access-token',
tokenType: 'pat',
channels: ['admin-notifications', 'user-notifications'],
isEnabled: true,
},
},
});
}
};

return <Button onClick={handleOnClick}>Update settings</Button>;
};

Remember that each setting has a version that changes each time its value changes. You need to pass the current version for any operation that modifies the value.

Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Delete settings values

To delete a value for a settings schema, use the useDeleteSettingsV2 hook. You need to provide the optimisticLockingVersion of the value you want to delete, as shown in the following example:

import React from 'react';
import { useSettingsObjectsV2, useDeleteSettingsV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
});
const { execute } = useDeleteSettingsV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: data.items[0].objectId,
optimisticLockingVersion: data.items[0].version,
});
}
};

return <Button onClick={handleOnClick}>Delete settings</Button>;
};
Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Get effective settings permissions

To get the effective settings permissions for the calling user in the environment, use the useEffectivePermissionsV2 hook. In the following example, you're checking whether the user has app-settings:objects:read and app-settings:objects:write permissions for my-example-1 and my-example-2 schemas:

import React from 'react';
import { Container, Flex, Text } from '@dynatrace/strato-components';
import { BlockIcon } from '@dynatrace/strato-icons';
import { useEffectivePermissionsV2 } from '@dynatrace-sdk/react-hooks';

export const App = () => {
const { data } = useEffectivePermissionsV2({
body: {
permissions: [
{
permission: 'app-settings:objects:read',
context: { schemaId: 'my-example-1' },
},
{
permission: 'app-settings:objects:write',
context: { schemaId: 'my-example-2' },
},
],
},
});

return (
<Container>
{data && data[0].granted === 'false' && (
<Flex>
<BlockIcon />
<Text>Permission denied. Contact your account admin.</Text>
</Flex>
)}
</Container>
);
};

The function returns an array containing information about requested permissions in the following format:

[
{
"permission": "app-settings:objects:read",
"granted": "true",
"context": { "schemaId": "my-example-1" }
},
{
"permission": "app-settings:objects:write",
"granted": "false",
"context": { "schemaId": "my-example-2" }
}
]
Tip

This operation requires one of the following scopes:

  • app-settings:objects:read
  • app-settings:objects:write
Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Owner-based access control

If a schema has the ownerBasedAccessControl property set to true, users can more finely control which users can access specific settings. For these types of schemas, the user that first stores a settings object is the owner of that object. By default, only the owner can access these objects, but the following sections explain how to share control over these objects. These APIs only work on a single-settings object per request. For the examples listed below, assume the my-example schema has the ownerBasedAccessControl property set to true.

The following sections mention accessors. An accessor can be a specific user, a group, or the all-users type, which applies to all users. When using the all-users type, you don't need to specify any ID.

Transfer ownership

An owner has read and write access to their object. A settings object can have only one owner, but the owner can be any kind of accessor.

To transfer this ownership of a settings object to a different accessor, use the useTransferOwnershipV2 hook.

After the request is sent, the previous owner loses access, so owners might want to use the permission mechanism described in the next section to add permissions they want to retain before transferring ownership.

In the following example, you transfer the ownership of a settings object to a fictional user on the first object of the my-example schema, assuming you have ownership over that object:

import React from 'react';
import { useSettingsObjectsV2, useTransferOwnershipV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
});
const { execute } = useTransferOwnershipV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: data.items[0].objectId,
body: {
newOwner: {
type: 'user',
id: '550e8400-e29b-41d4-a716-446655440000',
},
},
});
}
};

return <Button onClick={handleOnClick}>Transfer ownership</Button>;
};
Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Add permissions for an accessor to an object

To grant permissions for an accessor to an existing settings object, use the useCreatePermissionsV2 hook.

You can grant the accessor either read-only or read-and-write access. You can only use an accessor without permission on the object. For the others, you should use the update function, which is documented further below.
Only users with read and write access on the object can add permissions for a new accessor.

In the following example, you grant read and write access to a fictional group on the first object of the my-example schema. This means that all users belonging to this group receive read and write access:

import React from 'react';
import { useSettingsObjectsV2, useCreatePermissionsV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
});
const { execute } = useCreatePermissionsV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: data.items[0].objectId,
body: {
accessor: {
type: 'group',
id: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
},
permissions: ['r', 'w'],
},
});
}
};

return <Button onClick={handleOnClick}>Add permissions</Button>;
};
Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Get permissions of all accessors of an object

Use the usePermissionsV2 hook to get an overview of all permissions for each accessor of a specific settings object.

Only users with read access to the object can get the permissions overview.

In the following example, you get a permission overview for the object with a specific objectId:

import React from 'react';
import { usePermissionsV2 } from '@dynatrace-sdk/react-hooks';
import { ExternalLink, Paragraph } from '@dynatrace/strato-components/typography';
import { Flex } from '@dynatrace/strato-components/layouts';

export const App = () => {
const { data, isLoading } = usePermissionsV2({
objectId: '<some objectId>',
});

return (
<Flex>
{!isLoading && data && (
<List>
{data.accessors.map((item) => (
<Text key={item.accessor.id}>
{item.accessor.type} {item.accessor.id}
</Text>
))}
</List>
)}
</Flex>
);
};
Tip

This operation requires the scope app-settings:objects:read. Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Update permissions for an accessor on an object

To update the permissions of an accessor for a specific settings object, use either the useUpdateAccessorPermissionsV2 or the useUpdateAllUsersPermissionsV2 hook.

The first function is for accessors of type user and group, the second for the all-users type. To update permissions for an accessor, you must first add them via the hook documented above.

Only users that have read and write access on the object can update permissions for an accessor.

In the following example, you update the permission of a fictional group for the first object of the my-example schema to read-only:

import React from 'react';
import { useSettingsObjectsV2, useUpdateAccessorPermissionsV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
});
const { execute } = useUpdateAccessorPermissionsV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: response.items[0].objectId,
accessorType: 'group',
accessorId: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
body: {
permissions: ['r'],
},
});
}
};

return <Button onClick={handleOnClick}>Update accessor permissions</Button>;
};
Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Remove permissions for an accessor on an object

To remove all granted permissions for an accessor on an object, use either the useDeleteAccessorPermissionsV2 or the useDeleteAllUsersPermissionsV2 hook.

If the accessor doesn't have access via different means, such as a group or via the owner, the object will be inaccessible after this call.

Only users with read and write access on the object can remove permissions for an accessor.

In the following example, you remove all permissions of the all-users accessor of the first object of the my-example schema:

import React from 'react';
import { useSettingsObjectsV2, useDeleteAllUsersPermissionsV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
});
const { execute } = useDeleteAllUsersPermissionsV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: response.items[0].objectId,
});
}
};

return <Button onClick={handleOnClick}>Delete all-users permissions</Button>;
};
Tip

This operation requires the scope app-settings:objects:write. Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Administrator access

You can bypass the access checks for specific administrator users to avoid:

  • A user locking themselves out of a settings object.
  • The owner of a settings object being unavailable.
  • Not having sufficient permissions for a settings object.

All documented hooks besides useEffectivePermissionsV2 and useCreateSettingsV2 accept the adminAccess parameter. Passing this parameter with the value true allows users to modify any object they want, without having to worry about the permissions granted or owner assigned.

This requires the additional scope of app-settings:objects:admin.

In the following example, you transfer the ownership of a settings object to a fictional user on the first object of the my-example schema, without needing to be the current owner and without having access to the settings object:

import React from 'react';
import { useSettingsObjectsV2, useTransferOwnershipV2 } from '@dynatrace-sdk/react-hooks';
import { Button } from '@dynatrace/strato-components/buttons';

export const App = () => {
const { data } = useSettingsObjectsV2({
schemaId: 'my-example',
adminAccess: true,
});
const { execute } = useTransferOwnershipV2();

const handleOnClick = () => {
if (data) {
execute({
objectId: data.items[0].objectId,
adminAccess: true,
body: {
newOwner: {
type: 'user',
id: '550e8400-e29b-41d4-a716-446655440000',
},
},
});
}
};

return <Button onClick={handleOnClick}>Transfer ownership</Button>;
};
Tip

This operation requires the following scopes:

  • app-settings:objects:write
  • app-settings:objects:admin
Read more about scopes in this guide.

Note

To use await in React components, you need to wrap the asynchronous invocation in an async function. Read more about it in this guide.

Still have questions?
Find answers in the Dynatrace Community