# 5.4 Settings & Configurations

Now that we have created our plugin that adds the Tasks functionality to our app, let's see if we can make it configurable.

There are "configurable", we mean 2 things:

1. A developer that is using this plugin, can configure it via the `configs` prop.
2. An end-user can configure the feature through the "Settings" UI.

We will attempt to do both these things in this chapter. For this example, we will make the number of items our Task List loads per page.

### Step 1.1: Consume a Variable from the Config

Let's go back to our TaskList component from [Chapter 4.2](https://bluebase.gitbook.io/core/tutorial/4.-crud-operations/4.2-reading-tasks).

Change **Line 32** from:

```
const itemsPerPage = 10;
```

To:

```
const [itemsPerPage] = useConfig('tasks.itemsPerPage');
```

Basically, rather than having a hardcoded number in the code, we extract it from config with key `'tasks.itemsPerPage'`. We utilize the `useConfig` hook for this purpose, that is imported from the `@bluebase/core` package.&#x20;

Note that the `useConfig` hook has the same API as the `useState` hook in the `react` library.

This should be your final code now:

{% code title="src/components/TaskList/TaskList.tsx" %}

```typescript
import { QueryResult } from '@apollo/client';
import { Divider } from '@bluebase/components';
import { getComponent, useConfig } from '@bluebase/core';
import { GraphqlConnection, GraphqlListProps } from '@bluebase/plugin-json-graphql-components';
import React from 'react';
import { ListRenderItemInfo } from 'react-native';

import { Tasks, TasksCollectionQueryQuery, TasksCollectionQueryQueryVariables } from '../../graphql-types';
import TaskListEmptyState from '../TaskListEmptyState';
import { TaskListItem, TaskListItemProps } from '../TaskListItem';
import { TasksCollectionQuery, TasksCollectionQueryUpdateQueryFn } from './TasksCollectionQuery.graphql';

const GraphqlList = getComponent<GraphqlListProps<TaskListItemProps, TasksCollectionQueryQuery>>('GraphqlList');

function mapQueryResultToConnection(result: QueryResult<TasksCollectionQueryQuery>) {
	return result.data?.tasksCollection as GraphqlConnection<Tasks>;
}

function renderItem({ item }: ListRenderItemInfo<TaskListItemProps>) {
	return <TaskListItem {...item} />;
}

const renderDivider = () => <Divider inset />;

export interface TaskListProps {
	completed: boolean;
}

export const TaskList = (props: TaskListProps) => {
	const { completed } = props;
	const [itemsPerPage] = useConfig('tasks.itemsPerPage');

	const variables: TasksCollectionQueryQueryVariables = {
		filter: {
			completed: { 'eq': completed }
		}
	};

	return (
		<GraphqlList
			key="task-list"
			pagination="infinite"
			itemsPerPage={itemsPerPage}
			query={TasksCollectionQuery}
			updateQueryInfinitePagination={TasksCollectionQueryUpdateQueryFn}
			mapQueryResultToConnection={mapQueryResultToConnection}
			renderItem={renderItem}
			ItemSeparatorComponent={renderDivider}
			ListEmptyComponent={TaskListEmptyState}
			queryOptions={{
				variables
			}}
		/>
	);
};

TaskList.displayName = 'TaskList';
```

{% endcode %}

### Step 1.2 Add Default Configs

Now that we are using the config, we also need to define its default value. Add the `defaultConfigs` object to your plugin as shown in the code below:

{% code title="src/index.ts" %}

```typescript
import { createPlugin } from '@bluebase/core';

export default createPlugin({
	key: 'tasks',
	name: 'Tasks',
	description: 'A todo app made with BlueBase framework.',

	defaultConfigs: {
		'tasks.itemsPerPage': 10,
	}
	
	// ... other properties
});
```

{% endcode %}

Now run your app and inspect. You will observe that BlueBase has successfully loaded the default config, which has been passed onto the `GraphqlList` component.

