diff --git a/src/App.svelte b/src/App.svelte index 6257257b..3e30b8ad 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -56,6 +56,7 @@ import { register as registerSW } from "./swmodule"; import TeamDetail from "./components/teams/TeamDetail.svelte"; import UserPermissions from "./components/users/UserPermissions.svelte"; + import GroupPermissions from "./components/groups/GroupPermissions.svelte"; import RunnerDetail from "./components/runners/RunnerDetail.svelte"; import Imprint from "./components/general/Imprint.svelte"; import Privacy from "./components/general/Privacy.svelte"; @@ -63,9 +64,11 @@ import Contacts from "./components/contacts/Contacts.svelte"; import ContactDetail from "./components/contacts/ContactDetail.svelte"; import Donors from "./components/donors/Donors.svelte"; + import Groups from "./components/groups/Groups.svelte"; import DonorDetail from "./components/donors/DonorDetail.svelte"; import Donations from "./components/donations/Donations.svelte"; import DonationDetail from "./components/donations/DonationDetail.svelte"; + import GroupDetail from "./components/groups/GroupDetail.svelte"; store.init(); registerSW(); @@ -110,6 +113,19 @@ + + + + + + + + + + + + + diff --git a/src/components/dashboard/Dashboard.svelte b/src/components/dashboard/Dashboard.svelte index b46e0615..4c66b23c 100644 --- a/src/components/dashboard/Dashboard.svelte +++ b/src/components/dashboard/Dashboard.svelte @@ -54,125 +54,142 @@ {/if} {#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')} - - - {$_('users')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')} - - - - {$_('runners')} - - {/if} - {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')} - - - {$_('teams')} - -{/if} -{#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')} - - - - {$_('donors')} - -{/if} -{#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} - - - - {$_('donations')} - -{/if} -{#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')} - - {$_('tracks')} - + class:bg-gray-100={$router.path === '/users/'} + class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900" + href="/users/"> + + + {$_('users')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:GET')} + + + {$_('user-groups')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:GET')} + + + + {$_('runners')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')} + + + {$_('teams')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('DONOR:GET')} + + + + {$_('donors')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('DONATION:GET')} + + + + {$_('donations')} + + {/if} + {#if store.state.jwtinfo.userdetails.permissions.includes('TRACK:GET')} + + + {$_('tracks')} + {/if} - - - {$_('contacts')} - - + + + {$_('contacts')} + + + import { _ } from "svelte-i18n"; + import { clickOutside } from "../base/outsideclick"; + import { focusTrap } from "svelte-focus-trap"; + import Toastify from "toastify-js"; + import { UserGroupService } from "@odit/lfk-client-js"; + export let modal_open; + export let current_groups; + let description_input_value; + function focus(el) { + el.focus(); + } + $: description_input_value = ""; + $: name_input_value = ""; + $: processed_last_submit = true; + $: isNameValid = name_input_value.trim().length !== 0; + $: createbtnenabled = isNameValid; + (() => { + document.onkeydown = (e) => { + e = e || window.event; + if (e.key === "Escape") { + modal_open = false; + } + if (e.keyCode === 13) { + if (createbtnenabled === true) { + createbtnenabled = false; + submit(); + } + } + }; + })(); + function submit() { + if (processed_last_submit === true) { + processed_last_submit = false; + const toast = Toastify({ + text: $_('group-is-being-added'), + duration: -1, + }).showToast(); + let postdata = { + name: name_input_value, + description: description_input_value, + }; + UserGroupService.userGroupControllerPost(postdata) + .then((result) => { + name_input_value = ""; + description_input_value = ""; + modal_open = false; + // + Toastify({ + text: $_('group-added'), + duration: 500, + backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", + }).showToast(); + current_groups.push(result); + current_groups = current_groups; + }) + .catch((err) => { + // + }) + .finally(() => { + processed_last_submit = true; + // + toast.hideToast(); + }); + } + } + + +{#if modal_open} +
{ + modal_open = false; + }}> +
+ +
+{/if} diff --git a/src/components/groups/GroupDetail.svelte b/src/components/groups/GroupDetail.svelte new file mode 100644 index 00000000..414790fb --- /dev/null +++ b/src/components/groups/GroupDetail.svelte @@ -0,0 +1,221 @@ + + +{#await promise} + {$_('loading-group-detail')} +{:then} +
+
+
+ +
+
+
+ {original_data.name} + + {#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:DELETE')} + {#if delete_triggered} + + + {/if} + {#if !delete_triggered} + + {/if} + {/if} + {#if !delete_triggered} + + {/if} + +
+ +
+ + + {#if !isGroupnameValid} + + {$_('group-name-is-required')} + + {/if} +
+
+ + +
+
+

+ {$_('permissions')} + {$_('edit-permissions')} +

+
+ +
+ {#each original_data.permissions as p} + {#if p.toLowerCase().includes(search_permission.toLowerCase())} + {p} + + {/if} + {/each} +
+
+{:catch error} + +{/await} diff --git a/src/components/groups/GroupPermissions.svelte b/src/components/groups/GroupPermissions.svelte new file mode 100644 index 00000000..8bd4714b --- /dev/null +++ b/src/components/groups/GroupPermissions.svelte @@ -0,0 +1,227 @@ + + +{#await group_promise} + +{:then user} +
+
+
+ +
+
+
+ {$_('permissions')}: + {original_data.name} + + {#if promises.length === 0} + + {:else} + + {/if} + +
+ +
+
+ {$_('verfuegbare')} +
+
+ {$_('granted')} +
+
+ +
+ {#if allpermissions.length > 0} +
+
+ {#each allpermissions as p} + {#if !(grantedPermissions.filter((o)=>p.target == o.target && p.action == o.action).length > 0)} +

+ {p.target + ':' + p.action} + +

+ {/if} + {/each} +
+
+
+
+ {#each grantedPermissions as p} +

+ {p.target + ':' + p.action} + +

+ {/each} +
+
+ {/if} +
+
+{:catch error} + +{/await} diff --git a/src/components/groups/Groups.svelte b/src/components/groups/Groups.svelte new file mode 100644 index 00000000..fb5749eb --- /dev/null +++ b/src/components/groups/Groups.svelte @@ -0,0 +1,29 @@ + + +
+ + {$_('user-groups')} + {#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:CREATE')} + + {/if} + + +
+ +{#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:CREATE')} + +{/if} diff --git a/src/components/groups/UserGroupsEmptyState.svelte b/src/components/groups/UserGroupsEmptyState.svelte new file mode 100644 index 00000000..42e08003 --- /dev/null +++ b/src/components/groups/UserGroupsEmptyState.svelte @@ -0,0 +1,12 @@ + + +
+

+ + {$_('there-are-no-groups-yet')}.
+ {$_('add-your-first-group')} +

+
\ No newline at end of file diff --git a/src/components/groups/UserGroupsOverview.svelte b/src/components/groups/UserGroupsOverview.svelte new file mode 100644 index 00000000..3af8e6d1 --- /dev/null +++ b/src/components/groups/UserGroupsOverview.svelte @@ -0,0 +1,126 @@ + + +{#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:GET')} + {#await groups_promise} + + {:then} + {#if current_groups.length === 0} + + {:else} + +
+ + + + + + + + + + {#each current_groups as group} + {#if Object.values(group) + .toString() + .toLowerCase() + .includes(searchvalue)} + + + + {#if active_deletes[group.id] === true} + + {:else} + + {/if} + + {/if} + {/each} + +
+ {$_('name')} + + {$_('description')} + + {$_('action')} +
+
+
+
+ {group.name} +
+
+
+
+ {group.description} + + + + + Details + {#if store.state.jwtinfo.userdetails.permissions.includes('USERGROUP:DELETE')} + + {/if} +
+
+ {/if} + {:catch error} +
+ + {$_('general_promise_error')} + {error} + +
+ {/await} +{/if} diff --git a/src/components/groups/groups_empty.svg b/src/components/groups/groups_empty.svg new file mode 100644 index 00000000..2b627d32 --- /dev/null +++ b/src/components/groups/groups_empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/users/AddUserModal.svelte b/src/components/users/AddUserModal.svelte index 3e04c0af..14409ddf 100644 --- a/src/components/users/AddUserModal.svelte +++ b/src/components/users/AddUserModal.svelte @@ -116,9 +116,9 @@ width="24" height="24" xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 640 512"> + d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" />

diff --git a/src/components/users/UserDetail.svelte b/src/components/users/UserDetail.svelte index 94b0b52f..6b0fa588 100644 --- a/src/components/users/UserDetail.svelte +++ b/src/components/users/UserDetail.svelte @@ -126,9 +126,9 @@ width="24" height="24" xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 640 512"> + d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" />
  • {$_('users')}
  • -

    Profile Picture

    +

    {$_('profile-picture')}

    {$_('profile-picture')} + class="ml-1 font-medium text-gray-700">{$_('active')}?

    - set the user active/ inactive + {$_('set-the-user-active-inactive')}

    @@ -307,7 +307,7 @@
    diff --git a/src/components/users/UserPermissions.svelte b/src/components/users/UserPermissions.svelte index c232d05e..92071b12 100644 --- a/src/components/users/UserPermissions.svelte +++ b/src/components/users/UserPermissions.svelte @@ -50,6 +50,7 @@ (o) => o.target + ":" + o.action !== a.target + ":" + a.action ); }); + grantedPermissions_initial = grantedPermissions; Toastify({ text: $_("permissions-updated"), duration: 2500, @@ -88,12 +89,12 @@ width="24" height="24" xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 640 512"> + d="M12 14v8H4a8 8 0 018-8zm0-1a6 6 0 110-12 6 6 0 010 12zm2.6 5.81a3.51 3.51 0 010-1.62l-1-.57 1-1.74 1 .58a3.5 3.5 0 011.4-.82V13.5h2v1.15a3.5 3.5 0 011.4.8l1-.57 1 1.74-1 .57a3.51 3.51 0 010 1.62l1 .57-1 1.74-1-.58a3.5 3.5 0 01-1.4.82v1.14h-2v-1.15a3.5 3.5 0 01-1.4-.8l-1 .57-1-1.74 1-.57zM18 17a1 1 0 100 2 1 1 0 000-2z" />
  • - {$_('users')}{$_('users')} {#each allpermissions as p} - {#if !grantedPermissions.includes(p)} + {#if !(grantedPermissions.filter((o)=>p.target == o.target && p.action == o.action).length > 0)}

    {p.target + ':' + p.action} diff --git a/src/locales/de.json b/src/locales/de.json index 8994efb7..ff10859a 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -6,8 +6,10 @@ "active": "Aktiv", "add-donation": "Sponsoring erstellen", "add-donor": "Sponsor:in erstellen", + "add-user-group": "Neue Gruppe erstellen", "add-your-first-contact": "Erstelle den ersten Kontakt", "add-your-first-donor": "Erstelle die erste Sponsor:in", + "add-your-first-group": "Erstelle die erste Gruppe", "add-your-first-organization": "Erstelle die erste Organisation", "add-your-first-runner": "Erstelle die erste Läufer:in", "add-your-first-team": "Erstelle das erste Team", @@ -61,6 +63,7 @@ "create-a-new-team": "Erstelle ein neues Team", "create-a-new-track": "Neuen Track erstellen", "create-a-new-user": "Neue Benutzer:in anlegen", + "create-a-new-user-group": "Erstelle eine neue Gruppe", "create-organization": "Organisation erstellen", "create-team": "Team erstellen", "create-track": "Track erstellen", @@ -92,11 +95,14 @@ "delete-contact": "Kontakt löschen", "delete-donation": "Sponsporing löschen", "delete-donor": "Sponsor:in löschen", + "delete-group": "Gruppe löschen", "delete-organization": "Organisation löschen", "delete-runner": "Läufer:in löschen", "delete-team": "Team Löschen", "delete-user": "Benutzer:in löschen", "dependency_name": "Name", + "description": "Beschreibung", + "description-optional": "Beschreibung (optional)", "deselect-all": "Alle abwählen", "details": "Details", "distance": "Distanz", @@ -141,7 +147,12 @@ "generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.", "go-to-login": "Zum Login", "goback": "Zur Startseite", + "granted": "Gewährt", "group": "Gruppe", + "group-added": "Gruppe hinzugefügt", + "group-is-being-added": "Gruppe wird erstellt", + "group-name-is-required": "Der Gruppenname muss angegeben werden.", + "group-updated": "Gruppe aktualisiert", "groups": "Gruppen", "home": "Start", "icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:", @@ -175,6 +186,7 @@ "minimum-lap-time-in-s": "Minimale Rundenzeit (in Sekunden)", "minimum-lap-time-must-be-a-positive-number-or-0": "Die minimale Rundenzeit muss eine positive Zahl oder 0 sein", "name": "Name", + "name-is-required": "Der Gruppenname muss angegeben werden", "new-password": "Neues Passwort", "no-contact-specified": "Kein Kontakt angegeben", "no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢", @@ -207,6 +219,7 @@ "please-provide-the-nessecary-information-to-add-a-new-donor": "Bitte mach die Notwendigen Angaben, um eine neue Sponsor:in zu erstellen", "please-provide-the-nessecary-information-to-create-a-new-donation": "Bitte gebe alle für das Sponsoring notwendigen Daten an.", "please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.", + "please-provide-the-required-information-for-creating-a-new-user-group": "Bitte gebe alle für eine neue Gruppe notwendigen Informationen an.", "please-provide-the-required-information-to-add-a-new-contact": "Bitte gebe alle nötigen Informationen an, im den neuen Kontakt zu erstellen.", "please-provide-the-required-information-to-add-a-new-organization": "Bitte gebe alle nötigen Informationen an, im die neue Organisation zu erstellen.", "please-provide-the-required-information-to-add-a-new-runner": "Bitte die benötigten Informationen angeben.", @@ -234,9 +247,12 @@ "runners-are-being-loaded": "Läufer:innen werden geladen ...", "save": "Speichern", "save-changes": "Änderungen speichern", + "search-for-permission": "Berechtigungen durchsuchen", "select-all": "Alle auswählen", "send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services", + "set-the-user-active-inactive": "Den Benutzer auf (in)aktiv setzen", "settings": "Einstellungen", + "something-about-the-group": "Infos zur Gruppe", "stats-are-being-loaded": "Die Statistiken werden geladen...", "status": "Status", "successful-password-reset": "Passwort erfolgreich zurückgesetzt!", @@ -249,6 +265,7 @@ "the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "Die angegebene Telefonnummer ist nicht korrekt.
    Bitte gebe eine Telefonnummer im internationalen Format an...", "there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.", "there-are-no-donors-yet": "Es gibt noch keine Sponsor:innen", + "there-are-no-groups-yet": "Es gibt noch keine Gruppen", "there-are-no-organizations-added-yet": "Es wurden noch keine Organisationen hinzugefügt.", "there-are-no-runners-added-yet": "Es wurden noch keine Läufer:innen hinzugefügt.", "there-are-no-teams-added-yet": "Es wurden noch keine Teams hinzugefügt.", @@ -269,10 +286,13 @@ "updated-contact": "Kontakt aktualisiert!", "updated-donor": "Sponsor:in wurde aktualisiert", "updated-organization": "Organisation wurde aktualisiert", + "updateing-group": "Gruppe wird aktualisiert...", "updating-organization": "Organisation wird aktualisiert", + "updating-permissions": "Berechtigungen werden aktualisiert...", "updating-runner": "Läufer:in wird aktualisiert.", "updating-user": "Benutzer:in wird aktualisiert...", "user-added": "Benutzer hinzugefügt", + "user-groups": "Benutzergruppen", "user-is-being-added": "Benutzer wird hinzugefügt ...", "user-updated": "Benutzer:in wurde aktualisiert", "username": "Benutzername", @@ -281,7 +301,7 @@ "valid-email-is-required": "Es wird eine valide E-Mail Adresse benötigt", "valid-international-phone-number-is-required": "Du musst eine Telefonnummer im internationalen Format angeben...", "valid-zipcode-postal-code-is-required": "Du musst eine valide Postleitzahl angeben", - "verfuegbare": "verfügbare", + "verfuegbare": "Verfügbar", "welcome_wavinghand": "Willkommen 👋", "you-can-now-use-your-new-password-to-log-in-to-your-account": "Du kannst dich jetzt mit deinem neuen Passwort anmelden! 🎉", "zip-postal-code": "Postleitzahl" diff --git a/src/locales/en.json b/src/locales/en.json index d7af7fe6..29df2791 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -6,8 +6,10 @@ "active": "Active", "add-donation": "Add donation", "add-donor": "add donor", + "add-user-group": "Add User Group", "add-your-first-contact": "Add your first contact", "add-your-first-donor": "add your first donor", + "add-your-first-group": "Add your first group", "add-your-first-organization": "Add your first organization", "add-your-first-runner": "Add your first runner", "add-your-first-team": "Add your first team", @@ -61,6 +63,7 @@ "create-a-new-team": "Create a new team", "create-a-new-track": "Create a new Track", "create-a-new-user": "Create a new User", + "create-a-new-user-group": "Create a new user group", "create-organization": "Create Organization", "create-team": "Create Team", "create-track": "Create Track", @@ -92,11 +95,14 @@ "delete-contact": "Delete Contact", "delete-donation": "Delete Donation", "delete-donor": "Delete donor", + "delete-group": "Delete Group", "delete-organization": "Delete Organization", "delete-runner": "Delete Runner", "delete-team": "Delete Team", "delete-user": "Delete User", "dependency_name": "Name", + "description": "description", + "description-optional": "Description (optional)", "deselect-all": "deselect all", "details": "Details", "distance": "Distance", @@ -141,7 +147,12 @@ "generic-ui-logic-error": "Something went wrong in the UI logic", "go-to-login": "Go To Login", "goback": "Go Home", + "granted": "granted", "group": "Group", + "group-added": "Group added", + "group-is-being-added": "Group is being added...", + "group-name-is-required": "Group name is required", + "group-updated": "group updated", "groups": "Groups", "home": "Home", "icon-image-credits": "We also want to thank these projects for illustrations and icons:", @@ -175,6 +186,7 @@ "minimum-lap-time-in-s": "minimum lap time in s", "minimum-lap-time-must-be-a-positive-number-or-0": "minimum lap time must be a positive number or 0", "name": "Name", + "name-is-required": "Name is required", "new-password": "New password", "no-contact-specified": "no contact specified", "no-license-text-could-be-found": "No license text could be found 😢", @@ -207,6 +219,7 @@ "please-provide-the-nessecary-information-to-add-a-new-donor": "Please provide the nessecary information to add a new donor", "please-provide-the-nessecary-information-to-create-a-new-donation": "Please provide the nessecary information to create a new donation", "please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file", + "please-provide-the-required-information-for-creating-a-new-user-group": "Please provide the required information for creating a new user group.", "please-provide-the-required-information-to-add-a-new-contact": "Please provide the required information to add a new contact.", "please-provide-the-required-information-to-add-a-new-organization": "Please provide the required information to add a new organization.", "please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.", @@ -234,9 +247,12 @@ "runners-are-being-loaded": "runners are being loaded...", "save": "Save", "save-changes": "Save Changes", + "search-for-permission": "Search for permission", "select-all": "select all", "send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services", + "set-the-user-active-inactive": "set the user active/ inactive", "settings": "Settings", + "something-about-the-group": "Something about the group...", "stats-are-being-loaded": "stats are being loaded...", "status": "Status", "successful-password-reset": "Successful password reset!", @@ -249,6 +265,7 @@ "the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.
    please enter a valid international number...", "there-are-no-contacts-added-yet": "There are no contacts added yet.", "there-are-no-donors-yet": "There are no donors yet", + "there-are-no-groups-yet": "There are no groups yet", "there-are-no-organizations-added-yet": "There are no organizations added yet.", "there-are-no-runners-added-yet": "There are no runners added yet.", "there-are-no-teams-added-yet": "There are no teams added yet.", @@ -269,10 +286,13 @@ "updated-contact": "Updated contact!", "updated-donor": "updated donor", "updated-organization": "updated organization", + "updateing-group": "updateing group...", "updating-organization": "updating organization", + "updating-permissions": "updating permissions...", "updating-runner": "Updating runner...", "updating-user": "updating user...", "user-added": "User added", + "user-groups": "User Groups", "user-is-being-added": "User is being added...", "user-updated": "User updated", "username": "Username",