Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b7f82018f9 | |||
| a245f849e5 | |||
| 4c3312daca | |||
| a6983780f5 | |||
| 6e146c1577 | |||
| 49cbd328e6 | |||
| 1db28b5bc0 | |||
| 285343218b | |||
| f402122d0c | |||
| 4339e4fd98 | |||
| 16cbcdff60 | |||
| 8dc77f52e4 | |||
| b04b9b92a6 | |||
| 8d66ed4cbe | |||
| b0ee825e0a | |||
| a321c813de | |||
| fda40d72f8 | |||
| 2375746d91 | |||
| cf0cf2f5e9 | |||
| 3e71ecc6cb | |||
| 1302165ab2 | |||
| d08138c9e1 | |||
| 4cd1ea3277 | |||
| 1059164b4a | |||
| f438bea4cc | |||
| 9394ca597c | |||
| 53fe79fbbd | |||
| d62534b3eb | |||
| 18e8e3ffd1 | |||
| ae55a76ca7 | |||
| cf485055a6 | |||
| 968e5bfb95 | |||
| 6de5f1f660 |
+15
-10
@@ -1,15 +1,15 @@
|
||||
FROM alpine:3.22 AS svelte_build
|
||||
RUN apk add npm
|
||||
RUN adduser -Dh /home/svelte svelte
|
||||
ADD . /home/svelte/Umbrella
|
||||
ADD frontend /home/svelte/Umbrella/frontend
|
||||
RUN chown -R svelte /home/svelte/Umbrella
|
||||
USER svelte
|
||||
WORKDIR /home/svelte/Umbrella/frontend
|
||||
RUN npm install && npm run build
|
||||
|
||||
|
||||
FROM alpine AS java_build
|
||||
RUN apk add gradle fontconfig font-opensans openjdk21-jre
|
||||
FROM alpine:3.22 AS java_build
|
||||
RUN apk add gradle
|
||||
ADD . /Umbrella
|
||||
WORKDIR /Umbrella
|
||||
COPY --from=svelte_build /home/svelte/Umbrella/frontend/dist web/src/main/resources/web
|
||||
@@ -17,13 +17,18 @@ RUN gradle --no-daemon build
|
||||
|
||||
|
||||
FROM alpine
|
||||
RUN apk add bash fontconfig font-opensans graphviz openjdk21-jre weasyprint
|
||||
RUN adduser -D umbrella
|
||||
COPY --from=java_build /Umbrella/backend/build/libs/backend.jar /home/umbrella/jar/
|
||||
RUN chown -R umbrella /home/umbrella
|
||||
ADD https://github.com/plantuml/plantuml/releases/download/v1.2025.10/plantuml-1.2025.10.jar /home/umbrella/plantuml.jar
|
||||
USER umbrella
|
||||
RUN apk --no-cache add bash fontconfig font-opensans graphviz openjdk21-jre tzdata weasyprint \
|
||||
&& adduser -D umbrella
|
||||
WORKDIR /home/umbrella
|
||||
RUN mkdir .config && ln -s /host/config.json .config/Umbrella.json
|
||||
|
||||
EXPOSE 80
|
||||
CMD java -jar jar/backend.jar
|
||||
|
||||
ADD https://github.com/plantuml/plantuml/releases/download/v1.2025.10/plantuml-1.2025.10.jar /home/umbrella/plantuml.jar
|
||||
COPY --from=java_build /Umbrella/backend/build/libs/backend.jar /home/umbrella/jar/
|
||||
RUN mkdir .config \
|
||||
&& ln -s /host/config.json .config/Umbrella.json \
|
||||
&& chmod a+rx plantuml.jar \
|
||||
&& chown -R umbrella . \
|
||||
&& ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
|
||||
USER umbrella
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
FROM alpine:3.22
|
||||
LABEL Maintainer "Stephan Richter <s.richter@srsoftware.de>"
|
||||
LABEL Maintainer "Stephan Richter"
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
RUN apk add bash npm
|
||||
|
||||
@@ -35,11 +35,12 @@ import org.json.JSONObject;
|
||||
|
||||
public class Util {
|
||||
public static final System.Logger LOG = System.getLogger("Util");
|
||||
private static final Pattern UML_PATTERN = Pattern.compile("@start(\\w+)(.*)@end(\\1)",Pattern.DOTALL);
|
||||
private static final Pattern UML_PATTERN = Pattern.compile("@start(\\w+)(.*?)@end(\\1)",Pattern.DOTALL);
|
||||
private static File plantumlJar = null;
|
||||
private static final JParsedown MARKDOWN = new JParsedown();
|
||||
public static final String SHA1 = "SHA-1";
|
||||
private static final MessageDigest SHA1_DIGEST;
|
||||
private static final Map<Integer,String> umlCache = new HashMap<>();
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -79,11 +80,22 @@ public class Util {
|
||||
try {
|
||||
if (plantumlJar != null && plantumlJar.exists()) {
|
||||
var matcher = UML_PATTERN.matcher(source);
|
||||
if (matcher.find()) {
|
||||
while (matcher.find()) {
|
||||
var uml = matcher.group(0).trim();
|
||||
var start = matcher.start(0);
|
||||
var end = matcher.end(0);
|
||||
|
||||
var umlHash = uml.hashCode();
|
||||
LOG.log(DEBUG,"Hash of Plantuml code: {0}",umlHash);
|
||||
var svg = umlCache.get(umlHash);
|
||||
if (svg != null){
|
||||
LOG.log(DEBUG,"Serving Plantuml generated SVG from cache…");
|
||||
source = source.substring(0, start) + svg + source.substring(end);
|
||||
matcher = UML_PATTERN.matcher(source);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG.log(DEBUG,"Cache miss. Generating SVG from plantuml code…");
|
||||
ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", plantumlJar.getAbsolutePath(), "-tsvg", "-pipe");
|
||||
var ignored = processBuilder.redirectErrorStream();
|
||||
var process = processBuilder.start();
|
||||
@@ -94,8 +106,11 @@ public class Util {
|
||||
|
||||
try (InputStream is = process.getInputStream()) {
|
||||
byte[] out = is.readAllBytes();
|
||||
var svg = new String(out, UTF_8);
|
||||
LOG.log(DEBUG,"Generated SVG. Pushing to cache…");
|
||||
svg = new String(out, UTF_8);
|
||||
umlCache.put(umlHash,svg);
|
||||
source = source.substring(0, start) + svg + source.substring(end);
|
||||
matcher = UML_PATTERN.matcher(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,19 +31,16 @@ public class Path {
|
||||
public static final String REDIRECT = "redirect";
|
||||
|
||||
public static final String SEARCH = "search";
|
||||
public static final String SERVICE = "service";
|
||||
public static final String SETTINGS = "settings";
|
||||
public static final String STATES = "states";
|
||||
public static final String STARTED = "started";
|
||||
public static final String STATE = "state";
|
||||
public static final String STOP = "stop";
|
||||
public static final String SUBMIT = "submit";
|
||||
|
||||
public static final String TAGGED = "tagged";
|
||||
public static final String TOKEN = "token";
|
||||
|
||||
public static final String USER = "user";
|
||||
public static final String USES = "uses";
|
||||
public static final String VIEW = "view";
|
||||
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ package de.srsoftware.umbrella.core.constants;
|
||||
* This is a collection of messages that appear throughout the project
|
||||
*/
|
||||
public class Text {
|
||||
public static final String BOOLEAN = "Boolean";
|
||||
public static final String BOOKMARK = "bookmark";
|
||||
public static final String BOOLEAN = "Boolean";
|
||||
|
||||
public static final String COMPANIES = "companies";
|
||||
public static final String COMPANY = "company";
|
||||
public static final String COMPANY_WITH_ID = "company ({id})";
|
||||
@@ -15,41 +16,51 @@ public class Text {
|
||||
public static final String CONTACT_WITH_ID = "contact ({id})";
|
||||
public static final String CUSTOMER = "customer";
|
||||
public static final String CUSTOMER_SETTINGS = "customer settings";
|
||||
|
||||
public static final String DOCUMENT = "document";
|
||||
public static final String DOCUMENTS = "documents";
|
||||
public static final String DOCUMENT_TYPE_ID = "document type id";
|
||||
public static final String DOCUMENT_WITH_ID = "document ({id})";
|
||||
|
||||
public static final String INVALID_DB_CODE = "Encountered invalid dbCode: {code}";
|
||||
public static final String ITEM = "item";
|
||||
public static final String ITEMS = "items";
|
||||
|
||||
public static final String LOCATION = "location";
|
||||
public static final String LOCATIONS = "locations";
|
||||
public static final String LOGIN_SERVICE = "login service";
|
||||
public static final String LONG = "Long";
|
||||
|
||||
public static final String NOTE = "note";
|
||||
public static final String NOTE_WITH_ID = "note ({id})";
|
||||
public static final String NUMBER = "number";
|
||||
|
||||
public static final String PATH = "path";
|
||||
public static final String PROJECT = "project";
|
||||
public static final String PROPERTIES = "properties";
|
||||
public static final String PROJECT_WITH_ID = "project ({id})";
|
||||
public static final String PROPERTIES = "properties";
|
||||
public static final String PROPERTY = "property";
|
||||
|
||||
public static final String SENDER = "sender";
|
||||
public static final String SESSION = "session";
|
||||
public static final String SERVICE_WITH_ID = "service ({id})";
|
||||
public static final String SESSION = "session";
|
||||
public static final String SETTINGS = "settings";
|
||||
public static final String STRING = "string";
|
||||
|
||||
public static final String TABLE_WITH_NAME = "table {name}";
|
||||
public static final String TAGS = "tags";
|
||||
public static final String TASK = "task";
|
||||
public static final String TASKS = "tasks";
|
||||
public static final String TIME_WITH_ID = "time ({id})";
|
||||
public static final String TYPE = "type";
|
||||
|
||||
public static final String UNIT = "unit";
|
||||
public static final String USER_WITH_ID = "user ({id})";
|
||||
|
||||
public static final String WIKI_PAGE = "wiki page";
|
||||
public static final String WIKI_PAGES = "wiki pages";
|
||||
public static final String UNIT = "unit";
|
||||
public static final String T_UNIT_PRICE = "unit price";
|
||||
|
||||
public static final String UNIT_PRICE = "unit price";
|
||||
public static final String USER = "user";
|
||||
public static final String USERS = "users";
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
*.db-journal
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"umbrella": {
|
||||
"base_url": "http://127.0.0.1:5173",
|
||||
"logging": {
|
||||
"rootLevel": "INFO"
|
||||
},
|
||||
"http": {
|
||||
"port": 8080
|
||||
},
|
||||
"threads": 16,
|
||||
"modules": {
|
||||
"notes": {
|
||||
"database": "demodata/notes.db"
|
||||
},
|
||||
"document": {
|
||||
"database": "demodata/documents.db",
|
||||
"templates": "demodata/templates"
|
||||
},
|
||||
"wiki": {
|
||||
"database": "demodata/wiki.db"
|
||||
},
|
||||
"project": {
|
||||
"database": "demodata/projects.db"
|
||||
},
|
||||
"message": {
|
||||
"database": "demodata/message.db",
|
||||
"smtp": {
|
||||
"pass": "none",
|
||||
"port": 587,
|
||||
"host": "none",
|
||||
"user": "none"
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"database": "demodata/tags.db"
|
||||
},
|
||||
"bookmark": {
|
||||
"database": "demodata/bookmark.db"
|
||||
},
|
||||
"task": {
|
||||
"database": "demodata/tasks.db"
|
||||
},
|
||||
"journal": {
|
||||
"database": "demodata/journal.db"
|
||||
},
|
||||
"contact": {
|
||||
"database": "demodata/contacts.db"
|
||||
},
|
||||
"files": {
|
||||
"database": "demodata/files.db",
|
||||
"base_dir": "demodata/filestore"
|
||||
},
|
||||
"company": {
|
||||
"database": "demodata/company.db"
|
||||
},
|
||||
"time": {
|
||||
"database": "demodata/times.db"
|
||||
},
|
||||
"stock": {
|
||||
"database": "demodata/stock.db"
|
||||
},
|
||||
"items": {},
|
||||
"user": {
|
||||
"database": "demodata/users.db"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -24,6 +24,7 @@ import static de.srsoftware.umbrella.core.constants.Field.SENDER;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.STATE;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.TYPE;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.UNIT;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.UNIT_PRICE;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.USER;
|
||||
import static de.srsoftware.umbrella.core.constants.Path.*;
|
||||
import static de.srsoftware.umbrella.core.constants.Text.*;
|
||||
@@ -540,6 +541,11 @@ public class DocumentApi extends BaseHandler implements DocumentService {
|
||||
var userCompanyIds = companyService().listCompaniesOf(user).keySet();
|
||||
|
||||
var documents = db.find(userCompanyIds,keys,fulltext);
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return sendContent(ex,mapValues(documents));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import static de.srsoftware.umbrella.core.constants.Field.NUMBER;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.SENDER;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.TYPE;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.UNIT;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.UNIT_PRICE;
|
||||
import static de.srsoftware.umbrella.core.constants.Text.*;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||
import static de.srsoftware.umbrella.core.model.Document.DEFAULT_THOUSANDS_SEPARATOR;
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { useTinyRouter } from 'svelte-tiny-router';
|
||||
import { api } from '../../urls.svelte';
|
||||
import { error, yikes } from '../../warn.svelte';
|
||||
import { error, warn, yikes } from '../../warn.svelte';
|
||||
import { t } from '../../translations.svelte';
|
||||
import { user } from '../../user.svelte';
|
||||
|
||||
const image_extensions = ['jpg','jpeg','gif','png','svg','webp'];
|
||||
const router = useTinyRouter();
|
||||
let children = $state({});
|
||||
|
||||
let new_dir = $state(null);
|
||||
let files = $state();
|
||||
let parent = $state(false);
|
||||
@@ -17,23 +18,6 @@
|
||||
let delete_allowed = $state(false);
|
||||
let available = $derived.by(isAvailable);
|
||||
|
||||
function isAvailable(){
|
||||
if (!new_dir) return false;
|
||||
if (children){
|
||||
if (children.dirs) {
|
||||
for (let key of Object.values(children.dirs)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
if (children.files) {
|
||||
for (let key of Object.values(children.files)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function create_dir(ev){
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
@@ -74,13 +58,30 @@
|
||||
|
||||
async function handleDirectory(res){
|
||||
let json = await res.json();
|
||||
children.dirs = json.dirs ? json.dirs : {};
|
||||
children.files = json.files ? json.files : {};
|
||||
children.dirs = json.dirs ? val_sort(json.dirs) : {};
|
||||
children.files = json.files ? val_sort(json.files) : {};
|
||||
children.title = json.title ? json.title : path;
|
||||
delete_allowed = json.delete;
|
||||
yikes();
|
||||
}
|
||||
|
||||
function isAvailable(){
|
||||
if (!new_dir) return false;
|
||||
if (children){
|
||||
if (children.dirs) {
|
||||
for (let key of Object.values(children.dirs)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
if (children.files) {
|
||||
for (let key of Object.values(children.files)){
|
||||
if (key == new_dir) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function is_image(file){
|
||||
let parts = file.toLowerCase().split('.');
|
||||
let ext = parts.pop();
|
||||
@@ -90,12 +91,15 @@
|
||||
async function loadChildren(p){
|
||||
p = p.substring(6);
|
||||
if (p == '') p = '/';
|
||||
children = { dirs : {}, files : {}, title : p};
|
||||
children = { dirs : [], files : [], title : p};
|
||||
path = p;
|
||||
if (p == '/'){
|
||||
children.dirs[`/user/${user.id}`] = t('my_files');
|
||||
children.dirs['/project'] = t('projects')
|
||||
children.dirs['/company'] = t('companies');
|
||||
children.dirs = [
|
||||
{ path : `/user/${user.id}`, name : t('my files') },
|
||||
{ path : '/project', name : t('projects')},
|
||||
{ path : '/company', name : t('companies')},
|
||||
]
|
||||
|
||||
parent = false;
|
||||
form = false;
|
||||
} else {
|
||||
@@ -114,8 +118,12 @@
|
||||
|
||||
function markdown(file){
|
||||
let parts = file.split('/');
|
||||
let md = ``;
|
||||
let path = `/api/files${file}`;
|
||||
path = encodeURI(path);
|
||||
let md = ``;
|
||||
navigator.clipboard.writeText(md);
|
||||
warn(t('Markdown has been copied to clipboard!'));
|
||||
setTimeout(yikes, 2500);
|
||||
}
|
||||
|
||||
function onclick(ev){
|
||||
@@ -153,6 +161,12 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
function val_sort(map){
|
||||
return Object.entries(map)
|
||||
.map(item => ({name:item[1],path:item[0]}))
|
||||
.sort((a,b) => a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
onMount(() => loadChildren(window.location.pathname));
|
||||
</script>
|
||||
|
||||
@@ -166,12 +180,12 @@
|
||||
</li>
|
||||
{/if}
|
||||
{#if children?.dirs}
|
||||
{#each Object.entries(children.dirs) as [k,v]}
|
||||
{#each children.dirs as dir}
|
||||
<li class="dir">
|
||||
<span class="symbol"></span>
|
||||
<a href={'/files'+k} {onclick}>{v}</a>
|
||||
<a href={'/files'+dir.path} {onclick}>{dir.name}</a>
|
||||
{#if delete_allowed}
|
||||
<button class="symbol" onclick={e => dropDir(`/api/files${k}`,v)}></button>
|
||||
<button class="symbol" onclick={e => dropDir(`/api/files${dir.path}`,dir.name)}></button>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
@@ -186,15 +200,15 @@
|
||||
</li>
|
||||
{/if}
|
||||
{#if children.files}
|
||||
{#each Object.entries(children.files) as [k,v]}
|
||||
{#each children.files as file}
|
||||
<li class="file">
|
||||
<span class="symbol"></span>
|
||||
<a href={`/api/files${k}`} target="_blank">{v}</a>
|
||||
{#if is_image(k)}
|
||||
<button class="symbol" title={'markdown_code'} onclick={e => markdown(k)}></button>
|
||||
<a href={`/api/files${file.path}`} target="_blank">{file.name}</a>
|
||||
{#if is_image(file.path)}
|
||||
<button class="symbol" title={'markdown_code'} onclick={e => markdown(file.path)}></button>
|
||||
{/if}
|
||||
{#if delete_allowed}
|
||||
<button class="symbol" title={t('delete_object',{'object':t('file')})} onclick={e => dropFile(`/api/files${k}`,v)}></button>
|
||||
<button class="symbol" title={t('delete_object',{'object':t('file')})} onclick={e => dropFile(`/api/files${file.path}`,file.name)}></button>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { useTinyRouter } from 'svelte-tiny-router';
|
||||
import { api, post, target } from '../../urls.svelte.js';
|
||||
import { error, yikes } from '../../warn.svelte';
|
||||
import { api, get, post, target } from '../../urls.svelte.js';
|
||||
import { error, warn, yikes } from '../../warn.svelte';
|
||||
import { t } from '../../translations.svelte.js';
|
||||
import { display } from '../../time.svelte';
|
||||
|
||||
import Bookmark from '../bookmark/Template.svelte';
|
||||
|
||||
const router = useTinyRouter();
|
||||
let counter = 9;
|
||||
let bookmarks = $state(null);
|
||||
let companies = $state(null);
|
||||
let documents = $state(null);
|
||||
@@ -34,12 +35,12 @@
|
||||
});
|
||||
|
||||
function doSearch(ignored){
|
||||
warn(t('searching…'));
|
||||
let url = window.location.origin + window.location.pathname;
|
||||
if (key) url += '?key=' + encodeURI(key);
|
||||
window.history.replaceState(history.state, '', url);
|
||||
|
||||
const data = { key : key, fulltext : fulltext };
|
||||
|
||||
post(api('bookmark/search'),data).then(handleBookmarks);
|
||||
post(api('company/search '),data).then(handleCompanies);
|
||||
post(api('document/search'),data).then(handleDocuments);
|
||||
@@ -51,6 +52,22 @@
|
||||
post(api('wiki/search' ),data).then(handleWikiPages);
|
||||
}
|
||||
|
||||
async function getTitle(key,module,entity_id){
|
||||
get(api(module+'/'+entity_id)).then(res => setTitle(res,key,module))
|
||||
}
|
||||
|
||||
async function setTitle(resp,key,module){
|
||||
if (resp.ok){
|
||||
const json = await resp.json();
|
||||
if (json.name) notes[key].title = t(module)+": "+json.name;
|
||||
if (json.title) notes[key].title = t(module)+": "+json.title;
|
||||
if (module == 'document'){
|
||||
notes[key].title = t(json.type)+" "+json.number;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onclick(e){
|
||||
e.preventDefault();
|
||||
var target = e.target;
|
||||
@@ -61,6 +78,7 @@
|
||||
}
|
||||
|
||||
async function handleBookmarks(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const res = await resp.json();
|
||||
bookmarks = Object.keys(res).length ? res : null;
|
||||
@@ -70,6 +88,7 @@
|
||||
}
|
||||
|
||||
async function handleCompanies(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const json = await resp.json();
|
||||
companies = Object.keys(json).length ? json : null;
|
||||
@@ -79,6 +98,7 @@
|
||||
}
|
||||
|
||||
async function handleDocuments(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const json = await resp.json();
|
||||
documents = Object.keys(json).length ? json : null;
|
||||
@@ -88,15 +108,25 @@
|
||||
}
|
||||
|
||||
async function handleNotes(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const json = await resp.json();
|
||||
notes = Object.keys(json).length ? json : null;
|
||||
if ( Object.keys(json).length ) {
|
||||
for (let key of Object.keys(json)){
|
||||
let module = json[key].module;
|
||||
let entity_id = json[key].entity_id;
|
||||
json[key].title = t(module)+' '+entity_id;
|
||||
getTitle(key,module,entity_id);
|
||||
}
|
||||
notes = json;
|
||||
} else notes = null;
|
||||
} else {
|
||||
error(resp);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleProjects(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const res = await resp.json();
|
||||
projects = Object.keys(res).length ? res : null;
|
||||
@@ -106,6 +136,7 @@
|
||||
}
|
||||
|
||||
async function handleStock(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const res = await resp.json();
|
||||
stock = Object.keys(res).length ? res : null;
|
||||
@@ -115,6 +146,7 @@
|
||||
}
|
||||
|
||||
async function handleTasks(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const res = await resp.json();
|
||||
tasks = Object.keys(res).length ? res : null;
|
||||
@@ -124,6 +156,7 @@
|
||||
}
|
||||
|
||||
async function handleTimes(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const res = await resp.json();
|
||||
times = Object.keys(res).length ? res : null;
|
||||
@@ -133,6 +166,7 @@
|
||||
}
|
||||
|
||||
async function handleWikiPages(resp){
|
||||
quitOne();
|
||||
if (resp.ok){
|
||||
const res = await resp.json();
|
||||
pages = Object.keys(res).length ? res : null;
|
||||
@@ -141,6 +175,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
function quitOne(){
|
||||
counter--;
|
||||
if (counter > 0) {
|
||||
warn(t('searching…')+" "+counter);
|
||||
} else yikes();
|
||||
}
|
||||
|
||||
$effect(() => doSearch(key))
|
||||
</script>
|
||||
|
||||
@@ -236,23 +277,6 @@
|
||||
</ul>
|
||||
</fieldset>
|
||||
{/if}
|
||||
{#if notes}
|
||||
<fieldset>
|
||||
<legend>
|
||||
{t('notes')}
|
||||
</legend>
|
||||
<ul>
|
||||
{#each Object.values(notes) as note}
|
||||
<li>
|
||||
<b>
|
||||
<a href="/{note.module}/{note.entity_id}/view" {onclick} >{t(note.module)} {note.entity_id}:</a>
|
||||
</b>
|
||||
{@html target(note.text.rendered)}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</fieldset>
|
||||
{/if}
|
||||
{#if times}
|
||||
<fieldset>
|
||||
<legend>
|
||||
@@ -308,3 +332,20 @@
|
||||
</ul>
|
||||
</fieldset>
|
||||
{/if}
|
||||
{#if notes}
|
||||
<fieldset>
|
||||
<legend>
|
||||
{t('notes')}
|
||||
</legend>
|
||||
<ul>
|
||||
{#each Object.values(notes) as note}
|
||||
<li>
|
||||
<b>
|
||||
<a href="/{note.module}/{note.entity_id}/view" {onclick} >{note.title}</a>
|
||||
</b>
|
||||
{@html target(note.text.rendered)}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</fieldset>
|
||||
{/if}
|
||||
|
||||
@@ -15,5 +15,5 @@ export async function warn(msg){
|
||||
|
||||
export function yikes(){
|
||||
messages.error = null;
|
||||
messages.warn = null;
|
||||
messages.warning = null;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||
import static de.srsoftware.umbrella.core.ModuleRegistry.companyService;
|
||||
import static de.srsoftware.umbrella.core.ModuleRegistry.translator;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.*;
|
||||
import static de.srsoftware.umbrella.core.constants.Text.T_UNIT_PRICE;
|
||||
import static de.srsoftware.umbrella.core.constants.Text.UNIT;
|
||||
import static de.srsoftware.umbrella.core.constants.Text.UNIT_PRICE;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.databaseException;
|
||||
import static de.srsoftware.umbrella.stock.Constants.TABLE_ITEMS;
|
||||
import static java.lang.System.Logger.Level.DEBUG;
|
||||
@@ -75,7 +75,7 @@ public class ItemDb {
|
||||
LOG.log(DEBUG, " using location: {0}",location.resolve().name());
|
||||
var stockItem = new Item(0,company,0,location,code,name,description);
|
||||
var props = stockItem.properties();
|
||||
var keyUnitPrice = translator().translate(lang,T_UNIT_PRICE);
|
||||
var keyUnitPrice = translator().translate(lang, Text.UNIT_PRICE);
|
||||
var keyUnit = translator().translate(lang, Text.UNIT);
|
||||
var keyTax = translator().translate(lang,TAX_RATE);
|
||||
var keyLegacyId = translator().translate(lang,"legacy_id");
|
||||
|
||||
@@ -132,7 +132,23 @@ public class StockModule extends BaseHandler implements StockService {
|
||||
yield super.doGet(path,ex);
|
||||
}
|
||||
}
|
||||
case null, default -> super.doGet(path,ex);
|
||||
case null -> super.doGet(path,ex);
|
||||
default -> {
|
||||
try {
|
||||
var id = Long.parseLong(head);
|
||||
Item item = stockDb.loadItem(id);
|
||||
Owner owner = item.owner().resolve();
|
||||
if (owner instanceof Company company) {
|
||||
if (!companyService().membership(company.id(),user.get().id())) throw forbidden("You are not allowed to access {0}",OBJECT);
|
||||
}
|
||||
if (owner instanceof UmbrellaUser u){
|
||||
if (u.id() != user.get().id()) throw forbidden("You are not allowed to access {0}",OBJECT);
|
||||
}
|
||||
yield sendContent(ex,item);
|
||||
} catch (NumberFormatException nfe){
|
||||
yield super.doGet(path,ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (UmbrellaException e){
|
||||
return send(ex,e);
|
||||
|
||||
@@ -39,6 +39,7 @@ public class SqliteDb extends BaseDb implements TagDB{
|
||||
public SqliteDb(Connection tagDb, Connection bmDb) {
|
||||
super(tagDb);
|
||||
bookmarks = new de.srsoftware.umbrella.bookmarks.SqliteDb(bmDb);
|
||||
createTables();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,6 @@ public class Translations extends PathHandler implements Translator {
|
||||
}
|
||||
|
||||
private JSONObject loadTranslations(String lang) throws IOException {
|
||||
LOG.log(WARNING,"loadTranslations({0}) not implemented!",lang);
|
||||
var filename = lang + ".json";
|
||||
URL url = getClass().getClassLoader().getResource(filename);
|
||||
if (url == null) return new JSONObject();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"basic_data": "Basis-Daten",
|
||||
"bookmark": "Lesezeichen",
|
||||
"bookmarks": "Lesezeichen",
|
||||
"Boolean": "Boolean",
|
||||
"by": "von",
|
||||
|
||||
"cancel": "abbrechen",
|
||||
@@ -30,6 +31,7 @@
|
||||
"confirm_state": "Status wirklich ändern?",
|
||||
"companies": "Firmen",
|
||||
"company": "Firma",
|
||||
"company ({id})": "Firma ({id})",
|
||||
"company_optional": "Firma (optional)",
|
||||
"confirmation": "Bestätigung",
|
||||
"complete": "abschließen",
|
||||
@@ -53,6 +55,7 @@
|
||||
"customer_address": "Adresse",
|
||||
"customer_email": "Emailadresse des Kunden",
|
||||
"customer_id": "Kundennummer",
|
||||
"customer settings": "Kunden-Einstellungen",
|
||||
"custom_tag_colors": "Nutzerdefinierte Tag-Farben",
|
||||
|
||||
"data_sent": "Daten übermittelt",
|
||||
@@ -72,6 +75,8 @@
|
||||
"document": "Dokument",
|
||||
"document_list": "Dokumente",
|
||||
"documents": "Dokumente",
|
||||
"document type id": "Dokumenten-Typ-ID",
|
||||
"document ({id})": "Dokument ({id})",
|
||||
"do_login" : "anmelden",
|
||||
"do_open" : "öffnen",
|
||||
"do_send" : "versenden",
|
||||
@@ -87,6 +92,7 @@
|
||||
"edit_service": "Login-Service \"{name}\" bearbeiten",
|
||||
"email": "E-Mail",
|
||||
"email_or_username": "Email oder Nutzername",
|
||||
"Encountered invalid dbCode: {code}": "Ungültiger dbCode aufgetreten: {code}",
|
||||
"end": "Ende",
|
||||
"estimated_time": "geschätzte Zeit",
|
||||
"estimated_times": "geschätzte Zeiten",
|
||||
@@ -167,12 +173,16 @@
|
||||
"local_court": "Amtsgericht",
|
||||
"locality": "Ort",
|
||||
"location": "Ort",
|
||||
"locations": "Orte",
|
||||
"login" : "Anmeldung",
|
||||
"login service": "Login-Service",
|
||||
"login_services": "Login-Services",
|
||||
"logout": "Abmelden",
|
||||
"logout_user": "{user} abmelden",
|
||||
"Long": "Ganzzahl",
|
||||
|
||||
"markdown_code": "Markdown-Code",
|
||||
"Markdown has been copied to clipboard!": "Markdown wurde in die Zwischenablage kopiert!",
|
||||
"markdown_supported": "Markdown & <a target=\"_blank\" href=\"https://plantuml.com\">Plantuml</a> nutzbar!",
|
||||
"MANAGE_LOGIN_SERVICES": "Login-Services verwalten",
|
||||
"member": "Mitarbeiter",
|
||||
@@ -205,6 +215,7 @@
|
||||
"month": "Monat",
|
||||
"move_to_top": "nach ganz oben bewegen",
|
||||
"must_not_be_empty": "darf nicht leer sein",
|
||||
"my files": "Meine Dateien",
|
||||
|
||||
"name": "Name",
|
||||
"net_price": "Nettopreis",
|
||||
@@ -218,6 +229,7 @@
|
||||
"no_project_for_id": "Kein Projekt mit ID {0} gefunden!",
|
||||
"no_task_for_id": "Keine Aufgabe mit ID {0} gefunden!",
|
||||
"note": "Notiz",
|
||||
"note ({id})": "Notiz ({id})",
|
||||
"notes": "Notizen",
|
||||
"not_recent_version": "Die ist nicht die neuste Version dieser Seite!",
|
||||
"number": "Nummer",
|
||||
@@ -230,6 +242,7 @@
|
||||
"page": "Seite",
|
||||
"parent_task": "übergeordnete Aufgabe",
|
||||
"password" : "Passwort",
|
||||
"path": "Pfad",
|
||||
"permission": {
|
||||
"EDIT": "lesen/schreiben",
|
||||
"OWNER": "Besitzer"
|
||||
@@ -250,7 +263,10 @@
|
||||
"priority": "Priorität",
|
||||
"processing_code": "Code wird verarbeitet…",
|
||||
"project": "Projekt",
|
||||
"project ({id})": "Projekt ({id})",
|
||||
"projects": "Projekte",
|
||||
"properties": "Eigenschaften",
|
||||
"property": "Eigenschaft",
|
||||
|
||||
"record": "Eintrag",
|
||||
"region": "Bundesland",
|
||||
@@ -262,6 +278,7 @@
|
||||
"saved": "gespeichert",
|
||||
"save_object": "{object} speichern",
|
||||
"search": "Suche",
|
||||
"searching…": "suche…",
|
||||
"select_company" : "Wählen Sie eine ihrer Firmen:",
|
||||
"select_customer": "Kunde auswählen",
|
||||
"select_property": "Eigenschaft auswählen",
|
||||
@@ -274,6 +291,8 @@
|
||||
"sender_tax_id": "Steuernummer",
|
||||
"sent_email": "Email gesendet",
|
||||
"service": "Service",
|
||||
"service ({id})": "Service ({id})",
|
||||
"session": "Sitzung",
|
||||
"settings" : "Einstellungen",
|
||||
"share_with": "Teilen mit:",
|
||||
"show": "anzeigen",
|
||||
@@ -301,12 +320,14 @@
|
||||
},
|
||||
"stock": "Inventar",
|
||||
"street": "Straße",
|
||||
"string": "Text",
|
||||
"subject": "Betreff",
|
||||
"subtask": "Unteraufgabe",
|
||||
"subtasks": "Unteraufgaben",
|
||||
"succeeding_document": "Nachfolge-Dokument",
|
||||
"sum_of_records": "Summe der ausgewählten Einträge",
|
||||
|
||||
"table {name}": "Tabelle {name}",
|
||||
"tag_name": "Tag-Name",
|
||||
"tag_uses": "Verwendung des Tags „{tag}“",
|
||||
"tags": "Tags",
|
||||
@@ -319,6 +340,7 @@
|
||||
"tax_rate": "Steuersatz",
|
||||
"template": "Vorlage",
|
||||
"theme": "Design",
|
||||
"time ({id})": "Zeit ({id})",
|
||||
"times": "Zeiten",
|
||||
"timetracking": "Zeiterfassung",
|
||||
"title_not_available": "„{title}“ ist als Seitenname nicht mehr verfügbar!",
|
||||
@@ -333,6 +355,7 @@
|
||||
|
||||
"unexpected_item_id_format": "Alte Artikel-ID sollte die Form tt:zz:zz haben, habe aber {0} gefunden!",
|
||||
"unit": "Einheit",
|
||||
"unit price": "Preis/Einheit",
|
||||
"unit_price": "Preis/Einheit",
|
||||
"unknown_item_location": "Artikel {0} von {1} {2} ist verknüpft mit unbekanntem Lagerort {3}!",
|
||||
"unlink": "Trennen",
|
||||
@@ -340,6 +363,7 @@
|
||||
"UPDATE_USERS" : "Nutzer aktualisieren",
|
||||
"upload_file": "Datei hochladen",
|
||||
"user": "Benutzer",
|
||||
"user ({id})": "Benutzer ({id})",
|
||||
"user_list": "Benutzer-Liste",
|
||||
"user_module" : "Umbrella User-Verwaltung",
|
||||
"users": "Benutzer",
|
||||
@@ -351,6 +375,8 @@
|
||||
"welcome" : "Willkommen, {0}",
|
||||
"wiki": "Wiki",
|
||||
"wikis": "Wiki-Seiten",
|
||||
"wiki page": "Wiki-Seite",
|
||||
"wiki pages": "Wiki-Seiten",
|
||||
"wiki_pages": "Wiki-Seiten",
|
||||
|
||||
"value": "Wert",
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"basic_data": "basic data",
|
||||
"bookmark": "bookmark",
|
||||
"bookmarks": "bookmarks",
|
||||
"Boolean": "Boolean",
|
||||
"by": "by",
|
||||
|
||||
"cancel": "cancel",
|
||||
@@ -30,6 +31,7 @@
|
||||
"confirm_state": "Really change state?",
|
||||
"companies": "companies",
|
||||
"company": "company",
|
||||
"company ({id})": "company ({id})",
|
||||
"company_optional": "company (optional)",
|
||||
"confirmation": "confirmation",
|
||||
"complete": "complete",
|
||||
@@ -53,6 +55,7 @@
|
||||
"customer_address": "address",
|
||||
"customer_email": "customer email address",
|
||||
"customer_id": "customer ID",
|
||||
"customer settings": "customer settings",
|
||||
"custom_tag_colors": "custom tag colors",
|
||||
|
||||
"data_sent": "data sent",
|
||||
@@ -72,6 +75,8 @@
|
||||
"document": "document",
|
||||
"document_list": "document list",
|
||||
"documents": "documents",
|
||||
"document type id": "document type id",
|
||||
"document ({id})":"document ({id})",
|
||||
"do_login" : "do login",
|
||||
"do_open" : "open",
|
||||
"do_send" : "send",
|
||||
@@ -87,6 +92,7 @@
|
||||
"edit_service": "edit login service \"{name}\"",
|
||||
"email": "email",
|
||||
"email_or_username": "email or username",
|
||||
"Encountered invalid dbCode: {code}": "Encountered invalid dbCode: {code}",
|
||||
"end": "end",
|
||||
"estimated_time": "estimated duration",
|
||||
"estimated_times": "estimated durations",
|
||||
@@ -167,12 +173,16 @@
|
||||
"local_court": "local court",
|
||||
"locality": "locality",
|
||||
"location": "location",
|
||||
"locations": "locations",
|
||||
"login" : "login",
|
||||
"login service": "login service",
|
||||
"login_services": "login service",
|
||||
"logout": "logout",
|
||||
"logout_user": "logout {user}",
|
||||
"Long": "Long",
|
||||
|
||||
"markdown_code": "Markdown-Code",
|
||||
"Markdown has been copied to clipboard!": "Markdown has been copied to clipboard!",
|
||||
"markdown_supported": "Markdown & <a target=\"_blank\" href=\"https://plantuml.com\">Plantuml</a> supported!",
|
||||
"MANAGE_LOGIN_SERVICES": "manage login services",
|
||||
"member": "member",
|
||||
@@ -205,6 +215,7 @@
|
||||
"month": "month",
|
||||
"move_to_top": "move to top level",
|
||||
"must_not_be_empty": "must not be empty",
|
||||
"my files": "my files",
|
||||
|
||||
"name": "Name",
|
||||
"net_price": "net price",
|
||||
@@ -218,6 +229,7 @@
|
||||
"no_project_for_id": "No project found for id {0}",
|
||||
"no_task_for_id": "No task found for id {0}",
|
||||
"note": "note",
|
||||
"note ({id})":"note ({id})",
|
||||
"notes": "notes",
|
||||
"not_recent_version": "This is not the current version of this page!",
|
||||
"number": "number",
|
||||
@@ -230,6 +242,7 @@
|
||||
"page": "page",
|
||||
"parent_task": "parent task",
|
||||
"password" : "password",
|
||||
"path": "path",
|
||||
"permission": {
|
||||
"EDIT": "read/write",
|
||||
"OWNER": "owner"
|
||||
@@ -250,7 +263,10 @@
|
||||
"priority": "priority",
|
||||
"processing_code": "processing code…",
|
||||
"project": "project",
|
||||
"project ({id})": "project ({id})",
|
||||
"projects": "projects",
|
||||
"properties": "properties",
|
||||
"property": "property",
|
||||
|
||||
"record": "record",
|
||||
"region": "region",
|
||||
@@ -262,6 +278,7 @@
|
||||
"saved": "saved",
|
||||
"save_object": "save {object}",
|
||||
"search": "search",
|
||||
"searching…": "searhcing…",
|
||||
"select_company" : "select on of you companies:",
|
||||
"select_customer": "select customer",
|
||||
"select_property": "select property",
|
||||
@@ -274,6 +291,8 @@
|
||||
"sender_tax_id": "tax ID",
|
||||
"sent_email": "email sent",
|
||||
"service": "service",
|
||||
"service ({id})": "service ({id})",
|
||||
"session": "session",
|
||||
"settings" : "settings",
|
||||
"share_with": "share with:",
|
||||
"show": "show",
|
||||
@@ -301,12 +320,14 @@
|
||||
},
|
||||
"stock": "stock",
|
||||
"street": "street",
|
||||
"string": "string",
|
||||
"subject": "subject",
|
||||
"subtask": "subtask",
|
||||
"subtasks": "subtasks",
|
||||
"succeeding_document": "succeeding document",
|
||||
"sum_of_records": "sum of records",
|
||||
|
||||
"table {name}": "table {name}",
|
||||
"tag_name": "tag name",
|
||||
"tag_uses": "usage of tag „{tag}“",
|
||||
"tags": "tags",
|
||||
@@ -319,13 +340,14 @@
|
||||
"tax_rate": "tax rate",
|
||||
"template": "template",
|
||||
"theme": "design",
|
||||
"time ({id})": "time ({id})",
|
||||
"times": "times",
|
||||
"timetracking": "time tracking",
|
||||
"title_not_available": "„{title}“ is not available as page name!",
|
||||
"title_or_desc": "title/description",
|
||||
"toggle_objects": "toggle {objects}",
|
||||
"tutorial": "tutorial",
|
||||
"type": "document type",
|
||||
"type": "type",
|
||||
"type_confirmation": "confirmation",
|
||||
"type_invoice": "invoice",
|
||||
"type_offer": "offer",
|
||||
@@ -333,6 +355,7 @@
|
||||
|
||||
"unexpected_item_id_format": "Expected old item ID to be of the form ss:dd:dd, encountered {0}!",
|
||||
"unit": "unit",
|
||||
"unit price": "unit price",
|
||||
"unit_price": "price/unit",
|
||||
"unknown_item_location": "Item {0} of {1} {2} refers to location {3}, which is unknown!",
|
||||
"unlink": "unlink",
|
||||
@@ -340,14 +363,20 @@
|
||||
"UPDATE_USERS" : "update users",
|
||||
"upload_file": "upload file",
|
||||
"user": "user",
|
||||
"user ({id})": "user ({id})",
|
||||
"user_list": "user list",
|
||||
"user_module" : "Umbrella user management",
|
||||
"users": "users",
|
||||
"user_created_entity": "{user} created \"{entity}\"",
|
||||
"user_deleted_entity": "{user} deleted \"{entity}\"",
|
||||
"user_updated_entity": "{user} updated \"{entity}\"",
|
||||
|
||||
"website": "website",
|
||||
"welcome" : "Welcome, {0}",
|
||||
"wiki": "Wiki",
|
||||
"wikis": "wiki pages",
|
||||
"wiki page": "wiki page",
|
||||
"wiki pages": "wiki pages",
|
||||
"wiki_pages": "wiki pages",
|
||||
|
||||
"value": "value",
|
||||
|
||||
@@ -9,4 +9,5 @@ tasks.processResources {
|
||||
from("../frontend/dist") {
|
||||
into("web")
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
@@ -57,8 +57,9 @@ footer {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
img {
|
||||
img, svg {
|
||||
max-width: 100%;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
nav {
|
||||
|
||||
@@ -57,8 +57,9 @@ footer {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
img {
|
||||
img, svg {
|
||||
max-width: 100%;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
nav {
|
||||
|
||||
@@ -57,8 +57,9 @@ footer {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
img {
|
||||
img, svg {
|
||||
max-width: 100%;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
nav {
|
||||
|
||||
@@ -152,15 +152,27 @@ public class SqliteDb extends BaseDb implements WikiDb {
|
||||
@Override
|
||||
public Map<Long, WikiPage> find(long userId, List<String> keys, boolean fulltext) {
|
||||
try {
|
||||
var query = select(ALL).from(TABLE_PAGES).leftJoin(ID,TABLE_PAGES_USERS,PAGE_ID).where(USER_ID,equal(userId));
|
||||
for (var key : keys) query.where(TITLE,like("%"+key+"%"));
|
||||
var rs = query.exec(db);
|
||||
var map = new HashMap<Long,WikiPage>();
|
||||
{
|
||||
var query = select(ALL).from(TABLE_PAGES).leftJoin(ID, TABLE_PAGES_USERS, PAGE_ID).where(USER_ID, equal(userId));
|
||||
for (var key : keys) query.where(TITLE, like("%" + key.replaceAll("[ÄäÖöÜüß]", "%") + "%"));
|
||||
var rs = query.exec(db);
|
||||
while (rs.next()) {
|
||||
var page = WikiPage.of(rs);
|
||||
map.put(page.id(),page);
|
||||
map.put(page.id(), page);
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
if (fulltext) {
|
||||
var query = select(ALL).from(TABLE_PAGES).leftJoin(ID, TABLE_PAGES_USERS, PAGE_ID).where(USER_ID, equal(userId));
|
||||
for (var key : keys) query.where(CONTENT, like("%" + key.replaceAll("[ÄäÖöÜüß]", "%") + "%"));
|
||||
var rs = query.exec(db);
|
||||
while (rs.next()) {
|
||||
var page = WikiPage.of(rs);
|
||||
map.put(page.id(), page);
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
return map;
|
||||
} catch (SQLException e) {
|
||||
throw failedToSearchDb(t(WIKI_PAGES)).causedBy(e);
|
||||
|
||||
Reference in New Issue
Block a user