implemented changing project state from project page
This commit is contained in:
@@ -14,6 +14,7 @@ public class Paths {
|
|||||||
public static final String SEARCH = "search";
|
public static final String SEARCH = "search";
|
||||||
public static final String SERVICE = "service";
|
public static final String SERVICE = "service";
|
||||||
public static final String SETTINGS = "settings";
|
public static final String SETTINGS = "settings";
|
||||||
|
public static final String STATES = "states";
|
||||||
public static final String SUBMIT = "submit";
|
public static final String SUBMIT = "submit";
|
||||||
public static final String TOKEN = "token";
|
public static final String TOKEN = "token";
|
||||||
public static final String VIEW = "view";
|
public static final String VIEW = "view";
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ public class Constants {
|
|||||||
public static final String POSITION = "position";
|
public static final String POSITION = "position";
|
||||||
public static final String PROJECT_ID = "project_id";
|
public static final String PROJECT_ID = "project_id";
|
||||||
|
|
||||||
public static final String STATES = "states";
|
|
||||||
|
|
||||||
public static final String TABLE_COMPANY_SETTINGS = "company_settings";
|
public static final String TABLE_COMPANY_SETTINGS = "company_settings";
|
||||||
public static final String TABLE_CUSTOMER_SETTINGS = "company_customer_settings";
|
public static final String TABLE_CUSTOMER_SETTINGS = "company_customer_settings";
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import static de.srsoftware.tools.Strings.escapeHtmlEntities;
|
|||||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||||
import static de.srsoftware.umbrella.core.Constants.*;
|
import static de.srsoftware.umbrella.core.Constants.*;
|
||||||
import static de.srsoftware.umbrella.core.Paths.LIST;
|
import static de.srsoftware.umbrella.core.Paths.LIST;
|
||||||
|
import static de.srsoftware.umbrella.core.Paths.STATES;
|
||||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE;
|
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE;
|
||||||
import static de.srsoftware.umbrella.core.Util.request;
|
import static de.srsoftware.umbrella.core.Util.request;
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||||
|
|||||||
30
frontend/src/Components/StateSelector.svelte
Normal file
30
frontend/src/Components/StateSelector.svelte
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<script>
|
||||||
|
import {onMount} from 'svelte';
|
||||||
|
import {t} from '../translations.svelte.js';
|
||||||
|
let { caption = t('select_state'), selected = $bindable(0), onchange = (val) => console.log('changed to '+val)} = $props();
|
||||||
|
|
||||||
|
let message = $state(t('loading'));
|
||||||
|
let states = $state(null);
|
||||||
|
|
||||||
|
async function loadStates(){
|
||||||
|
const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/task/states`;
|
||||||
|
var resp = await fetch(url,{credentials: 'include'});
|
||||||
|
if (resp.ok){
|
||||||
|
states = await resp.json();
|
||||||
|
} else {
|
||||||
|
message = await resp.text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(loadStates)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if states}
|
||||||
|
<select bind:value={selected} onchange={() => onchange(selected)}>
|
||||||
|
{#each Object.entries(states) as [k,s]}
|
||||||
|
<option value={+k}>{t('state_'+s.toLowerCase())}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
{:else}
|
||||||
|
<span>{message}</span>
|
||||||
|
{/if}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import TaskList from '../../Components/TaskList.svelte';
|
import TaskList from '../../Components/TaskList.svelte';
|
||||||
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
|
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
|
||||||
import LineEditor from '../../Components/LineEditor.svelte';
|
import LineEditor from '../../Components/LineEditor.svelte';
|
||||||
|
import StateSelector from '../../Components/StateSelector.svelte';
|
||||||
|
|
||||||
let { id } = $props();
|
let { id } = $props();
|
||||||
let project = $state(null);
|
let project = $state(null);
|
||||||
@@ -69,6 +70,12 @@
|
|||||||
<LineEditor bind:value={project.name} editable={true} onSet={val => update({name:val})} />
|
<LineEditor bind:value={project.name} editable={true} onSet={val => update({name:val})} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{t('state')}</th>
|
||||||
|
<td>
|
||||||
|
<StateSelector selected={project.status.code} onchange={val => update({status:val})}/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{#if project.company}
|
{#if project.company}
|
||||||
<tr>
|
<tr>
|
||||||
<th>{t('company')}</th>
|
<th>{t('company')}</th>
|
||||||
|
|||||||
@@ -115,9 +115,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getProject(HttpExchange ex, long projectId, UmbrellaUser user) throws IOException, UmbrellaException {
|
private boolean addMembers(Project project, HttpExchange ex) throws IOException {
|
||||||
var project = projects.load(projectId);
|
|
||||||
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name());
|
|
||||||
var map = project.toMap();
|
var map = project.toMap();
|
||||||
var members = new HashMap<Long,Map<String,Object>>();
|
var members = new HashMap<Long,Map<String,Object>>();
|
||||||
for (var member : project.members()){
|
for (var member : project.members()){
|
||||||
@@ -128,6 +126,13 @@ public class ProjectModule extends BaseHandler implements ProjectService {
|
|||||||
if (!members.isEmpty()) map.put(MEMBERS,members);
|
if (!members.isEmpty()) map.put(MEMBERS,members);
|
||||||
project.companyId().map(companies::get).map(Company::toMap).ifPresent(data -> map.put(COMPANY,data));
|
project.companyId().map(companies::get).map(Company::toMap).ifPresent(data -> map.put(COMPANY,data));
|
||||||
return sendContent(ex,map);
|
return sendContent(ex,map);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getProject(HttpExchange ex, long projectId, UmbrellaUser user) throws IOException, UmbrellaException {
|
||||||
|
var project = projects.load(projectId);
|
||||||
|
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name());
|
||||||
|
return addMembers(project,ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean postProjectList(HttpExchange ex, UmbrellaUser user) throws IOException {
|
private boolean postProjectList(HttpExchange ex, UmbrellaUser user) throws IOException {
|
||||||
@@ -183,7 +188,7 @@ public class ProjectModule extends BaseHandler implements ProjectService {
|
|||||||
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name());
|
if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name());
|
||||||
var json = json(ex);
|
var json = json(ex);
|
||||||
projects.save(project.patch(json));
|
projects.save(project.patch(json));
|
||||||
return sendContent(ex,project.toMap());
|
return addMembers(project,ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import static de.srsoftware.tools.Optionals.isSet;
|
|||||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||||
import static de.srsoftware.umbrella.core.Constants.*;
|
import static de.srsoftware.umbrella.core.Constants.*;
|
||||||
import static de.srsoftware.umbrella.core.Paths.LIST;
|
import static de.srsoftware.umbrella.core.Paths.LIST;
|
||||||
|
import static de.srsoftware.umbrella.core.Paths.STATES;
|
||||||
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_NOT_IMPLEMENTED;
|
import static de.srsoftware.umbrella.core.ResponseCode.HTTP_NOT_IMPLEMENTED;
|
||||||
import static de.srsoftware.umbrella.core.Util.mapValues;
|
import static de.srsoftware.umbrella.core.Util.mapValues;
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.forbidden;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.forbidden;
|
||||||
@@ -22,10 +23,7 @@ import de.srsoftware.umbrella.core.api.ProjectService;
|
|||||||
import de.srsoftware.umbrella.core.api.TaskService;
|
import de.srsoftware.umbrella.core.api.TaskService;
|
||||||
import de.srsoftware.umbrella.core.api.UserService;
|
import de.srsoftware.umbrella.core.api.UserService;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
import de.srsoftware.umbrella.core.model.Project;
|
import de.srsoftware.umbrella.core.model.*;
|
||||||
import de.srsoftware.umbrella.core.model.Task;
|
|
||||||
import de.srsoftware.umbrella.core.model.Token;
|
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -49,6 +47,23 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
return companies;
|
return companies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
|
addCors(ex);
|
||||||
|
try {
|
||||||
|
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
||||||
|
var user = users.loadUser(token);
|
||||||
|
if (user.isEmpty()) return unauthorized(ex);
|
||||||
|
var head = path.pop();
|
||||||
|
return switch (head) {
|
||||||
|
case STATES -> getStateList(ex);
|
||||||
|
default -> super.doGet(path,ex);
|
||||||
|
};
|
||||||
|
} catch (UmbrellaException e){
|
||||||
|
return send(ex,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
public boolean doPost(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
addCors(ex);
|
||||||
@@ -89,6 +104,12 @@ public class TaskModule extends BaseHandler implements TaskService {
|
|||||||
return sendContent(ex,result);
|
return sendContent(ex,result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean getStateList(HttpExchange ex) throws IOException {
|
||||||
|
var map = new HashMap<Integer,String>();
|
||||||
|
for (var status : Status.values()) map.put(status.code(),status.name());
|
||||||
|
return sendContent(ex,map);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HashMap<Long, Task> listCompanyTasks(long companyId) throws UmbrellaException {
|
public HashMap<Long, Task> listCompanyTasks(long companyId) throws UmbrellaException {
|
||||||
var projectList = projects.listCompanyProjects(companyId,false);
|
var projectList = projects.listCompanyProjects(companyId,false);
|
||||||
|
|||||||
@@ -175,7 +175,9 @@
|
|||||||
"state_new":"neu",
|
"state_new":"neu",
|
||||||
"state_open": "offen",
|
"state_open": "offen",
|
||||||
"state_payed": "bezahlt",
|
"state_payed": "bezahlt",
|
||||||
|
"state_pending": "ausstehend",
|
||||||
"state_sent": "versendet",
|
"state_sent": "versendet",
|
||||||
|
"state_started": "gestartet",
|
||||||
"status" : {
|
"status" : {
|
||||||
"403": "Zugriff verweigert",
|
"403": "Zugriff verweigert",
|
||||||
"404": "Seite nicht gefunden",
|
"404": "Seite nicht gefunden",
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user