modify_properties.html
1 <@tform action='jsp/admin/DoModifyProperties.jsp' class='mt-2'>
2 <@pageContainer>
3 <@pageColumn>
4 <@pageHeader title='#i18n{portal.system.modify_properties.boxTitle}'>
5 <@tform>
6 <@formGroup labelFor='plugin_type' labelKey='#i18n{portal.system.manage_plugins.buttonFilter}' hideLabel=['all'] formStyle='inline'>
7 <@inputGroup>
8 <@input name='search_prop' id='search_prop' placeHolder='#i18n{portal.system.manage_plugins.buttonFilter}' params='autocomplete="off" addons' />
9 <@button color='primary' title='#i18n{portal.system.manage_plugins.buttonFilter}' buttonIcon='filter' hideTitle=['all'] />
10 </@inputGroup>
11 </@formGroup>
12 </@tform>
13 </@pageHeader>
14 <@tabs>
15 <@tabList>
16 <#list groups_list as group>
17 <#assign index = group?index>
18 <#if index == 0 ><#assign tabactive = true><#else><#assign tabactive = false></#if>
19 <@tabLink active=tabactive href='#group-${index}' title=group.description tabLabel=group.name />
20 </#list>
21 </@tabList>
22 <@tabContent class='pt-0'>
23 <#list groups_list as group>
24 <#assign index = group?index>
25 <#if index == 0 ><#assign tabactive = true><#else><#assign tabactive = false></#if>
26 <@tabPanel active=tabactive id='group-${index}'>
27 <@input type='hidden' name='token' value='${token}' />
28 <@row class='row-cols-1 row-cols-sm-2 row-cols-md-3 g-3'>
29 <#assign groups = group.localizedDataList?map( prop -> prop.group )>
30 <#assign groupList = []>
31 <#list groups?sort as groupGroup><#if !groupList?seq_contains(groupGroup)><#assign groupList = groupList + [groupGroup]></#if></#list>
32 <#list groupList?sort as groupCol>
33 <@columns class='pt-3' params='data-prop="${groupCol}"'>
34 <#assign groupName=''>
35 <#assign helpText=''>
36 <#list group.localizedDataList?filter( groupItem -> groupItem.group = groupCol ) as groupItem>
37 <#if groupName=''>
38 <#assign prefix=groupItem.key?keep_before(".site_property") >
39 <#assign groupName>#i18n{${prefix}.site_property.${groupCol}.group.title}</#assign>
40 <h3>${groupName!}</h3>
41 </#if>
42 <#assign labelText=groupItem.label>
43 <#if groupItem.key?ends_with( ".checkbox" )><#assign labelText=''></#if>
44 <#if groupItem.help?length gt 0><#assign helpText = groupItem.help></#if>
45 <@box id='box_${groupItem.key}'>
46 <@boxBody class='searchable'>
47 <@formGroup class='property' labelKey=labelText labelFor=groupItem.key helpKey=helpText params=' data-property="${groupItem.key}"' rows=2>
48 <#if groupItem.key?ends_with( ".textblock" )>
49 <@input type='textarea' name=groupItem.key id=groupItem.key>${groupItem.value?html}</@input>
50 <#elseif groupItem.key?ends_with( ".htmlblock" )>
51 <@input type='textarea' name=groupItem.key id=groupItem.key class='richtext'>${groupItem.value?html}</@input>
52 <#elseif groupItem.key?ends_with( ".checkbox" )>
53 <#if groupItem.value == "1">
54 <@checkBox orientation='switch' name=groupItem.key id=groupItem.key labelKey=groupItem.label value='1' checked=true />
55 <#else>
56 <@checkBox orientation='switch' name=groupItem.key id=groupItem.key labelKey=groupItem.label value='1' checked=false />
57 </#if>
58 <@input type='hidden' name='${groupItem.key}' value='0' />
59 <#elseif groupItem.key?contains( "color" )>
60 <@inputGroup class='color-wrapper-input'>
61 <@input type='text' class='color-input' name=groupItem.key id=groupItem.key value=groupItem.value?html />
62 <@inputGroupItem>
63 <input type="color" class="color-input" name="color-input" value="${groupItem.value?html}" colorspace="display-p3" alpha>
64 </@inputGroupItem>
65 </@inputGroup>
66 <#else>
67 <@input type='text' name=groupItem.key id=groupItem.key value=groupItem.value?html />
68 </#if>
69 </@formGroup>
70 </@boxBody>
71 </@box>
72 </#list>
73 </@columns>
74 </#list>
75 </@row>
76 </@tabPanel>
77 </#list>
78 </@tabContent>
79 </@tabs>
80 </@pageColumn>
81 <@row class='position-fixed bottom-0 end-0 w-100 h-10'>
82 <@columns class='d-flex justify-content-center align-items-center col-12' params='style="background-color:rgba(255,255,255,.8)"'>
83 <@button class='mt-3' type='submit' buttonIcon='device-floppy' title='#i18n{portal.system.modify_properties.buttonLabel}' />
84 </@columns>
85 </@row>
86 </@pageContainer>
87 </@tform>
88 <@overlay />
89 <#include "/admin/util/editor/editor.html" />
90 <@initEditor />
91 <script type="module">
92 import LuteceSearchList from './themes/shared/modules/luteceSearchList.js';
93 const searchInput = document.querySelector("#search_prop");
94 const searchElementList = document.querySelectorAll("*[data-prop]");
95 new LuteceSearchList( searchInput, searchElementList, {
96 searchableChild: [".searchable",".title"],
97 });
98
99 window.addEventListener( "load", function(){
100 <#-- Theme specific code -->
101 <#if commonsThemeCode = 'tabler'>
102 document.querySelector('[data-prop="bo"]').classList.add('d-none');
103 </#if>
104 <#-- End theme specific code -->
105 const colorInputs = document.querySelectorAll(".color-wrapper-input");
106 colorInputs.forEach( input => {
107 const colorInput = input.querySelector("input[type='color']");
108 const colorValue = input.querySelector("input[type='text']");
109 colorInput.addEventListener("change", function(){
110 colorValue.value = colorInput.value;
111 });
112 colorValue.addEventListener("change", function(){
113 colorInput.value = colorValue.value;
114 });
115 });
116
117 // Tab management with sessionStorage
118 const tabLinks = document.querySelectorAll('[data-bs-toggle="tab"]');
119 const tabPanels = document.querySelectorAll('[role="tabpanel"]');
120 const storageKey = "lutece-admin-prop-tab";
121
122 // Restore last active tab on page load
123 const savedTabId = sessionStorage.getItem(storageKey);
124 if (savedTabId) {
125 // Deactivate all tabs and panels
126 tabLinks.forEach(link => {
127 link.classList.remove('active');
128 link.setAttribute('aria-selected', 'false');
129 });
130 tabPanels.forEach(panel => {
131 panel.classList.remove('active', 'show');
132 });
133
134 // Activate the saved tab
135 const savedTabLink = <#noparse>document.querySelector(`[href="${savedTabId}"]`);</#noparse>
136 const savedTabPanel = document.querySelector(savedTabId);
137
138 if (savedTabLink && savedTabPanel) {
139 savedTabLink.classList.add('active');
140 savedTabLink.setAttribute('aria-selected', 'true');
141 savedTabPanel.classList.add('active', 'show');
142 }
143 }
144
145 // Save tab selection on click
146 tabLinks.forEach(link => {
147 link.addEventListener('click', function(e) {
148 const targetId = this.getAttribute('href');
149 sessionStorage.setItem(storageKey, targetId);
150 });
151 });
152 });
153
154 // Checkbox dependent inputs
155 document.addEventListener( "DOMContentLoaded", function(){
156 // Custom styles option
157 const showStyles = document.getElementById('theme.site_property.layout.customstyles.checkbox');
158 if( showStyles ){
159 if( !showStyles.checked ){
160 document.getElementById('box_theme.site_property.layout.colors.light.textblock').classList.add('d-none');
161 document.getElementById('box_theme.site_property.layout.colors.dark.textblock').classList.add('d-none');
162 }
163 showStyles.addEventListener('change', function(){
164 if( this.checked ){
165 document.getElementById('box_theme.site_property.layout.colors.dark.textblock').classList.remove('d-none');
166 document.getElementById('box_theme.site_property.layout.colors.light.textblock').classList.remove('d-none');
167 } else {
168 document.getElementById('box_theme.site_property.layout.colors.dark.textblock').classList.add('d-none');
169 document.getElementById('box_theme.site_property.layout.colors.light.textblock').classList.add('d-none');
170 }
171 });
172 }
173
174 // Bo vertical menu transparent option
175 const verticalMenu = document.getElementById('portal.site.site_property.layout.menu.vertical.checkbox');
176 if( verticalMenu ){
177 if( !verticalMenu.checked ){
178 document.getElementById('box_portal.site.site_property.layout.menu.transparent.checkbox').classList.add('d-none');
179 }
180 verticalMenu.addEventListener('change', function(){
181 if( this.checked ){
182 document.getElementById('box_portal.site.site_property.layout.menu.transparent.checkbox').classList.remove('d-none');
183 } else {
184 document.getElementById('box_portal.site.site_property.layout.menu.transparent.checkbox').classList.add('d-none');
185 }
186 });
187 }
188
189 // Login cover options
190 const loginCover = document.getElementById('portal.site.site_property.layout.login.cover.checkbox');
191 if( loginCover ){
192 if( !loginCover.checked ){
193 document.getElementById('box_portal.site.site_property.layout.login.cover.contain.checkbox').classList.add('d-none');
194 }
195 loginCover.addEventListener('change', function(){
196 if( this.checked ){
197 document.getElementById('box_portal.site.site_property.layout.login.cover.contain.checkbox').classList.remove('d-none');
198
199 } else {
200 document.getElementById('box_portal.site.site_property.layout.login.cover.contain.checkbox').classList.add('d-none');
201
202 }
203 });
204 }
205
206 // Theme dark light options
207 const darkmode = document.getElementById('portal.site.site_property.layout.darkmode.checkbox');
208 darkmode.addEventListener('change', function(){
209 if( this.checked ){
210 localStorage.setItem('lutece-tabler-theme', 'dark');
211
212 } else {
213 localStorage.setItem('lutece-tabler-theme', 'light');
214 }
215 });
216 });
217 </script>