Browse Source

started to implement project tagging, was interrupted.

next on: saving tags for user = null
module/notes
Stephan Richter 3 months ago
parent
commit
382eae000c
  1. 2
      backend/src/main/java/de/srsoftware/umbrella/backend/Application.java
  2. 2
      core/src/main/java/de/srsoftware/umbrella/core/Constants.java
  3. 42
      frontend/src/routes/project/Create.svelte
  4. 4
      frontend/src/routes/project/Settings.svelte
  5. 19
      frontend/src/routes/tags/TagList.svelte
  6. 19
      project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java
  7. 8
      tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java

2
backend/src/main/java/de/srsoftware/umbrella/backend/Application.java

@ -66,8 +66,8 @@ public class Application { @@ -66,8 +66,8 @@ public class Application {
var legacyApi = new LegacyApi(userModule.userDb(),config);
var markdownApi = new MarkdownApi(userModule);
var messageApi = new MessageApi(messageSystem);
var projectModule = new ProjectModule(config,companyModule);
var tagModule = new TagModule(config,userModule);
var projectModule = new ProjectModule(config,companyModule,tagModule);
var taskModule = new TaskModule(config,projectModule,tagModule);
var timeModule = new TimeModule(config,taskModule);
var webHandler = new WebHandler();

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

@ -67,6 +67,7 @@ public class Constants { @@ -67,6 +67,7 @@ public class Constants {
public static final String PASSWORD = "password";
public static final String PERMISSION = "permission";
public static final String POST = "POST";
public static final String PROJECT = "project";
public static final String PROJECT_ID = "project_id";
public static final String RECEIVERS = "receivers";
@ -86,6 +87,7 @@ public class Constants { @@ -86,6 +87,7 @@ public class Constants {
public static final String SUBJECT = "subject";
public static final String TABLE_SETTINGS = "settings";
public static final String TAGS = "tags";
public static final String TEMPLATE = "template";
public static final String TEXT = "text";
public static final String THEME = "theme";

42
frontend/src/routes/project/Create.svelte

@ -5,19 +5,21 @@ @@ -5,19 +5,21 @@
import CompanySelector from '../../Components/CompanySelector.svelte';
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
import Settings from './Settings.svelte';
let showSettings = $state(false);
let ready = $derived(!!project.name.trim())
import Tags from '../tags/TagList.svelte';
let error = $state(null);
let ready = $derived(!!project.name.trim())
const router = useTinyRouter();
let showSettings = $state(false);
let project = $state({
name:'',
description : { source : '', rendered : '' },
settings:{
show_closed:false
}
},
tags: []
});
async function onsubmit(ev){
@ -40,6 +42,11 @@ @@ -40,6 +42,11 @@
project.company_id = company.id;
console.log(project);
}
function toggleSettings(ev){
ev.preventDefault();
showSettings = !showSettings;
}
</script>
<style>
@ -82,22 +89,39 @@ @@ -82,22 +89,39 @@
<MarkdownEditor bind:value={project.description} simple={true} />
</td>
</tr>
{#if !showSettings}
{#if showSettings}
<tr>
<th>
{t('settings')}
</th>
<td>
<button onclick={() => showSettings = true}>{t('extended_settings')}</button>
<label>
<input type="checkbox" bind:checked={project.settings.show_closed} />
{t('display_closed_tasks')}
</label>
</td>
</tr>
{:else}
<tr>
<th>
{t('settings')}
</th>
<td>
<button onclick={toggleSettings} >{t('extended_settings')}</button>
</td>
</tr>
{/if}
<tr>
<th>
{t('tags')}
</th>
<td>
<Tags module="project" bind:tags={project.tags} />
</td>
</tr>
</tbody>
</table>
</fieldset>
{#if showSettings}
<Settings bind:settings={project.settings}/>
{/if}
<button type="submit" disabled={!ready}>{t('create')}</button>
</fieldset>
</form>

4
frontend/src/routes/project/Settings.svelte

@ -6,8 +6,4 @@ @@ -6,8 +6,4 @@
</script>
<fieldset>
<legend>{t('settings')}</legend>
<label>
<input type="checkbox" bind:checked={settings.show_closed} />
{t('display_closed_tasks')}
</label>
</fieldset>

19
frontend/src/routes/tags/TagList.svelte

@ -7,12 +7,22 @@ @@ -7,12 +7,22 @@
import Editor from '../../Components/LineEditor.svelte';
let { module, id, user_list = [] } = $props();
let {
id = null,
module,
tags = $bindable([]),
user_list = [],
} = $props();
let error = $state(null);
let newTag = $state('');
let tags = $state([]);
async function addTag(tag){
if (!id) {
// when creating elements, they don`t have an id, yet
tags.push(tag);
tags = tags.sort();
return;
}
const url = api(`tags/${module}/${id}`);
const resp = await fetch(url,{
credentials:'include',
@ -30,6 +40,10 @@ @@ -30,6 +40,10 @@
}
async function drop(tag){
if (!id){ // then creating new elements, the don`t have an id, yet
tags = tags.filter(item => item !== tag);
return;
}
const url = api(`tags/${module}/${id}`);
const resp = await fetch(url,{
credentials:'include',
@ -46,6 +60,7 @@ @@ -46,6 +60,7 @@
}
async function loadTags(entityId){
if (!entityId) return; // when crating elements, they dont`t have an id, yet.
const url = api(`tags/${module}/${entityId}`);
const resp = await fetch(url,{credentials:'include'});
if (resp.ok) {

19
project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java

@ -20,11 +20,14 @@ import de.srsoftware.tools.SessionToken; @@ -20,11 +20,14 @@ import de.srsoftware.tools.SessionToken;
import de.srsoftware.umbrella.core.BaseHandler;
import de.srsoftware.umbrella.core.api.CompanyService;
import de.srsoftware.umbrella.core.api.ProjectService;
import de.srsoftware.umbrella.core.api.TagService;
import de.srsoftware.umbrella.core.api.UserService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.core.model.*;
import java.io.IOException;
import java.util.*;
import org.json.JSONArray;
import org.json.JSONObject;
public class ProjectModule extends BaseHandler implements ProjectService {
@ -32,12 +35,14 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -32,12 +35,14 @@ public class ProjectModule extends BaseHandler implements ProjectService {
private final ProjectDb projects;
private final CompanyService companies;
private final UserService users;
private final TagService tags;
public ProjectModule(Configuration config, CompanyService companyService) throws UmbrellaException {
public ProjectModule(Configuration config, CompanyService companyService, TagService tagService) throws UmbrellaException {
var dbFile = config.get(CONFIG_DATABASE).orElseThrow(() -> missingFieldException(CONFIG_DATABASE));
projects = new SqliteDb(connect(dbFile));
companies = companyService;
users = companies.userService();
projects = new SqliteDb(connect(dbFile));
companies = companyService;
tags = tagService;
users = companies.userService();
}
private void addMember(Project project, long userId) {
@ -245,6 +250,12 @@ public class ProjectModule extends BaseHandler implements ProjectService { @@ -245,6 +250,12 @@ public class ProjectModule extends BaseHandler implements ProjectService {
var owner = Map.of(user.id(),new Member(user,OWNER));
var prj = new Project(0,name,description, OPEN,companyId,showClosed, owner);
prj = projects.save(prj);
if (json.has(TAGS) && json.get(TAGS) instanceof JSONArray arr){
var tagList = arr.toList().stream().filter(elem -> elem instanceof String).map(String.class::cast).toList();
tags.save(PROJECT,prj.id(),null,tagList);
}
return sendContent(ex,prj);
}

8
tags/src/main/java/de/srsoftware/umbrella/tags/SqliteDb.java

@ -130,8 +130,12 @@ CREATE TABLE IF NOT EXISTS "{0}" ( @@ -130,8 +130,12 @@ CREATE TABLE IF NOT EXISTS "{0}" (
public void save(Collection<Long> userIds, String module, long entityId, Collection<String> tags) {
try {
var query = replaceInto(TABLE_TAGS,USER_ID,MODULE,ID,TAG);
for (var userId : userIds) {
for (var tag : tags) query.values(userId,module,entityId,tag);
for (var tag : tags) {
if (userIds == null) { // tags not assigned to a user are available to all users
query.values(null, module, entityId, tag);
} else for (var userId : userIds) {
query.values(userId,module,entityId,tag);
}
}
query.execute(db).close();
} catch (SQLException e){

Loading…
Cancel
Save