improved search, integrated legacy modules into navigation
This commit is contained in:
@@ -1,17 +1,39 @@
|
|||||||
<script>
|
<script>
|
||||||
import { logout, user } from '../user.svelte.js';
|
import { logout, user } from '../user.svelte.js';
|
||||||
import { onMount } from 'sevelte';
|
import { onMount } from 'svelte';
|
||||||
import { useTinyRouter } from 'svelte-tiny-router';
|
import { useTinyRouter } from 'svelte-tiny-router';
|
||||||
import { t } from '../translations.svelte.js';
|
import { t } from '../translations.svelte.js';
|
||||||
|
|
||||||
const router = useTinyRouter();
|
const router = useTinyRouter();
|
||||||
|
|
||||||
|
const modules = $state([]);
|
||||||
|
|
||||||
|
async function fetchModules(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/legacy/modules`;
|
||||||
|
const resp = await fetch(url,{credentials:'include'});
|
||||||
|
if (resp.ok){
|
||||||
|
const arr = await resp.json();
|
||||||
|
for (let entry of arr) modules.push({name:t('module.'+entry.module),url:entry.url});
|
||||||
|
console.log(modules);
|
||||||
|
} else {
|
||||||
|
console.log('error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMount(fetchModules);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
nav a{
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<a onclick={() => router.navigate('/user')}>{t('menu.users')}</a>
|
<a onclick={() => router.navigate('/user')}>{t('menu.users')}</a>
|
||||||
<a href="https://svelte.dev/tutorial/svelte/state" target="_blank">{t('menu.tutorial')}</a>
|
<a href="https://svelte.dev/tutorial/svelte/state" target="_blank">{t('menu.tutorial')}</a>
|
||||||
|
{#each modules as module,i}
|
||||||
|
<a href={module.url}>{module.name}</a>
|
||||||
|
{/each}
|
||||||
{#if user.name }
|
{#if user.name }
|
||||||
<a onclick={logout}>{t('menu.logout')}</a>
|
<a onclick={logout}>{t('menu.logout')}</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import static de.srsoftware.umbrella.core.Constants.*;
|
|||||||
import static de.srsoftware.umbrella.core.Constants.TOKEN;
|
import static de.srsoftware.umbrella.core.Constants.TOKEN;
|
||||||
import static de.srsoftware.umbrella.core.Paths.*;
|
import static de.srsoftware.umbrella.core.Paths.*;
|
||||||
import static de.srsoftware.umbrella.core.Util.request;
|
import static de.srsoftware.umbrella.core.Util.request;
|
||||||
import static de.srsoftware.umbrella.user.Paths.NOTIFY;
|
import static de.srsoftware.umbrella.user.Paths.*;
|
||||||
import static de.srsoftware.umbrella.user.Paths.VALIDATE_TOKEN;
|
|
||||||
import static java.lang.Long.parseLong;
|
import static java.lang.Long.parseLong;
|
||||||
import static java.lang.System.Logger.Level.*;
|
import static java.lang.System.Logger.Level.*;
|
||||||
import static java.lang.System.Logger.Level.DEBUG;
|
import static java.lang.System.Logger.Level.DEBUG;
|
||||||
@@ -27,10 +26,7 @@ import de.srsoftware.umbrella.user.model.UmbrellaUser;
|
|||||||
import de.srsoftware.umbrella.user.sqlite.SqliteDB;
|
import de.srsoftware.umbrella.user.sqlite.SqliteDB;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@@ -57,6 +53,7 @@ public class LegacyApi extends BaseHandler {
|
|||||||
}
|
}
|
||||||
case LOGIN -> getLogin(ex);
|
case LOGIN -> getLogin(ex);
|
||||||
case LOGOUT-> logout(ex);
|
case LOGOUT-> logout(ex);
|
||||||
|
case MODULES -> getModules(ex);
|
||||||
case SEARCH -> sendRedirect(ex,url(ex).replaceAll("/legacy/","/"));
|
case SEARCH -> sendRedirect(ex,url(ex).replaceAll("/legacy/","/"));
|
||||||
default -> super.doGet(path,ex);
|
default -> super.doGet(path,ex);
|
||||||
};
|
};
|
||||||
@@ -93,6 +90,17 @@ public class LegacyApi extends BaseHandler {
|
|||||||
return sendRedirect(ex,location);
|
return sendRedirect(ex,location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean getModules(HttpExchange ex) throws IOException {
|
||||||
|
var optToken = SessionToken.from(ex).map(Token::of);
|
||||||
|
if (optToken.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
|
||||||
|
var list = new ArrayList<Map<String,String>>();
|
||||||
|
for (var module : config.keys()){
|
||||||
|
Optional<String> url = config.get(module+".baseUrl");
|
||||||
|
url.ifPresent(u -> list.add(Map.of("module",module,URL,u)));
|
||||||
|
}
|
||||||
|
return sendContent(addCors(ex),list);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean jsonUser(HttpExchange ex) throws UmbrellaException, IOException {
|
private boolean jsonUser(HttpExchange ex) throws UmbrellaException, IOException {
|
||||||
Map<String, Object> data = null;
|
Map<String, Object> data = null;
|
||||||
try {
|
try {
|
||||||
@@ -214,42 +222,6 @@ public class LegacyApi extends BaseHandler {
|
|||||||
return sendContent(ex,Map.of(REDIRECT,"home"));
|
return sendContent(ex,Map.of(REDIRECT,"home"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Session requestSession(Token token) throws UmbrellaException {
|
|
||||||
var session = users.load(token);
|
|
||||||
session = users.extend(session);
|
|
||||||
return session;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean getSearch(HttpExchange ex) throws IOException, UmbrellaException {
|
|
||||||
var optToken = SessionToken.from(ex).map(Token::of);
|
|
||||||
if (optToken.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
|
|
||||||
var token = optToken.get();
|
|
||||||
var params = queryParam(ex);
|
|
||||||
var key = params.get(KEY) instanceof String s ? s : null;
|
|
||||||
if (key == null) throw new UmbrellaException(HTTP_BAD_REQUEST,"Missing search key");
|
|
||||||
var fulltext = key.contains("+") || "on".equals(params.get("fulltext"));
|
|
||||||
StringBuilder searchResult = new StringBuilder();
|
|
||||||
if (fulltext){
|
|
||||||
for (var module : config.keys()){
|
|
||||||
var baseUrl = config.get(module + ".baseUrl");
|
|
||||||
if (baseUrl.isEmpty()) continue;
|
|
||||||
|
|
||||||
var res = request(baseUrl.get()+"/search",token.asMap().plus(KEY,key),MIME_FORM_URL,token.asBearer());
|
|
||||||
if (!(res instanceof String content) || content.isBlank()) continue;
|
|
||||||
searchResult.append("<fieldset><label>").append(module).append("</label>");
|
|
||||||
searchResult.append(content).append("</fieldset>\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var bookmark = config.get("bookmark.baseUrl");
|
|
||||||
if (bookmark.isEmpty()) throw new UmbrellaException(500,"Tag search not available: Bookmark module not configured!");
|
|
||||||
var res = request(bookmark.get()+"/search",token.asMap().plus(KEY,key),MIME_FORM_URL,null);
|
|
||||||
if (!(res instanceof String content)) throw new UmbrellaException(500,"Search did not return html content!");
|
|
||||||
searchResult.append(content);
|
|
||||||
}
|
|
||||||
addCors(ex);
|
|
||||||
return sendContent(ex,searchResult.toString());
|
|
||||||
};
|
|
||||||
|
|
||||||
private boolean postSearch(HttpExchange ex) throws IOException, UmbrellaException {
|
private boolean postSearch(HttpExchange ex) throws IOException, UmbrellaException {
|
||||||
var optToken = SessionToken.from(ex).map(Token::of);
|
var optToken = SessionToken.from(ex).map(Token::of);
|
||||||
if (optToken.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
|
if (optToken.isEmpty()) return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
|
||||||
@@ -279,6 +251,12 @@ public class LegacyApi extends BaseHandler {
|
|||||||
return sendContent(ex,searchResult.toString());
|
return sendContent(ex,searchResult.toString());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected Session requestSession(Token token) throws UmbrellaException {
|
||||||
|
var session = users.load(token);
|
||||||
|
session = users.extend(session);
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
private static String stripTrailingSlash(Object o){
|
private static String stripTrailingSlash(Object o){
|
||||||
String url = o.toString();
|
String url = o.toString();
|
||||||
if (url.endsWith("/")) return url.substring(0,url.length()-1);
|
if (url.endsWith("/")) return url.substring(0,url.length()-1);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class Paths {
|
|||||||
public static final String INSTALL = "install";
|
public static final String INSTALL = "install";
|
||||||
public static final String JAVASCRIPT = "js";
|
public static final String JAVASCRIPT = "js";
|
||||||
public static final String MENU = "menu";
|
public static final String MENU = "menu";
|
||||||
|
public static final String MODULES = "modules";
|
||||||
public static final String NOTIFY = "notify";
|
public static final String NOTIFY = "notify";
|
||||||
public static final String BUTTONS = "buttons";
|
public static final String BUTTONS = "buttons";
|
||||||
public static final String OIDC_LOGIN = "oidc_login";
|
public static final String OIDC_LOGIN = "oidc_login";
|
||||||
|
|||||||
Reference in New Issue
Block a user