preparing to manage weights in poll
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -51,4 +51,5 @@ public class Path {
|
|||||||
public static final String USER = "user";
|
public static final String USER = "user";
|
||||||
public static final String USES = "uses";
|
public static final String USES = "uses";
|
||||||
|
|
||||||
|
public static final String WEIGHT = "weight";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public class Text {
|
|||||||
public static final String UNIT = "unit";
|
public static final String UNIT = "unit";
|
||||||
public static final String USER_WITH_ID = "user ({id})";
|
public static final String USER_WITH_ID = "user ({id})";
|
||||||
|
|
||||||
|
public static final String WEIGHT = "weight";
|
||||||
public static final String WIKI = "wiki";
|
public static final String WIKI = "wiki";
|
||||||
public static final String WIKI_PAGE = "wiki page";
|
public static final String WIKI_PAGE = "wiki page";
|
||||||
public static final String WIKI_PAGES = "wiki pages";
|
public static final String WIKI_PAGES = "wiki pages";
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ import static java.text.MessageFormat.format;
|
|||||||
|
|
||||||
public class Poll implements Mappable {
|
public class Poll implements Mappable {
|
||||||
public static class Option implements Mappable{
|
public static class Option implements Mappable{
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
Integer status;
|
Integer status;
|
||||||
private String description;
|
private String description;
|
||||||
private String name;
|
private String name;
|
||||||
private final Set<String> dirtyFields = new HashSet<>();
|
private final Set<String> dirtyFields = new HashSet<>();
|
||||||
|
|
||||||
public Option(int id, String name, String description, Integer status) {
|
public Option(int id, String name, String description, Integer status) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@@ -102,16 +102,16 @@ public class Poll implements Mappable {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return format("Option \"{0}\"",name);
|
return format("Option \"{0}\"",name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
private Owner owner;
|
private Owner owner;
|
||||||
|
|
||||||
private String id, name, description;
|
private String id, name, description;
|
||||||
private boolean isPrivate;
|
private boolean isPrivate;
|
||||||
private List<Option> options;
|
private List<Option> options;
|
||||||
private Map<Integer,String> weights;
|
private Map<Integer,String> weights;
|
||||||
private Map<UmbrellaUser,Long> shares;
|
private Map<UmbrellaUser,Long> shares;
|
||||||
private Set<String> dirtyFields = new HashSet<>();
|
private Set<String> dirtyFields = new HashSet<>();
|
||||||
|
|
||||||
public Poll(String id, Owner owner, String name, String description, boolean isPrivate, List<Option> options, Map<Integer,String> weights, Map<UmbrellaUser,Long> shares){
|
public Poll(String id, Owner owner, String name, String description, boolean isPrivate, List<Option> options, Map<Integer,String> weights, Map<UmbrellaUser,Long> shares){
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
@@ -141,6 +141,13 @@ public class Poll implements Mappable {
|
|||||||
return !dirtyFields.isEmpty();
|
return !dirtyFields.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDirty(String ... fields){
|
||||||
|
for (var field : fields){
|
||||||
|
if (dirtyFields.contains(field)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPrivate(){
|
public boolean isPrivate(){
|
||||||
return isPrivate;
|
return isPrivate;
|
||||||
}
|
}
|
||||||
@@ -180,10 +187,17 @@ public class Poll implements Mappable {
|
|||||||
public List<Option> options(){
|
public List<Option> options(){
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Owner owner(){
|
public Owner owner(){
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Poll setWeight(Integer weight, String description) {
|
||||||
|
weights.put(weight,description);
|
||||||
|
dirtyFields.add(WEIGHTS);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<UmbrellaUser, Long> shares(){
|
public Map<UmbrellaUser, Long> shares(){
|
||||||
return shares;
|
return shares;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
let { id } = $props();
|
let { id } = $props();
|
||||||
let new_option = $state({name:'',description:{'source':'',rendered:''}});
|
let new_option = $state({name:'',description:{'source':'',rendered:''}});
|
||||||
|
let new_weight = $state({description:'',weight:0});
|
||||||
let poll = $state(null);
|
let poll = $state(null);
|
||||||
|
|
||||||
async function load(){
|
async function load(){
|
||||||
@@ -51,7 +52,23 @@
|
|||||||
if (field == 'name' && newVal == ''){
|
if (field == 'name' && newVal == ''){
|
||||||
poll.options = poll.options.filter(o => o.id !== option.id);
|
poll.options = poll.options.filter(o => o.id !== option.id);
|
||||||
} else poll.options = json.options;
|
} else poll.options = json.options;
|
||||||
} else error(res);
|
return true;
|
||||||
|
}
|
||||||
|
error(res);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function patch_weight(data){
|
||||||
|
let url = api(`poll/${id}/weight`);
|
||||||
|
let res = await patch(url,data);
|
||||||
|
if (res.ok) {
|
||||||
|
yikes();
|
||||||
|
const json = await res.json();
|
||||||
|
console.log(json);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
error(res);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -66,6 +83,12 @@
|
|||||||
} else error(res);
|
} else error(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function save_new_weight(e){
|
||||||
|
const data = {};
|
||||||
|
data[new_weight.weight] = new_weight.description;
|
||||||
|
patch_weight(data);
|
||||||
|
}
|
||||||
|
|
||||||
onMount(load);
|
onMount(load);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -130,10 +153,19 @@
|
|||||||
<input type="number" value={weight} />
|
<input type="number" value={weight} />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="text" value={descr} />
|
<LineEditor value={descr} onSet={desc => patch_weight({weight: desc})} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="number" bind:value={new_weight.weight} />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" bind:value={new_weight.description} />
|
||||||
|
<button onclick={save_new_weight}>{t('save')}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
|||||||
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
||||||
import static de.srsoftware.umbrella.core.constants.Field.FIELD;
|
import static de.srsoftware.umbrella.core.constants.Field.FIELD;
|
||||||
import static de.srsoftware.umbrella.core.constants.Field.ID;
|
import static de.srsoftware.umbrella.core.constants.Field.ID;
|
||||||
import static de.srsoftware.umbrella.core.constants.Path.LIST;
|
import static de.srsoftware.umbrella.core.constants.Path.*;
|
||||||
import static de.srsoftware.umbrella.core.constants.Path.OPTION;
|
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||||
import static de.srsoftware.umbrella.poll.Constants.CONFIG_DATABASE;
|
import static de.srsoftware.umbrella.poll.Constants.CONFIG_DATABASE;
|
||||||
import static java.lang.System.Logger.Level.WARNING;
|
import static java.lang.System.Logger.Level.WARNING;
|
||||||
@@ -117,6 +116,7 @@ public class PollModule extends BaseHandler implements PollService {
|
|||||||
return switch (head){
|
return switch (head){
|
||||||
case null -> patchPoll(ex, poll);
|
case null -> patchPoll(ex, poll);
|
||||||
case OPTION -> patchPollOptions(ex, path, poll);
|
case OPTION -> patchPollOptions(ex, path, poll);
|
||||||
|
case WEIGHT -> patchWeights(ex, poll);
|
||||||
default -> notFound(ex);
|
default -> notFound(ex);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -136,6 +136,11 @@ public class PollModule extends BaseHandler implements PollService {
|
|||||||
return sendContent(ex,pollDb.save(poll));
|
return sendContent(ex,pollDb.save(poll));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean patchWeights(HttpExchange ex, Poll poll) throws IOException {
|
||||||
|
// TODO
|
||||||
|
return notFound(ex);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean patchPollOptions(HttpExchange ex, Path path, Poll poll) throws IOException {
|
private boolean patchPollOptions(HttpExchange ex, Path path, Poll poll) throws IOException {
|
||||||
try {
|
try {
|
||||||
if (path.empty()) throw missingField(ID);
|
if (path.empty()) throw missingField(ID);
|
||||||
@@ -180,7 +185,7 @@ public class PollModule extends BaseHandler implements PollService {
|
|||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
return switch (head){
|
return switch (head){
|
||||||
case OPTION -> postOption(ex, poll);
|
case OPTION -> postOption(ex, poll);
|
||||||
default -> notFound(ex);
|
case null, default -> notFound(ex);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,11 @@ import static de.srsoftware.umbrella.core.constants.Field.*;
|
|||||||
import static de.srsoftware.umbrella.core.constants.Field.DESCRIPTION;
|
import static de.srsoftware.umbrella.core.constants.Field.DESCRIPTION;
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||||
import static de.srsoftware.umbrella.poll.Constants.*;
|
import static de.srsoftware.umbrella.poll.Constants.*;
|
||||||
import static java.lang.System.Logger.Level.WARNING;
|
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
|
|
||||||
import de.srsoftware.umbrella.core.BaseDb;
|
import de.srsoftware.umbrella.core.BaseDb;
|
||||||
import de.srsoftware.umbrella.core.constants.Field;
|
import de.srsoftware.umbrella.core.constants.Field;
|
||||||
import de.srsoftware.umbrella.core.constants.Text;
|
import de.srsoftware.umbrella.core.constants.Text;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
|
||||||
import de.srsoftware.umbrella.core.model.Poll;
|
import de.srsoftware.umbrella.core.model.Poll;
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||||
|
|
||||||
@@ -112,6 +110,15 @@ public class SqliteDb extends BaseDb implements PollDb {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dropWeight(Poll poll, int weight){
|
||||||
|
try {
|
||||||
|
delete().from(TABLE_WEIGHTS).where(POLL_ID, equal(poll.id())).where(ID, equal(weight)).execute(db);
|
||||||
|
poll.weights().remove(weight);
|
||||||
|
} catch (SQLException e){
|
||||||
|
throw failedToDropObject(Text.WEIGHT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Poll> listPolls(UmbrellaUser user) {
|
public Collection<Poll> listPolls(UmbrellaUser user) {
|
||||||
try {
|
try {
|
||||||
@@ -145,7 +152,7 @@ public class SqliteDb extends BaseDb implements PollDb {
|
|||||||
while (rs.next()) poll.options().add(Poll.Option.of(rs));
|
while (rs.next()) poll.options().add(Poll.Option.of(rs));
|
||||||
rs.close();
|
rs.close();
|
||||||
|
|
||||||
rs = select(ALL).from(TABLE_WEIGHTS).where(POLL_ID,equal(id)).exec(db);
|
rs = select(ALL).from(TABLE_WEIGHTS).where(POLL_ID,equal(id)).sort(WEIGHT+" ASC").exec(db);
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
var weight = rs.getInt(WEIGHT);
|
var weight = rs.getInt(WEIGHT);
|
||||||
var descr = rs.getString(DESCRIPTION);
|
var descr = rs.getString(DESCRIPTION);
|
||||||
@@ -200,13 +207,25 @@ public class SqliteDb extends BaseDb implements PollDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Poll update(Poll poll) {
|
private Poll update(Poll poll) {
|
||||||
if (poll.isDirty()) try {
|
if (poll.isDirty(NAME, DESCRIPTION)) try {
|
||||||
LOG.log(WARNING,"Updating poll not fully implemented");
|
|
||||||
|
|
||||||
replaceInto(TABLE_POLLS,ID,Field.USER_ID,NAME,DESCRIPTION).values(poll.id(),poll.owner().id(),poll.name(),poll.description()).execute(db);
|
replaceInto(TABLE_POLLS,ID,Field.USER_ID,NAME,DESCRIPTION).values(poll.id(),poll.owner().id(),poll.name(),poll.description()).execute(db);
|
||||||
} catch (SQLException e){
|
} catch (SQLException e){
|
||||||
throw failedToStoreObject(poll);
|
throw failedToStoreObject(poll);
|
||||||
}
|
}
|
||||||
|
if (poll.isDirty(WEIGHTS)) try {
|
||||||
|
Map.copyOf(poll.weights())
|
||||||
|
.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue().isBlank())
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.forEach(w -> dropWeight(poll,w));
|
||||||
|
var query = replaceInto(TABLE_WEIGHTS, POLL_ID, WEIGHT, DESCRIPTION);
|
||||||
|
for (var entry : poll.weights().entrySet()){
|
||||||
|
query.values(poll.id(),entry.getKey(),entry.getValue());
|
||||||
|
}
|
||||||
|
query.execute(db).close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw failedToStoreObject(poll);
|
||||||
|
}
|
||||||
for (var option : poll.options()) saveOption(poll.id(),option);
|
for (var option : poll.options()) saveOption(poll.id(),option);
|
||||||
return poll;
|
return poll;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user