Browse Source

preparing for task priorities

module/users
Stephan Richter 1 month ago
parent
commit
48deb1a91c
  1. 1
      core/src/main/java/de/srsoftware/umbrella/core/Constants.java
  2. 1
      core/src/main/java/de/srsoftware/umbrella/core/model/Member.java
  3. 20
      core/src/main/java/de/srsoftware/umbrella/core/model/Task.java
  4. 5
      frontend/src/routes/task/View.svelte
  5. 24
      task/src/main/java/de/srsoftware/umbrella/task/SqliteDb.java
  6. 2
      wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiModule.java

1
core/src/main/java/de/srsoftware/umbrella/core/Constants.java

@ -135,6 +135,7 @@ public class Constants {
public static final String PASSWORD = "password"; public static final String PASSWORD = "password";
public static final String PERMISSION = "permission"; public static final String PERMISSION = "permission";
public static final String POST = "POST"; public static final String POST = "POST";
public static final String PRIORITY = "priority";
public static final String PROJECT = "project"; public static final String PROJECT = "project";
public static final String PROJECT_ID = "project_id"; public static final String PROJECT_ID = "project_id";

1
core/src/main/java/de/srsoftware/umbrella/core/model/Member.java

@ -5,7 +5,6 @@ package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import de.srsoftware.tools.Mappable; import de.srsoftware.tools.Mappable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

20
core/src/main/java/de/srsoftware/umbrella/core/model/Task.java

@ -20,8 +20,8 @@ public class Task implements Mappable {
private final long id, projectId; private final long id, projectId;
private Long parentTaskId; private Long parentTaskId;
private String description, name; private String description, name;
private Set<Long> requiredTasksIds; private final Set<Long> requiredTasksIds;
private int status; private int status, priority;
private Double estimatedTime; private Double estimatedTime;
private LocalDate dueDate, start; private LocalDate dueDate, start;
private boolean noIndex, showClosed; private boolean noIndex, showClosed;
@ -29,7 +29,7 @@ public class Task implements Mappable {
private final Set<String> dirtyFields = new HashSet<>(); private final Set<String> dirtyFields = new HashSet<>();
public Task (long id, long projectId, Long parentTaskId, String name, String description, int status, Double estimatedTime, LocalDate start, LocalDate dueDate, boolean showClosed, boolean noIndex, Map<Long,Member> members){ public Task (long id, long projectId, Long parentTaskId, String name, String description, int status, Double estimatedTime, LocalDate start, LocalDate dueDate, boolean showClosed, boolean noIndex, Map<Long,Member> members, int priority){
this.id = id; this.id = id;
this.projectId = projectId; this.projectId = projectId;
this.parentTaskId = parentTaskId; this.parentTaskId = parentTaskId;
@ -43,6 +43,7 @@ public class Task implements Mappable {
this.noIndex = noIndex; this.noIndex = noIndex;
this.members = members; this.members = members;
this.requiredTasksIds = new HashSet<>(); this.requiredTasksIds = new HashSet<>();
this.priority = priority;
} }
public Task clean() { public Task clean() {
@ -105,6 +106,7 @@ public class Task implements Mappable {
var parentTaskId = rs.getLong(PARENT_TASK_ID); var parentTaskId = rs.getLong(PARENT_TASK_ID);
var startDate = nullIfEmpty(rs.getString(START_DATE)); var startDate = nullIfEmpty(rs.getString(START_DATE));
var dueDate = nullIfEmpty(rs.getString(DUE_DATE)); var dueDate = nullIfEmpty(rs.getString(DUE_DATE));
return new Task( return new Task(
rs.getLong(ID), rs.getLong(ID),
rs.getLong(PROJECT_ID), rs.getLong(PROJECT_ID),
@ -117,7 +119,8 @@ public class Task implements Mappable {
dueDate != null ? LocalDate.parse(dueDate) : null, dueDate != null ? LocalDate.parse(dueDate) : null,
rs.getBoolean(SHOW_CLOSED), rs.getBoolean(SHOW_CLOSED),
rs.getBoolean(NO_INDEX), rs.getBoolean(NO_INDEX),
new HashMap<>() new HashMap<>(),
rs.getInt(PRIORITY)
); );
} }
@ -149,9 +152,9 @@ public class Task implements Mappable {
LocalDate dueDate = json.has(DUE_DATE) && json.get(DUE_DATE) instanceof String d ? LocalDate.parse(d) : null; LocalDate dueDate = json.has(DUE_DATE) && json.get(DUE_DATE) instanceof String d ? LocalDate.parse(d) : null;
var showClosed = json.has(SHOW_CLOSED) && json.get(SHOW_CLOSED) instanceof Boolean sc ? sc : false; var showClosed = json.has(SHOW_CLOSED) && json.get(SHOW_CLOSED) instanceof Boolean sc ? sc : false;
var noIndex = json.has(NO_INDEX) && json.get(NO_INDEX) instanceof Boolean ni ? ni : false; var noIndex = json.has(NO_INDEX) && json.get(NO_INDEX) instanceof Boolean ni ? ni : false;
var priority = json.has(PRIORITY) && json.get(PRIORITY) instanceof Number pr ? prjId.intValue() : 0;
if (!(json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject)) throw missingFieldException(MEMBERS); if (!(json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject)) throw missingFieldException(MEMBERS);
return new Task(0,prjId.longValue(),parentTaskId,name,description,status,estimatedTime,startDate,dueDate,showClosed,noIndex,new HashMap<>()); return new Task(0,prjId.longValue(),parentTaskId,name,description,status,estimatedTime,startDate,dueDate,showClosed,noIndex,new HashMap<>(),priority);
} }
public Task patch(JSONObject json) { public Task patch(JSONObject json) {
@ -164,6 +167,7 @@ public class Task implements Mappable {
case NAME: name = json.getString(key); break; case NAME: name = json.getString(key); break;
case NO_INDEX: noIndex = json.getBoolean(NO_INDEX); break; case NO_INDEX: noIndex = json.getBoolean(NO_INDEX); break;
case PARENT_TASK_ID: parentTaskId = json.getLong(PARENT_TASK_ID); break; case PARENT_TASK_ID: parentTaskId = json.getLong(PARENT_TASK_ID); break;
case PRIORITY: priority = json.getInt(PRIORITY); break;
case REQUIRED_TASKS_IDS: case REQUIRED_TASKS_IDS:
requiredTasksIds.clear(); requiredTasksIds.clear();
requiredTasksIds.addAll(json.getJSONArray(REQUIRED_TASKS_IDS).toList().stream().map(entry -> Long.parseLong(entry.toString())).toList()); requiredTasksIds.addAll(json.getJSONArray(REQUIRED_TASKS_IDS).toList().stream().map(entry -> Long.parseLong(entry.toString())).toList());
@ -185,6 +189,10 @@ public class Task implements Mappable {
return parentTaskId; return parentTaskId;
} }
public int priority(){
return priority;
}
public long projectId(){ public long projectId(){
return projectId; return projectId;
} }

5
frontend/src/routes/task/View.svelte

@ -263,6 +263,11 @@
<input type="number" bind:value={task.estimated_time} onchange={() => update({estimated_time:task.estimated_time})} />&nbsp;h <input type="number" bind:value={task.estimated_time} onchange={() => update({estimated_time:task.estimated_time})} />&nbsp;h
</div> </div>
<div>{t('priority')}</div>
<div>
<input type="number" bind:value={task.priority} onchange={() => update({priority:task.priority})} />
</div>
<div>{t('depends_on')}</div> <div>{t('depends_on')}</div>
<div> <div>
<RequiredTasks {task} /> <RequiredTasks {task} />

24
task/src/main/java/de/srsoftware/umbrella/task/SqliteDb.java

@ -25,7 +25,6 @@ import java.util.*;
public class SqliteDb extends BaseDb implements TaskDb { public class SqliteDb extends BaseDb implements TaskDb {
private static final System.Logger LOG = System.getLogger("TaskDb"); private static final System.Logger LOG = System.getLogger("TaskDb");
private static final int INITIAL_DB_VERSION = 1;
public SqliteDb(Connection connection) { public SqliteDb(Connection connection) {
super(connection); super(connection);
@ -41,9 +40,11 @@ public class SqliteDb extends BaseDb implements TaskDb {
swapStates(TABLE_TASKS); swapStates(TABLE_TASKS);
case 2: case 2:
createDependencyTable(); createDependencyTable();
case 3:
createPriorityColumn();
} }
return setCurrentVersion(3); return setCurrentVersion(4);
} }
private void createDependencyTable() { private void createDependencyTable() {
@ -59,6 +60,15 @@ public class SqliteDb extends BaseDb implements TaskDb {
} }
} }
private void createPriorityColumn() {
var sql = format("ALTER TABLE {0} ADD {1} INT NOT NULL DEFAULT 0",TABLE_TASKS,PRIORITY);
try {
db.prepareStatement(sql).execute();
} catch (SQLException e) {
throw databaseException("Failed to add {0} column to {1}",PRIORITY,TABLE_TASKS);
}
}
private void createTaskTable() { private void createTaskTable() {
var createTable = """ var createTable = """
CREATE TABLE IF NOT EXISTS "{0}" ( CREATE TABLE IF NOT EXISTS "{0}" (
@ -299,15 +309,15 @@ CREATE TABLE IF NOT EXISTS {0} (
public Task save(Task task) { public Task save(Task task) {
try { try {
if (task.id() == 0){ // new task if (task.id() == 0){ // new task
var rs = insertInto(TABLE_TASKS,PROJECT_ID,PARENT_TASK_ID,NAME,DESCRIPTION,STATUS,EST_TIME,START_DATE,DUE_DATE,SHOW_CLOSED,NO_INDEX) var rs = insertInto(TABLE_TASKS,PROJECT_ID,PARENT_TASK_ID,NAME,DESCRIPTION,STATUS,EST_TIME,START_DATE,DUE_DATE,SHOW_CLOSED,NO_INDEX,PRIORITY)
.values(task.projectId(),task.parentTaskId(),task.name(),task.description(),task.status(),task.estimatedTime(),task.start(),task.dueDate(),task.showClosed(),task.noIndex()) .values(task.projectId(),task.parentTaskId(),task.name(),task.description(),task.status(),task.estimatedTime(),task.start(),task.dueDate(),task.showClosed(),task.noIndex(),task.priority())
.execute(db) .execute(db)
.getGeneratedKeys(); .getGeneratedKeys();
Long taskId = null; Long taskId = null;
if (rs.next()) taskId=rs.getLong(1); if (rs.next()) taskId=rs.getLong(1);
rs.close(); rs.close();
if (taskId == null) throw new UmbrellaException("Failed to save task {0}",task.name()); if (taskId == null) throw new UmbrellaException("Failed to save task {0}",task.name());
return new Task(taskId,task.projectId(),task.parentTaskId(),task.name(),task.description(),task.status(),task.estimatedTime(),task.start(),task.dueDate(),task.showClosed(),task.noIndex(),task.members()); return new Task(taskId,task.projectId(),task.parentTaskId(),task.name(),task.description(),task.status(),task.estimatedTime(),task.start(),task.dueDate(),task.showClosed(),task.noIndex(),task.members(), task.priority());
} }
if (task.isDirty(MEMBERS)){ if (task.isDirty(MEMBERS)){
var query = replaceInto(TABLE_TASKS_USERS,TASK_ID,USER_ID,PERMISSIONS); var query = replaceInto(TABLE_TASKS_USERS,TASK_ID,USER_ID,PERMISSIONS);
@ -332,9 +342,9 @@ CREATE TABLE IF NOT EXISTS {0} (
task.clean(REQUIRED_TASKS_IDS); task.clean(REQUIRED_TASKS_IDS);
} }
if (task.isDirty()) { if (task.isDirty()) {
update(TABLE_TASKS).set(PROJECT_ID,PARENT_TASK_ID,NAME,DESCRIPTION,STATUS,EST_TIME,START_DATE,DUE_DATE,SHOW_CLOSED,NO_INDEX) update(TABLE_TASKS).set(PROJECT_ID,PARENT_TASK_ID,NAME,DESCRIPTION,STATUS,EST_TIME,START_DATE,DUE_DATE,SHOW_CLOSED,NO_INDEX,PRIORITY)
.where(ID,equal(task.id())).prepare(db) .where(ID,equal(task.id())).prepare(db)
.apply(task.projectId(),task.parentTaskId(),task.name(),task.description(),task.status(),task.estimatedTime(),task.start(),task.dueDate(),task.showClosed(),task.noIndex()) .apply(task.projectId(),task.parentTaskId(),task.name(),task.description(),task.status(),task.estimatedTime(),task.start(),task.dueDate(),task.showClosed(),task.noIndex(),task.priority())
.close(); .close();
task.clean(); task.clean();
} }

2
wiki/src/main/java/de/srsoftware/umbrella/wiki/WikiModule.java

@ -20,11 +20,9 @@ import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.api.WikiService; import de.srsoftware.umbrella.core.api.WikiService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException; import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.*; import de.srsoftware.umbrella.core.model.*;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
public class WikiModule extends BaseHandler implements WikiService { public class WikiModule extends BaseHandler implements WikiService {
private final WikiDb wikiDb; private final WikiDb wikiDb;

Loading…
Cancel
Save