![](https://3369392052-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPjsIbS1DfhqT8BS3Ui%2Fuploads%2FEAqG2GBVFU7E6uXLYh5h%2FScreenshot%202022-04-25%20at%208.22.21%20PM.png?alt=media\&token=e47d9be3-ca1c-4f31-9a9d-c7ca45f5353d)

### Step 1.3: Override Config Value

Now comes the fun part. Let's override this value from our app's configs:

{% code title="configs.ts" %}

```typescript
export const configs = {

	'tasks.itemsPerPage': 5,

	// ... other configs
};
```

{% endcode %}

Run your app again. You will observe that the value in the `configs` was loaded and preferred over the `defaultConfigs`.

![](https://3369392052-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPjsIbS1DfhqT8BS3Ui%2Fuploads%2Fl3uIBD5BJhJMAmLZ6Qlc%2FScreenshot%202022-04-25%20at%208.24.05%20PM.png?alt=media\&token=72d5b144-50b6-444f-9784-71f488080e16)

Now, let's see how we can allow the end-user to customize the value too.

### Step 2.1: Create a Form

Let's create a form that will allow the user to input a value, and update the config when he presses the submit button.

For this purpose, we will use the `JsonForm` component from the `@bluebase/plugin-json-schema-components`.

{% hint style="info" %}
The props of `JsonForm` component are very similar to the `GraphqlJsonForm` that we have previously usesd.&#x20;

This is because the `GraphqlJsonForm` too uses `JsonForm` internally`.`
{% endhint %}

{% hint style="info" %}
`JsonForm` component is built using the [formik](https://formik.org/) library.
{% endhint %}

{% code title="src/components/TaskSettingsForm/TaskSettingsForm.tsx" %}

```typescript
import { getComponent, useConfig } from '@bluebase/core';
import { JsonFormProps } from '@bluebase/plugin-json-schema-components';
import { FormikHelpers } from 'formik';
import React from 'react';

interface TaskSettingsFormValues {
	itemsPerPage: number;
}

const JsonForm = getComponent<JsonFormProps<TaskSettingsFormValues>>('JsonForm');

export interface TaskSettingsFormProps {}

export const TaskSettingsForm = (props: TaskSettingsFormProps) => {
	const [itemsPerPage, setItemsPerPage] = useConfig('tasks.itemsPerPage');

	return (
		<JsonForm
			{...props}
			schema={{
				validateOnBlur: false,
				validateOnChange: false,

				fields: [
					{
						autoFocus: true,
						label: 'Items per page',
						name: 'itemsPerPage',
						required: true,
						type: 'number',
					},
					{
						schema: { component: 'Divider' },
						type: 'component',
					},
					{
						direction: 'right',
						name: 'form-actions',
						type: 'inline',

						fields: [
							{
								name: 'reset',
								type: 'reset',
							},
							{
								name: 'submit',
								title: 'Save',
								type: 'submit',
							},
						],
					},
				],

				initialValues: {
					itemsPerPage,
				},

				onSubmit: (values: TaskSettingsFormValues, helpers: FormikHelpers<TaskSettingsFormValues>) => {
					const { setSubmitting } = helpers;
					setItemsPerPage(values.itemsPerPage);

					// Wait one second and then setSubmitting to false
					setTimeout(() => setSubmitting(false), 1000);
				}
			}}
		/>
	);
};

TaskSettingsForm.displayName = 'TaskSettingsForm';
```

{% endcode %}

Add the index file to export the component.

{% code title="src/components/TaskSettingsForm/index.ts" %}

```typescript
export * from './TaskSettingsForm';

import { TaskSettingsForm } from './TaskSettingsForm';
export default TaskSettingsForm;
```

{% endcode %}

### Step 2.2 Add Screen in the Settings App

Now we want to create a screen for "Tasks" in the Settings app. Luckily the Settings app allows this to be done via `bluebase.plugin.setting-app.pages` filter.

This filter inputs an array of screens in the settings app, all we have to do is to append our own screen configs and return the array. Create a new file and copy the following code:

{% code title="src/filter.ts" %}

```typescript
import { SettingsPageProps } from '@bluebase/plugin-settings-app';

import TaskSettingsForm from './components/TaskSettingsForm';

export const filters = {
	'bluebase.plugin.setting-app.pages': [
		{
			key: 'bluebase-settings-todo-page',
			priority: 20,

			value: (pages: SettingsPageProps[]) => [
				{
					name: 'TaskSettings',
					path: 'task',

					options: {
						drawerIcon: { type: 'icon', name: 'checkbox-multiple-marked' },
						title: 'Tasks',
					},

					items: [
						{
							name: 'task-settings',
							component: TaskSettingsForm,
							title: 'Task Settings',
							description: 'Configure your tasks',
						},
					],
				},
				...pages,
			],
		},
	],
};
```

{% endcode %}

Note that in Line 22 till 27 we define the "Task Settings" panel and use the `TaskSettingsForm` component that we created in the previous step.

Let's add this filter to the plugin (See Line 13):

{% code title="src/index.ts" %}

```typescript
import { createPlugin } from '@bluebase/core';


import { filters } from './filters';
import { lang } from './lang';

export default createPlugin({
	key: 'tasks',
	name: 'Tasks',
	description: 'A todo app made with BlueBase framework.',

	filters: {
		...filters,
		...lang,
	},
	
	// ... Other properties
});
```

{% endcode %}

Run the app and go to the settings section. You will see the "Tasks" settings page is added.

![](https://3369392052-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPjsIbS1DfhqT8BS3Ui%2Fuploads%2FU7Rx4faM0ElPY90Hqhtr%2FScreenshot%202022-04-25%20at%208.56.01%20PM.png?alt=media\&token=220aef7a-061a-4f26-89ba-663b973f0baf)

When you use and submit the form, you will observe that it will update the config to achieve the desired result:

![](https://3369392052-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPjsIbS1DfhqT8BS3Ui%2Fuploads%2FS0oOIhl2nAxg9y1uIvez%2FScreenshot%202022-04-25%20at%208.53.11%20PM.png?alt=media\&token=7164482c-f7d8-49f6-b505-26bb870adc80)
