Skip to main content

configurations

Retrieving Configurations and Permissions in the Loader Data

To retrieve configurations and permissions in the loader data, you need to:

  1. Define Configurations in Routes: Specify the configurations you need in the configurations field of the route definition. You can either fetch all configurations (['*']) or list specific configuration keys.
  2. Use resourceParams: This allows dynamic resolution of parameters for specific resources using placeholders like $params to construct the query or path used to fetch the configuration and permissions.
  3. Fetch Data in Loader: The loader fetches the configuration and permissions based on the defined resourceParams and configurations.

Here’s how you can set up routes, resourceParams, and configuration to get configurations in the loader data.

Example 1: Generic Configuration (configurations: ['*'])

This will retrieve all available configurations generically for the route.

Route Definition:

export const project_route = [
{
name: "menu.projects",
path: PROJECTS_ROUTES.projectView,
key: "project-view",
priority: 7,
position: IMenuPosition.Middle,
icon: {
name: "AiOutlineProject",
style: { fontSize: "large" },
},
component: () => import("./components/index"),
authority: [
IPreDefineAccountPermissions.viewSelfProjects,
IPreDefineAccountPermissions.viewOthersProjects,
],
extraPermissions: [
IPreDefineAccountPermissions.manageSelfProjects,
IPreDefineAccountPermissions.editSelfProjects,
IPreDefineAccountPermissions.createSelfProjects,
],
extraParams: ({ params }) => ({
resourceParams: {
path: IConfigCollectionName.Organizations, // Default to Organizations, could change to Projects based on logic
fragment: IConfigFragmentName.Settings,
query: {
name: "$params.orgName",
},
configKey: "", // Optional. Add the initial hierarchy of the settings, or leave empty.
},
}),
configurations: ["*"], // Fetch all configurations
},
];

Component Usage:

Within the component, the configurations and permissions retrieved via the loader can be accessed using useLoaderData:

export default () => {
const loaderData = useLoaderData<{
permissions: IPermissions;
configurations: IPreferences;
dataContext: any;
}>();

const { permissions, configurations, dataContext } = loaderData;
const { preferencesInput } = dataContext; // Use this to get the settings URI for updates

const [updateConfigurationMutation] = useUpdateConfigurationMutation();

const overrides: IConfigurationOverridesInput = {
resource: preferencesInput.editableSettingsInput, // Override based on resource
};

// Function to update specific configuration
const updateConfiguration = ({
key,
value,
}: {
key: IConfigurationsFlattenedKeys;
value: string | number | boolean;
}) => {
return updateConfigurationMutation({
variables: {
key,
input: preferencesInput,
value,
target: ConfigurationTarget.ORGANIZATION_RESOURCE, // Use based on URI or resource context
overrides,
},
});
};

// Further component logic...
};

When to Use resourceParams:

For organization-related pages, you generally do not need to specify resourceParams explicitly because the system will automatically resolve the organization's settings using the :orgName from the route. For example, the following default behavior will occur:

resourceParams = { path: 'organizations', query: { name: params.orgName }, fragment: 'settings' }

However, for resource-specific pages such as o/:orgName/projects/:projectId, you must provide resourceParams to get the specific configurations and permissions related to that resource (in this case, projectId):

resourceParams = {
path: IConfigCollectionName.Projects,
query: {
name: '$params.projectId', // Retrieves configurations for the specific project
},
fragment: IConfigFragmentName.Settings,
};

Example 2: Fetching Specific Configuration Keys

When you want to optimize the loader by fetching only specific configurations, you can define the required configuration keys in the route.

Route Definition:

export const project_route = [
{
name: "menu.projects",
path: PROJECTS_ROUTES.projectView,
key: "project-view",
priority: 7,
position: IMenuPosition.Middle,
icon: {
name: "AiOutlineProject",
style: { fontSize: "large" },
},
component: () => import("./components/index"),
authority: [
IPreDefineAccountPermissions.viewSelfProjects,
IPreDefineAccountPermissions.viewOthersProjects,
],
extraPermissions: [
IPreDefineAccountPermissions.manageSelfProjects,
IPreDefineAccountPermissions.editSelfProjects,
IPreDefineAccountPermissions.createSelfProjects,
],
extraParams: ({ params }) => ({
resourceParams: {
path: IConfigCollectionName.Projects,
fragment: IConfigFragmentName.Settings,
query: {
name: "$params.projectId", // Use the project ID for specific project configuration
},
},
}),
configurations: ["organization.projectDefaults", "organization.projectSettings"], // Fetch specific configurations
},
];

This fetches only the projectDefaults and projectSettings configurations for the project.

Example 3: No Configurations Specified

If configurations is not specified in the route definition, no configuration data will be included in the loader. This is useful for pages where configurations are not required.

Route Definition (No Configurations):

export const project_route = [
{
name: "menu.projects",
path: PROJECTS_ROUTES.projectView,
key: "project-view",
priority: 7,
position: IMenuPosition.Middle,
icon: {
name: "AiOutlineProject",
style: { fontSize: "large" },
},
component: () => import("./components/index"),
authority: [
IPreDefineAccountPermissions.viewSelfProjects,
IPreDefineAccountPermissions.viewOthersProjects,
],
extraPermissions: [
IPreDefineAccountPermissions.manageSelfProjects,
IPreDefineAccountPermissions.editSelfProjects,
IPreDefineAccountPermissions.createSelfProjects,
],
extraParams: ({ params }) => ({
resourceParams: {
path: IConfigCollectionName.Projects,
fragment: IConfigFragmentName.Settings,
query: {
name: "$params.projectId",
},
},
}),
// No configurations specified, so the loader won't fetch any
},
];

In this case, no configurations will be fetched or included in the loader data.

Conclusion:

  • Generic Configurations (['*']): Fetch all available configurations if you need them.
  • Specific Configurations: Use specific configuration keys to optimize performance.
  • No Configurations: If no configurations are needed, simply omit the configurations field from the route definition.

In addition to using the above approach for configuring routes, try avoiding the use of useSettings or its wrapped loaders and hooks. Instead, use the route-based configuration outlined earlier to manage the retrieval of configurations and permissions. This method provides a more flexible and efficient way to handle dynamic data in the loader, ensuring that you have full control over the configurations fetched for each route or resource.

This route-based approach allows for a more streamlined and maintainable way of handling settings, reducing dependencies on custom hooks or loaders like useSettings, and centralizing your configuration management within your routes.

Back to Index | Previous: Component Structure | Next: Icon System