Skip to content

Commit b99c72f

Browse files
authored
Add user-specific settings page (#3642)
* Add user-specific settings page * Remove duplicated code when changing settings value
1 parent 939758a commit b99c72f

File tree

6 files changed

+156
-18
lines changed

6 files changed

+156
-18
lines changed

opengrok-web/src/main/java/org/opengrok/web/Scripts.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public String toHtml() {
114114
putFromWebJar("jquery-tablesorter", "jquery.tablesorter.min.js", 12);
115115
putjs("tablesorter-parsers", "js/tablesorter-parsers-0.0.3", 13, true);
116116
putjs("searchable-option-list", "js/searchable-option-list-2.0.14", 14);
117-
putjs("utils", "js/utils-0.0.40", 15, true);
117+
putjs("utils", "js/utils-0.0.41", 15, true);
118118
putjs("repos", "js/repos-0.0.3", 20, true);
119119
putjs("diff", "js/diff-0.0.5", 20, true);
120120
putjs("jquery-caret", "js/jquery.caret-1.5.2", 25);

opengrok-web/src/main/webapp/default/style-1.0.2.css renamed to opengrok-web/src/main/webapp/default/style-1.0.3.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,3 +1351,17 @@ td#typeLabelTd {
13511351
.ui-autocomplete-loading {
13521352
background:url('img/indicator.gif') no-repeat right center;
13531353
}
1354+
1355+
/** --------------- settings -------------------- */
1356+
1357+
.local-setting {
1358+
background-color: inherit;
1359+
}
1360+
1361+
.header-half-bottom-margin {
1362+
margin-bottom: 0.5rem;
1363+
}
1364+
1365+
.no-margin-left {
1366+
margin-left: 0;
1367+
}

opengrok-web/src/main/webapp/httpheader.jspf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ org.opengrok.web.Scripts"
4545
PageConfig cfg = PageConfig.get(request);
4646
String styleDir = cfg.getCssDir();
4747
String ctxPath = request.getContextPath();
48-
String dstyle = styleDir + '/' + "style-1.0.2.min.css";
48+
String dstyle = styleDir + '/' + "style-1.0.3.min.css";
4949
String pstyle = styleDir + '/' + "print-1.0.1.min.css";
5050
String mstyle = styleDir + '/' + "mandoc-1.0.0.min.css";
5151
%><!DOCTYPE html>

opengrok-web/src/main/webapp/js/utils-0.0.40.js renamed to opengrok-web/src/main/webapp/js/utils-0.0.41.js

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,8 +1700,7 @@ function pageReadyMast() {
17001700
}
17011701

17021702
function domReadyMenu(minisearch) {
1703-
if (getCookie('OpenGrokSuggester.enabled') === 'false') {
1704-
console.log('Suggester disabled by a cookie');
1703+
if (getSettingsValue('suggester-enabled') === 'false') {
17051704
return;
17061705
}
17071706

@@ -2378,22 +2377,81 @@ function escapeHtml(string) { // taken from https://stackoverflow.com/questions/
23782377
}
23792378

23802379
/**
2381-
* Taken from https://www.w3schools.com/js/js_cookies.asp .
2382-
* @param cname cookie name to retrieve
2383-
* @returns {string} cookie value
2380+
* Returns user-specific local settings for a provided key.
2381+
* @param key settings key
2382+
* @returns {string} settings value or {@code undefined} if not set
23842383
*/
2385-
function getCookie(cname) {
2386-
const name = cname + "=";
2387-
const decodedCookie = decodeURIComponent(document.cookie);
2388-
const ca = decodedCookie.split(';');
2389-
for (let i = 0; i < ca.length; i++) {
2390-
let c = ca[i];
2391-
while (c.charAt(0) == ' ') {
2392-
c = c.substring(1);
2384+
function getSettingsValue(key) {
2385+
return localStorage.getItem(key);
2386+
}
2387+
2388+
/**
2389+
* Event listener which stores user-specific settings change for an {@code input} element.
2390+
* @param el settings {@code input} element
2391+
*/
2392+
function onSettingsValueChange(el) {
2393+
let value = getSettingsInputValue(el);
2394+
localStorage.setItem(el.name, value);
2395+
}
2396+
2397+
/**
2398+
* Decodes a settings value from a settings {@code input} element.
2399+
* @param el settings {@code input} element
2400+
* @returns {string|*} settings value
2401+
*/
2402+
function getSettingsInputValue(el) {
2403+
if (el.type === 'checkbox') {
2404+
if (el.checked) {
2405+
return el.dataset.checkedValue;
2406+
} else {
2407+
return el.dataset.uncheckedValue;
23932408
}
2394-
if (c.indexOf(name) === 0) {
2395-
return c.substring(name.length, c.length);
2409+
} else {
2410+
return el.value;
2411+
}
2412+
}
2413+
2414+
/**
2415+
* Resets all settings elements with class {@code local-setting} to their default values.
2416+
*/
2417+
function resetAllSettings() {
2418+
for (const el of document.getElementsByClassName('local-setting')) {
2419+
setDefaultSettingsValue(el);
2420+
onSettingsValueChange(el);
2421+
}
2422+
}
2423+
2424+
/**
2425+
* Sets a default value for a settings {@code input} element.
2426+
* @param el settings {@code input} element
2427+
*/
2428+
function setDefaultSettingsValue(el) {
2429+
setSettingsInputValue(el, el.dataset.defaultValue);
2430+
}
2431+
2432+
/**
2433+
* Sets the settings {@code input} element value to the provided one.
2434+
* @param el element to change
2435+
* @param value value to set
2436+
*/
2437+
function setSettingsInputValue(el, value) {
2438+
if (el.type === 'checkbox') {
2439+
el.checked = el.dataset.checkedValue === value;
2440+
} else {
2441+
el.value = value;
2442+
}
2443+
}
2444+
2445+
/**
2446+
* Initializes all settings elements with {@code local-setting} class.
2447+
*/
2448+
function initSettings() {
2449+
for (const el of document.getElementsByClassName('local-setting')) {
2450+
const value = getSettingsValue(el.name);
2451+
if (value) {
2452+
setSettingsInputValue(el, value);
2453+
} else {
2454+
setDefaultSettingsValue(el);
23962455
}
23972456
}
2398-
return "";
23992457
}

opengrok-web/src/main/webapp/menu.jspf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ document.domReady.push(function() { domReadyMenu(); });
222222
type="button" value="Clear"/>
223223
<input tabindex="11" class="submit btn" onclick="window.open('help.jsp', '_blank');"
224224
type="button" value="Help"/>
225+
<input tabindex="12" class="submit btn" onclick="window.open('settings.jsp', '_self');"
226+
type="button" value="Settings"/>
225227
</div>
226228
</div>
227229
<div id="ltbl">
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<%--
2+
CDDL HEADER START
3+
4+
The contents of this file are subject to the terms of the
5+
Common Development and Distribution License (the "License").
6+
You may not use this file except in compliance with the License.
7+
8+
See LICENSE.txt included in this distribution for the specific
9+
language governing permissions and limitations under the License.
10+
11+
When distributing Covered Code, include this CDDL HEADER in each
12+
file and include the License file at LICENSE.txt.
13+
If applicable, add the following below this CDDL HEADER, with the
14+
fields enclosed by brackets "[]" replaced with your own identifying
15+
information: Portions Copyright [yyyy] [name of copyright owner]
16+
17+
CDDL HEADER END
18+
19+
Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
20+
--%>
21+
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
22+
<%@page session="false" errorPage="error.jsp" import="org.opengrok.web.PageConfig" %>
23+
<%@ page import="org.opengrok.indexer.configuration.RuntimeEnvironment" %>
24+
<%
25+
{
26+
PageConfig cfg = PageConfig.get(request);
27+
cfg.setTitle("OpenGrok Settings");
28+
}
29+
%>
30+
<%@ include file="httpheader.jspf" %>
31+
<body>
32+
<div id="page">
33+
<div id="whole_header">
34+
<div id="header">
35+
<%@include file="pageheader.jspf" %>
36+
</div>
37+
<div id="Masthead">
38+
<a href="<%= request.getContextPath() %>/"><span id="home"></span>Home</a>
39+
</div>
40+
</div>
41+
<div id="sbar"></div>
42+
<div style="padding-left: 1rem;">
43+
<h1>Settings</h1>
44+
<h3 class="header-half-bottom-margin">Suggester</h3>
45+
<%
46+
boolean suggesterEnabled = RuntimeEnvironment.getInstance().getSuggesterConfig().isEnabled();
47+
%>
48+
<label>Enabled
49+
<input class="local-setting" name="suggester-enabled" type="checkbox" data-checked-value="true"
50+
data-unchecked-value="false" data-default-value="<%= suggesterEnabled ? "true" : "false" %>"
51+
<%= suggesterEnabled ? "" : "disabled" %>
52+
onchange="onSettingsValueChange(this)">
53+
</label>
54+
<br>
55+
<br>
56+
<input class="submit btn no-margin-left" onclick="resetAllSettings()" type="button" value="Reset to defaults"/>
57+
</div>
58+
</div>
59+
<script type="text/javascript">
60+
/* <![CDATA[ */
61+
document.pageReady.push(() => initSettings());
62+
/* ]]> */
63+
</script>
64+
<%@include file="foot.jspf" %>

0 commit comments

Comments
 (0)