Browse Source

added links to documents to time track list

module/search
Stephan Richter 2 months ago
parent
commit
dbe7e51b7d
  1. 1
      company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java
  2. 3
      core/src/main/java/de/srsoftware/umbrella/core/api/DocumentService.java
  3. 4
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java
  4. 9
      documents/src/main/java/de/srsoftware/umbrella/documents/DocumentDb.java
  5. 23
      documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java
  6. 27
      frontend/src/routes/time/Index.svelte
  7. 2
      time/src/main/java/de/srsoftware/umbrella/time/Constants.java
  8. 2
      time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java
  9. 2
      web/src/main/resources/web/css/default.css

1
company/src/main/java/de/srsoftware/umbrella/company/SqliteDb.java

@ -19,7 +19,6 @@ import de.srsoftware.umbrella.core.model.Company;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import org.json.JSONObject; import org.json.JSONObject;
public class SqliteDb extends BaseDb implements CompanyDb { public class SqliteDb extends BaseDb implements CompanyDb {

3
core/src/main/java/de/srsoftware/umbrella/core/api/DocumentService.java

@ -4,7 +4,10 @@ package de.srsoftware.umbrella.core.api;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.Document; import de.srsoftware.umbrella.core.model.Document;
import java.util.Map; import java.util.Map;
import java.util.Set;
public interface DocumentService { public interface DocumentService {
Map<Long, Map<Long, String>> docsReferencedByTimes(Set<Long> timeIds) throws UmbrellaException;
Map<Long, Document> list(long companyId) throws UmbrellaException; Map<Long, Document> list(long companyId) throws UmbrellaException;
} }

4
documents/src/main/java/de/srsoftware/umbrella/documents/DocumentApi.java

@ -430,6 +430,10 @@ public class DocumentApi extends BaseHandler implements DocumentService {
} }
} }
@Override
public Map<Long, Map<Long, String>> docsReferencedByTimes(Set<Long> timeIds) throws UmbrellaException {
return db.docReferencedByTimes(timeIds);
}
private boolean patchDocument(long docId, UmbrellaUser user, HttpExchange ex) throws UmbrellaException, IOException { private boolean patchDocument(long docId, UmbrellaUser user, HttpExchange ex) throws UmbrellaException, IOException {
var doc = getDocument(docId,user).a; var doc = getDocument(docId,user).a;

9
documents/src/main/java/de/srsoftware/umbrella/documents/DocumentDb.java

@ -10,6 +10,7 @@ import de.srsoftware.umbrella.documents.model.*;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set;
public interface DocumentDb { public interface DocumentDb {
Long dropPosition(long documentId, long pos) throws UmbrellaException; Long dropPosition(long documentId, long pos) throws UmbrellaException;
@ -27,9 +28,13 @@ public interface DocumentDb {
CompanySettings getCompanySettings(long companyId, Type docType) throws UmbrellaException; CompanySettings getCompanySettings(long companyId, Type docType) throws UmbrellaException;
Collection<Template> getCompanyTemplates(long l) throws UmbrellaException;
Type getType(int typeId) throws UmbrellaException; Type getType(int typeId) throws UmbrellaException;
Map<Long, Document> listDocs(long companyId) throws UmbrellaException; public Map<Long, Map<Long, String>> docReferencedByTimes(Set<Long> timeIds) throws UmbrellaException;
Map<Long, Document> listDocs(long companyId) throws UmbrellaException;
HashMap<Integer, Type> listTypes() throws UmbrellaException; HashMap<Integer, Type> listTypes() throws UmbrellaException;
@ -55,6 +60,4 @@ public interface DocumentDb {
void step(CompanySettings settings); void step(CompanySettings settings);
Pair<Integer> switchPositions(long docId, Pair<Integer> longPair) throws UmbrellaException; Pair<Integer> switchPositions(long docId, Pair<Integer> longPair) throws UmbrellaException;
Collection<Template> getCompanyTemplates(long l) throws UmbrellaException;
} }

23
documents/src/main/java/de/srsoftware/umbrella/documents/SqliteDb.java

@ -25,10 +25,7 @@ import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.Instant; import java.time.Instant;
import java.util.Collection; import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class SqliteDb implements DocumentDb{ public class SqliteDb implements DocumentDb{
private static final System.Logger LOG = System.getLogger(SqliteDb.class.getSimpleName()); private static final System.Logger LOG = System.getLogger(SqliteDb.class.getSimpleName());
@ -319,6 +316,24 @@ CREATE TABLE IF NOT EXISTS {0} ( {1} VARCHAR(255) PRIMARY KEY, {2} VARCHAR(255)
var version = createTables(); var version = createTables();
} }
@Override
public Map<Long, Map<Long, String>> docReferencedByTimes(Set<Long> timeIds) throws UmbrellaException {
try {
var map = new HashMap<Long, Map<Long, String>>(); // Map ( timeId → Map ( docId → name ))
var rs = select(FIELD_TIME_ID,FIELD_DOCUMENT_ID,NUMBER).from(TABLE_POSITIONS).leftJoin(FIELD_DOCUMENT_ID,TABLE_DOCUMENTS,ID).where(FIELD_TIME_ID,in(timeIds.toArray())).exec(db);
while (rs.next()) {
var timeId = rs.getLong(FIELD_TIME_ID);
var docId = rs.getLong(FIELD_DOCUMENT_ID);
var number = rs.getString(NUMBER);
map.computeIfAbsent(timeId,k -> new HashMap<>()).put(docId,number);
}
rs.close();
return map;
} catch (SQLException e) {
throw databaseException("Failed to list Documents for list of times");
}
}
@Override @Override
public Map<Long, Document> listDocs(long companyId) throws UmbrellaException { public Map<Long, Document> listDocs(long companyId) throws UmbrellaException {
try { try {

27
frontend/src/routes/time/Index.svelte

@ -7,6 +7,7 @@
import TimeEditor from '../../Components/TimeRecordEditor.svelte'; import TimeEditor from '../../Components/TimeRecordEditor.svelte';
let docLinks = $state(null);
let error = $state(null); let error = $state(null);
let router = useTinyRouter(); let router = useTinyRouter();
let times = $state(null); let times = $state(null);
@ -85,9 +86,10 @@
const resp = await fetch(url,{credentials:'include'}); const resp = await fetch(url,{credentials:'include'});
if (resp.ok){ if (resp.ok){
var json = await resp.json(); var json = await resp.json();
times = json.times; times = json.times;
tasks = json.tasks; tasks = json.tasks;
projects = json.projects; projects = json.projects;
docLinks = json.documents;
} else { } else {
error = await resp.text(); error = await resp.text();
} }
@ -97,6 +99,14 @@
detail = null; detail = null;
} }
function onclick(e){
e.preventDefault();
let href = e.target.getAttribute('href');
if (href) router.navigate(href);
return false;
}
async function onDrop(time_id){ async function onDrop(time_id){
const url = api(`time/${time_id}`); const url = api(`time/${time_id}`);
const res = await fetch(url,{ const res = await fetch(url,{
@ -226,9 +236,9 @@
{#if tasks[tid]} {#if tasks[tid]}
<li> <li>
{#if tasks[tid] && projects[tasks[tid].project_id]} {#if tasks[tid] && projects[tasks[tid].project_id]}
<a href="#" onclick={e => openProject(tasks[tid].project_id)}>{projects[tasks[tid].project_id].name}</a> / <a href="/project/{tasks[tid].project_id}/view" {onclick}>{projects[tasks[tid].project_id].name}</a> /
{/if} {/if}
<a href="#" onclick={e => openTask(tid)}>{tasks[tid].name}</a> <a href="/task/{tid}/view" {onclick}>{tasks[tid].name}</a>
</li> </li>
{/if} {/if}
{/each} {/each}
@ -236,6 +246,15 @@
</td> </td>
<td class="state" onclick={e => {detail = time.id}}> <td class="state" onclick={e => {detail = time.id}}>
{t("state_"+time.state.name.toLowerCase())} {t("state_"+time.state.name.toLowerCase())}
{#if time.state.name.toLowerCase() == 'pending' && docLinks[time.id]}
<ul>
{#each Object.entries(docLinks[time.id]) as [a,b]}
<li>
<a href="/document/{a}/view" {onclick}>{b}</a>
</li>
{/each}
</ul>
{/if}
</td> </td>
{/if} {/if}
</tr> </tr>

2
time/src/main/java/de/srsoftware/umbrella/time/Constants.java

@ -4,9 +4,9 @@ package de.srsoftware.umbrella.time;
public class Constants { public class Constants {
private Constants(){} private Constants(){}
public static final String CHILDREN = "children"; public static final String CHILDREN = "children";
public static final String CONFIG_DATABASE = "umbrella.modules.time.database"; public static final String CONFIG_DATABASE = "umbrella.modules.time.database";
public static final String DOCUMENTS = "documents";
public static final String JOIN = "join"; public static final String JOIN = "join";
public static final String PROJECTS = "projects"; public static final String PROJECTS = "projects";
public static final String TABLE_TASK_TIMES = "task_times"; public static final String TABLE_TASK_TIMES = "task_times";

2
time/src/main/java/de/srsoftware/umbrella/time/TimeModule.java

@ -238,6 +238,8 @@ public class TimeModule extends BaseHandler implements TimeService {
taskIds = times.values().stream().map(Time::taskIds).flatMap(Collection::stream).collect(toSet()); taskIds = times.values().stream().map(Time::taskIds).flatMap(Collection::stream).collect(toSet());
var tasks = taskService().load(taskIds); var tasks = taskService().load(taskIds);
var result = new HashMap<String,Object>(); var result = new HashMap<String,Object>();
var docList = documentService().docsReferencedByTimes(times.keySet());
result.put(DOCUMENTS,docList);
result.put(TIMES,mapValues(times)); result.put(TIMES,mapValues(times));
result.put(TASKS,mapValues(tasks)); result.put(TASKS,mapValues(tasks));
result.put(PROJECTS,mapValues(projects)); result.put(PROJECTS,mapValues(projects));

2
web/src/main/resources/web/css/default.css

@ -346,7 +346,7 @@ li > a > p:nth-child(1){
top: 0; top: 0;
} }
table{ table{
width: 100vw; min-width: 30vw;
} }
.start_end{ .start_end{

Loading…
Cancel
Save