Add configurable homepage tabs with validation for default tab inclusion

This commit is contained in:
2026-03-20 11:59:05 +00:00
parent 59d8bf75b2
commit fff9a5b95f
7 changed files with 39 additions and 10 deletions

View File

@@ -34,6 +34,9 @@ chill_main:
x: '%env(float:ADD_ADDRESS_MAP_CENTER_X)%'
y: '%env(float:ADD_ADDRESS_MAP_CENTER_Y)%'
z: '%env(float:ADD_ADDRESS_MAP_CENTER_Z)%'
homepage:
default_tab: 'MyCustoms'
display_tabs: ['MyCustoms', 'MyNotifications', 'MyAccompanyingCourses', 'MyEvaluations', 'MyTasks', 'MyWorkflows', 'MyTickets']
when@test:
chill_main:

View File

@@ -84,6 +84,7 @@ use Chill\MainBundle\Security\Authorization\ChillExportVoter;
use Chill\MainBundle\Security\Authorization\EntityWorkflowVoter;
use Misd\PhoneNumberBundle\Doctrine\DBAL\Types\PhoneNumberType;
use Ramsey\Uuid\Doctrine\UuidType;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
@@ -210,6 +211,15 @@ class ChillMainExtension extends Extension implements
$config['top_banner'] ?? []
);
if (!in_array($config['homepage']['default_tab'], $config['homepage']['display_tabs'], true)) {
throw new InvalidConfigurationException('The chill_main.homepage.default_tab must be included in chill_main.homepage.display_tabs');
}
$container->setParameter(
'chill_main.homepage',
$config['homepage']
);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader->load('services.yaml');
$loader->load('services/doctrine.yaml');
@@ -241,7 +251,7 @@ class ChillMainExtension extends Extension implements
// $this->configureSms($config['short_messages'], $container, $loader);
}
public function prepend(ContainerBuilder $container)
public function prepend(ContainerBuilder $container): void
{
$this->prependNotifierTexterWithLegacyData($container);
@@ -256,6 +266,7 @@ class ChillMainExtension extends Extension implements
'available_languages' => $config['available_languages'],
'add_address' => $config['add_address'],
'chill_main_config' => $config,
'homepage_widget_config' => $config['homepage'],
],
'form_themes' => ['@ChillMain/Form/fields.html.twig'],
];

View File

@@ -325,6 +325,17 @@ class Configuration implements ConfigurationInterface
->end()
->end();
/* @phpstan-ignore-next-line */
$rootNode->children()
->arrayNode('homepage')->addDefaultsIfNotSet()
->children()
->scalarNode('default_tab')->defaultValue('MyCustoms')->end()
->arrayNode('display_tabs')
->info('List of tabs to display on the homepage.')
->defaultValue(['MyCustoms', 'MyNotifications', 'MyAccompanyingCourses', 'MyEvaluations', 'MyTasks', 'MyWorkflows'])
->scalarPrototype()->end()
->end();
return $treeBuilder;
}
}

View File

@@ -486,9 +486,15 @@ export enum HomepageTabs {
MyWorkflows,
}
/**
* The configuration for homepage config.
*
* This config comes from configuration (see ChillMainBundle/DependencyInjection/Configuration or chill_main.homepage configuration
* in packages/config files). It goes through a twig globals, and is displayed in the homepage.
*/
export interface HomepageConfig {
defaultTab: HomepageTabs;
displayTabs: HomepageTabs[];
default_tab: HomepageTabs;
display_tabs: HomepageTabs[];
}
export interface TabDefinition {

View File

@@ -123,7 +123,7 @@ const tabDefinitions: TabDefinition[] = [
const displayedTabs = computed(() => {
const tabs = [] as TabDefinition[];
for (const tabEnum of homepageConfig.value.displayTabs) {
for (const tabEnum of homepageConfig.value.display_tabs) {
const def = tabDefinitions.find(
(t) => t.key === Number(HomepageTabs[tabEnum]),
);
@@ -132,7 +132,7 @@ const displayedTabs = computed(() => {
return tabs.filter(Boolean);
});
const activeTab = ref(Number(HomepageTabs[homepageConfig.value.defaultTab]));
const activeTab = ref(Number(HomepageTabs[homepageConfig.value.default_tab]));
const loading = computed(() => store.state.loading);
@@ -152,5 +152,6 @@ onMounted(() => {
<style scoped>
a.nav-link {
cursor: pointer;
padding: 8px;
}
</style>

View File

@@ -12,10 +12,7 @@
{% block js %}
<script type="text/javascript">
window.homepage_config = JSON.stringify({
defaultTab: 'MyTickets',
displayTabs: ['MyCustoms', 'MyTickets', 'MyNotifications']
});
window.homepage_config = '{{ homepage_widget_config|json_encode|raw }}';
</script>
{{ encore_entry_script_tags('page_homepage_widget') }}

View File

@@ -190,7 +190,7 @@ my_tasks.description_alert: "Liste des tâches auxquelles je suis assigné et do
my_tasks.description_warning: "Liste des tâches auxquelles je suis assigné et dont la date d'échéance est dépassée."
my_accompanying_courses.tab: "Mes nouveaux parcours"
my_accompanying_courses.description: "Liste des parcours d'accompagnement que l'on vient de m'attribuer depuis moins de 15 jours."
my_notifications.tab: "Mes nouvelles notifications"
my_notifications.tab: "Mes notifications"
my_notifications.description: "Liste des notifications reçues et non lues."
my_workflows.tab: "Mes workflows"
my_workflows.description: "Liste des workflows en attente d'une action."