Managing Module Settings
The module you are building can add and manage settings, the settings can be user modifiable with settings page in the dashboard or internal for the module itself.
Make sure to always prefix your settings keys with your module name for example: invoices_billing_enabled
to prevent conflicts with other modules that may possibly use the same settings key.
Using Settings Internally
Concord CRM ships with settings
function that can be used to retrieve, store and update settings related to your module, when your module does not provide settings that can be adjusted by an admin you can use this function directly in your code to store specific settings that can be retrieved and user anywhere in the module codebase.
if(settings('invoices_billing_enabled')) {
//
}
Updating and Adding Settings
To update settings, you can use the settings
function which as shown below:
settings()->set('invoices_billing_enabled', false)->save();
To save multiple settings you can provide an array
to the set
method.
settings()->set([
'invoices_billing_enabled'=>false,
'invoices_other_feature_enabled'=>true
])->save();
Checking If Setting Exist
To check if setting key exist, you can use the has
method, for example when the module is activated and you want to ensure that the a specific setting has default value, see example below that registers a listener in the module service provider:
public function boot() : void
{
$this->app['events']->listen('modules.invoices.enabled', function() {
if(!settings()->has('invoices_billing_enabled')) {
settings()->set('invoices_billing_enabled', false)->save();
}
});
}
Add Settings Page
Only admins can access the settings page in Concord CRM
If the module you are creating needs to have user configureable settings page that will be displayed in the dashboard, you will need to register a settings menu item and front-end route view that will display the settings form.
Register Settings Menu Item
Concord CRM will automatically register the settings menu items provided in the module service provider, to achieve this, in the module service provider create a method settingsMenu
and provide the items that needs to be registered.
To register multiple items, the settingsMenu
method should return an array of items.
use Modules\Core\Facades\Innoclapps;
use Modules\Core\Facades\SettingsMenu;
use Modules\Core\Settings\SettingsMenuItem;
protected function settingsMenu() : SettingsMenuItem
{
return SettingsMenuItem::make('invoices', __('invoices::settings.title'))
->path('/invoices')
->icon('CurrencyDollar')
->order(41);
}
The first argument of the SettingsMenuItem
class's make
method is the item unique identifier (ID) and the second argument is the label/title of the item.
To add collapsable menu item, you should provide third argument as an array that will include the children items.
SettingsMenuItem::make('invoices', __('invoices::settings.title'), [
SettingsMenuItem::make('billing', 'Invoices')->path('/invoices/billing'),
SettingsMenuItem::make('payments', 'Payments')->path('/invoices/payments'),
])->icon('CurrencyDollar')->order(41)
Register Frontend Settings Route
Next, we will need to register a route for the front-end that will display the settings form that the user can use to perform update.
// modules/Invoices/resources/js/app.js
import { translate } from "core/i18n";
import SettingsInvoices from "./views/SettingsInvoices.vue";
if (window.Innoclapps) {
Innoclapps.booting(function (app, router) {
router.addRoute("settings", {
path: "invoices", // "/settings/invoices"
component: SettingsInvoices,
meta: {
title: translate("invoices::settings.title"),
},
});
});
}
Here is a quick example from the SettingsInvoices.vue
Vue component.
<template>
<ICardHeader>
<ICardHeading :text="$t('invoices::settings.title')" />
</ICardHeader>
<ICard :overlay="!componentReady">
<ICardBody>
<IFormSwitchField>
<IFormSwitchLabel :text="$t('invoices::settings.auto_send')" />
<IFormSwitchDescription
:text="$t('invoices::settings.auto_send_info')"
/>
<IFormSwitch
v-model="form.invoices_auto_send"
@change="submit"
/>
</IFormSwitchField>
</ICardBody>
</ICard>
</template>
<script setup>
import { useSettings } from "@/Core/composables/useSettings";
const { form, submit, isReady: componentReady } = useSettings();
</script>
Make sure that you are running a dev server with the npm run dev
command and then navigate to settings and click on the menu item you have added before.
The submit
function within the useSettings
composable will update the form settings, you are not required to write a controller and route for the settings.
Include Submit Button
In many cases the settings may include dropdown, input fields that the user needs to fill then click on a button to save the settings, you can add a form that on submittion will call submit
function.
<template>
<form @submit.prevent="submit">
<ICard :overlay="!componentReady">
<ICardBody>
<div>
<IFormLabel class="mb-1">Label</IFormLabel>
<IFormInput v-model="form.module_setting_key" />
</div>
</ICardBody>
<ICardFooter class="text-right">
<IButton
type="submit"
variant="primary"
:disabled="form.busy"
:text="$t('core::app.save')"
/>
</ICardFooter>
</ICard>
</form>
</template>
<script setup>
import { useSettings } from "@/Core/composables/useSettings";
const { form, submit, isReady: componentReady } = useSettings();
</script>