Compare commits

..

No commits in common. "0.2.0" and "0.1.6" have entirely different histories.
0.2.0 ... 0.1.6

12 changed files with 205 additions and 268 deletions

View File

@ -2,23 +2,10 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.2.0](https://git.odit.services/lfk/frontend/compare/0.1.6...0.2.0)
- 🔒 added rendering based on permission level [`5937a0d`](https://git.odit.services/lfk/frontend/commit/5937a0d7ce970d38ddb0e4c6a02d11f8c8b53e9b)
- ❌ UserDetail - delete [`4512272`](https://git.odit.services/lfk/frontend/commit/4512272c1c2a5c861d8ac4c9908244df125dc3d9)
- 🖊 UserDetail - reactivity on edit + update functionality [`ce1f384`](https://git.odit.services/lfk/frontend/commit/ce1f3842e0f581d9e94ea6079cf223d945f7465d)
- [tmp] - disable darkmode + re-enable sw [`c7679b7`](https://git.odit.services/lfk/frontend/commit/c7679b7a67b362a7fbf796f612892bdfac50731c)
- 🕕 set manual refresh time to 2min [`be629e5`](https://git.odit.services/lfk/frontend/commit/be629e5c6b076bf9a28dcc953e97478d244d8413)
- 🐞 [tmp] - nginx.conf - disable .js file caching [`e6ac34b`](https://git.odit.services/lfk/frontend/commit/e6ac34bde8d288a45e83fc6723a2bbe952f2622a)
- update jwtinfo store on token refresh [`6356968`](https://git.odit.services/lfk/frontend/commit/63569684a392bf0c24c9c2efd7945114d1a230a5)
#### [0.1.6](https://git.odit.services/lfk/frontend/compare/0.1.5...0.1.6) #### [0.1.6](https://git.odit.services/lfk/frontend/compare/0.1.5...0.1.6)
> 10 January 2021
- ✨ UsersOverview - user delete [`f0c100a`](https://git.odit.services/lfk/frontend/commit/f0c100aee47d6a5aeb0995db79b268f33bf316e9) - ✨ UsersOverview - user delete [`f0c100a`](https://git.odit.services/lfk/frontend/commit/f0c100aee47d6a5aeb0995db79b268f33bf316e9)
- 🔒 UserDetail - added basic layout for permission change [`81c1537`](https://git.odit.services/lfk/frontend/commit/81c1537bada2c87127385d9110d48459cd1b505f) - 🔒 UserDetail - added basic layout for permission change [`81c1537`](https://git.odit.services/lfk/frontend/commit/81c1537bada2c87127385d9110d48459cd1b505f)
- 🚀RELEASE v0.1.6 [`ee01c3a`](https://git.odit.services/lfk/frontend/commit/ee01c3a059c435add68938657955cbd2c5851c50)
- 📧 UserDetail - email input [`f856c6a`](https://git.odit.services/lfk/frontend/commit/f856c6ae3792c93aee148339d89e3978db6e9293) - 📧 UserDetail - email input [`f856c6a`](https://git.odit.services/lfk/frontend/commit/f856c6ae3792c93aee148339d89e3978db6e9293)
- ✨ UserDetail multiselect layout for groups [`98ecfab`](https://git.odit.services/lfk/frontend/commit/98ecfab0325e35c5418775f7162049b56e5f332f) - ✨ UserDetail multiselect layout for groups [`98ecfab`](https://git.odit.services/lfk/frontend/commit/98ecfab0325e35c5418775f7162049b56e5f332f)
- UserDetail - placeholder for permission picker 🔒 [`b948b8c`](https://git.odit.services/lfk/frontend/commit/b948b8c1a48e5b4bc6a083139d26100ef4499970) - UserDetail - placeholder for permission picker 🔒 [`b948b8c`](https://git.odit.services/lfk/frontend/commit/b948b8c1a48e5b4bc6a083139d26100ef4499970)

View File

@ -9,7 +9,7 @@ http {
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
location ~* \.(?:ico|css|gif|jpe?g|png)$ { location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires 1y; expires 1y;
add_header Pragma public; add_header Pragma public;
add_header Cache-Control "public"; add_header Cache-Control "public";

View File

@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.2.0", "version": "0.1.6",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",
"dev": "snowpack dev", "dev": "snowpack dev",

View File

@ -13,7 +13,7 @@
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.2.0-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.1.6-RELEASE_INFO</span>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/env.js"></script> <script src="/env.js"></script>
<script defer type="module" src="/_dist_/index.js"></script> <script defer type="module" src="/_dist_/index.js"></script>

View File

@ -49,7 +49,7 @@
OpenAPI.BASE = config.baseurl; OpenAPI.BASE = config.baseurl;
import { register as registerSW } from "./swmodule"; import { register as registerSW } from "./swmodule";
store.init(); store.init();
registerSW(); // registerSW();
</script> </script>
<Route> <Route>

View File

@ -2,7 +2,7 @@
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick"; import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap"; import { focusTrap } from "svelte-focus-trap";
import { tracks as usersstore } from "../store.js"; import { tracks as tracksstore } from "../store.js";
import { UserService } from "@odit/lfk-client-js"; import { UserService } from "@odit/lfk-client-js";
import isEmail from "validator/es/lib/isEmail"; import isEmail from "validator/es/lib/isEmail";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
@ -68,11 +68,11 @@
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
let storeval = []; let storeval = [];
usersstore.subscribe((val) => { tracksstore.subscribe((val) => {
storeval = val; storeval = val;
}); });
storeval.push(result); storeval.push(result);
usersstore.set(storeval); tracksstore.set(storeval);
}) })
.catch((err) => { .catch((err) => {
// //

View File

@ -1,12 +1,9 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
$: releaseinfo = ""; const releaseinfo = document
setTimeout(() => { .getElementById("buildinfo")
releaseinfo = document .textContent.replace("RELEASE_INFO-", "")
.getElementById("buildinfo") .replace("-RELEASE_INFO", "");
.textContent.replace("RELEASE_INFO-", "")
.replace("-RELEASE_INFO", "");
}, 1500);
const year = new Date().getFullYear(); const year = new Date().getFullYear();
</script> </script>

View File

@ -1,50 +1,28 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import lodashIsEqual from "lodash.isequal"; import lodashIsEqual from "lodash.isequal";
import store from "../store";
import { UserService } from "@odit/lfk-client-js"; import { UserService } from "@odit/lfk-client-js";
import "gridjs/dist/theme/mermaid.css"; import "gridjs/dist/theme/mermaid.css";
import PromiseError from "./PromiseError.svelte"; import PromiseError from "./PromiseError.svelte";
export let params; export let params;
const user_promise = UserService.userControllerGetOne(params.userid); const user_promise = UserService.userControllerGetOne(params.userid);
let data_loaded = false; let data_loaded = false;
$: delete_triggered = false; let original_data = undefined;
$: original_data = {};
$: editable_userdata = undefined; $: editable_userdata = undefined;
user_promise.then((data) => { user_promise.then((data) => {
data_loaded = true; data_loaded = true;
original_data = Object.assign(original_data, data); original_data = data;
editable_userdata = data; editable_userdata = data;
}); });
$: changes_performed = !lodashIsEqual(original_data, editable_userdata); // $: changes_performed = lodashIsEqual(original_data, editable_userdata);
$: changes_performed = !lodashIsEqual({ test: 1 }, { test: 1 });
function submit() { function submit() {
if (data_loaded === true && changes_performed === true) { if (data_loaded === true && changes_performed === true) {
console.log("ok, submitting..."); console.log("ok, submitting...");
console.log(editable_userdata);
UserService.userControllerPut(original_data.id, editable_userdata)
.then((resp) => {
console.log(resp);
Object.assign(original_data, editable_userdata);
original_data = editable_userdata;
Object.assign(original_data, editable_userdata);
})
.catch((err) => {
console.log(err);
});
} else { } else {
console.log("no changes performed"); console.log("no changes performed");
} }
} }
function deleteUser() {
UserService.userControllerRemove(original_data.id, true)
.then((resp) => {
console.log(resp);
location.replace("./");
})
.catch((err) => {
console.log(err);
});
}
</script> </script>
{#await user_promise} {#await user_promise}
@ -85,47 +63,36 @@
<polyline points="12 5 19 12 12 19" /></svg> <polyline points="12 5 19 12 12 19" /></svg>
</li> </li>
<li class="flex items-center"> <li class="flex items-center">
<span class="mr-2">{original_data.firstname} <span class="mr-2">{user.firstname}
{original_data.middlename || ''} {user.middlename || ''}
{original_data.lastname}</span> {user.lastname}</span>
</li> </li>
</ol> </ol>
</nav> </nav>
</div> </div>
</div> </div>
<div class="mb-8 text-3xl font-extrabold leading-tight"> <div class="mb-8 text-3xl font-extrabold leading-tight">
{original_data.firstname} {user.firstname}
{original_data.middlename || ''} {user.middlename || ''}
{original_data.lastname} {user.lastname}
<span data-id="user_actions_${editable_userdata.id}"> <span data-id="user_actions_${user.id}">
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')} <button
{#if delete_triggered} class="hidden w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-400 text-base font-medium text-white sm:w-auto sm:text-sm"
<button data-userid="${user.id}"
on:click={deleteUser} onclick="user__delete_cancel()">{$_('cancel')}</button>
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('confirm-delete')}</button> <button
<button class="hidden w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-500 text-base font-medium text-white sm:w-auto sm:text-sm"
on:click={() => { data-userid="${user.id}"
delete_triggered = !delete_triggered; onclick="user__delete_confirm()">{$_('confirm-delete')}</button>
}} <button
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-400 text-base font-medium text-white sm:w-auto sm:text-sm">{$_('cancel')}</button> type="button"
{/if} class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-user')}</button>
{#if !delete_triggered} <button
<button disabled={!changes_performed}
on:click={() => { class:opacity-50={!changes_performed}
delete_triggered = true; type="button"
}} on:click={submit}
type="button" class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('delete-user')}</button>
{/if}
{/if}
{#if !delete_triggered}
<button
disabled={!changes_performed}
class:opacity-50={!changes_performed}
type="button"
on:click={submit}
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('save-changes')}</button>
{/if}
</span> </span>
</div> </div>
@ -134,7 +101,7 @@
<img <img
alt={$_('profile-picture')} alt={$_('profile-picture')}
class="inline-block h-20 w-20 rounded-full overflow-hidden bg-gray-100" class="inline-block h-20 w-20 rounded-full overflow-hidden bg-gray-100"
src={editable_userdata.profilePic} /> src={user.profilePic} />
<!-- <span <!-- <span
class="inline-block h-12 w-12 rounded-full overflow-hidden bg-gray-100"><svg class="inline-block h-12 w-12 rounded-full overflow-hidden bg-gray-100"><svg
class="h-full w-full text-gray-300" class="h-full w-full text-gray-300"

View File

@ -1,30 +1,23 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import store from "../store";
import AddUserModal from "./AddUserModal.svelte"; import AddUserModal from "./AddUserModal.svelte";
export let modal_open = false; export let modal_open = false;
import UsersOverview from "./UsersOverview.svelte"; import UsersOverview from "./UsersOverview.svelte";
console.log(store.state.jwtinfo.userdetails.permissions);
</script> </script>
<section class="container p-5"> <section class="container p-5">
<span class="mb-1 text-3xl font-extrabold leading-tight"> <span class="mb-1 text-3xl font-extrabold leading-tight">
{$_('users')} {$_('users')}
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')} <button
<button on:click={() => {
on:click={() => { modal_open = true;
modal_open = true; }}
}} type="button"
type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm">
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:ml-3 sm:w-auto sm:text-sm"> {$_('create-user')}
{$_('create-user')} </button>
</button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500">{$_('manage-admin-users')}</p> <p class="mb-8 text-lg text-gray-500">{$_('manage-admin-users')}</p>
<UsersOverview /> <UsersOverview />
</section> </section>
<AddUserModal bind:modal_open />
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:CREATE')}
<AddUserModal bind:modal_open />
{/if}

View File

@ -5,7 +5,6 @@
const users_promise = UserService.userControllerGetAll(); const users_promise = UserService.userControllerGetAll();
import "gridjs/dist/theme/mermaid.css"; import "gridjs/dist/theme/mermaid.css";
import { users as usersstore } from "../store.js"; import { users as usersstore } from "../store.js";
import store from "../store";
import UsersEmptyState from "./UsersEmptyState.svelte"; import UsersEmptyState from "./UsersEmptyState.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
@ -20,167 +19,163 @@
}); });
</script> </script>
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:GET')} {#await users_promise}
{#await users_promise} <div
<div class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" role="alert">
role="alert"> <p class="font-bold">users are being loaded...</p>
<p class="font-bold">users are being loaded...</p> <p class="text-sm">{$_('this-might-take-a-moment')}</p>
<p class="text-sm">{$_('this-might-take-a-moment')}</p> </div>
</div> {:then users}
{:then users} {#if userscache.length === 0}
{#if userscache.length === 0} <UsersEmptyState />
<UsersEmptyState /> {:else}
{#if advanced_search}
advanced search
{:else} {:else}
<input
type="search"
bind:value={searchvalue}
placeholder={$_('datatable.search')}
aria-label={$_('datatable.search')}
class="gridjs-input gridjs-search-input mb-4" />
{/if}
<button
on:click={() => {
advanced_search = !advanced_search;
}}
type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm">
{#if advanced_search} {#if advanced_search}
advanced search toggle simple search
{:else} {:else}toggle advanced search{/if}
<input </button>
type="search" <div
bind:value={searchvalue} class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
placeholder={$_('datatable.search')} <table class="divide-y divide-gray-200 w-full">
aria-label={$_('datatable.search')} <thead class="bg-gray-50">
class="gridjs-input gridjs-search-input mb-4" /> <tr>
{/if} <th
<button scope="col"
on:click={() => { class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
advanced_search = !advanced_search; Name
}} </th>
type="button" <th
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-600 text-base font-medium text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 sm:ml-3 sm:w-auto sm:text-sm"> scope="col"
{#if advanced_search} class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
toggle simple search Status
{:else}toggle advanced search{/if} </th>
</button> <th
<div scope="col"
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"> class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
<table class="divide-y divide-gray-200 w-full"> Groups
<thead class="bg-gray-50"> </th>
<tr> <th scope="col" class="relative px-6 py-3">
<th <span class="sr-only">Action</span>
scope="col" </th>
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> </tr>
Name </thead>
</th> <tbody class="divide-y divide-gray-200">
<th {#each users as u}
scope="col" {#if Object.values(u)
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> .toString()
Status .toLowerCase()
</th> .includes(searchvalue)}
<th <tr>
scope="col" <td class="px-6 py-4 whitespace-nowrap">
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"> <div class="flex items-center">
Groups {#if u.profilePic}
</th> <div class="flex-shrink-0 h-10 w-10">
<th scope="col" class="relative px-6 py-3"> <img
<span class="sr-only">Action</span> class="h-10 w-10 rounded-full"
</th> src={u.profilePic}
</tr> alt="" />
</thead> </div>
<tbody class="divide-y divide-gray-200"> {/if}
{#each users as u} <div class="ml-4">
{#if Object.values(u) <div
.toString() class="text-sm font-medium text-gray-900 dark:text-gray-100">
.toLowerCase() {u.firstname}
.includes(searchvalue)} {u.middlename || ''}
<tr> {u.lastname}
<td class="px-6 py-4 whitespace-nowrap"> </div>
<div class="flex items-center"> <div class="text-sm text-gray-500">
{#if u.profilePic} {u.email || u.username}
<div class="flex-shrink-0 h-10 w-10">
<img
class="h-10 w-10 rounded-full"
src={u.profilePic}
alt="" />
</div>
{/if}
<div class="ml-4">
<div
class="text-sm font-medium text-gray-900 dark:text-gray-100">
{u.firstname}
{u.middlename || ''}
{u.lastname}
</div>
<div class="text-sm text-gray-500">
{u.email || u.username}
</div>
</div> </div>
</div> </div>
</td> </div>
<td class="px-6 py-4 whitespace-nowrap"> </td>
{#if u.enabled} <td class="px-6 py-4 whitespace-nowrap">
<span {#if u.enabled}
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Active</span> <span
{:else} class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Active</span>
<span
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Inactive</span>
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{#each u.groups as g}
<a
href="../groups/{g.id}"
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{g.name}</a>
{/each}
</td>
{#if active_deletes[u.id] === true}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {
active_deletes[u.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
Delete</button>
<button
on:click={() => {
UserService.userControllerRemove(u.id, true)
.then((resp) => {
console.log(resp);
// user deleted
users_promise.then((data) => {
console.log(data);
usersstore.set(data);
});
})
.catch((err) => {
// error deleting user
});
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Confirm
Delete</button>
</td>
{:else} {:else}
<td <span
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium"> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Inactive</span>
<a
href="./{u.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
<button
on:click={() => {
active_deletes[u.id] = true;
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
{/if}
</td>
{/if} {/if}
</tr> </td>
{/if} <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{/each} {#each u.groups as g}
</tbody> <a
</table> href="../groups/{g.id}"
</div> class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{g.name}</a>
{/if} {/each}
{:catch error} </td>
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500"> {#if active_deletes[u.id] === true}
<span class="inline-block align-middle mr-8"> <td
<b class="capitalize">{$_('general_promise_error')}</b> class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
{error} <button
</span> on:click={() => {
active_deletes[u.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
Delete</button>
<button
on:click={() => {
UserService.userControllerRemove(u.id, true)
.then((resp) => {
console.log(resp);
// user deleted
users_promise.then((data) => {
console.log(data);
usersstore.set(data);
});
})
.catch((err) => {
// error deleting user
});
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Confirm
Delete</button>
</td>
{:else}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<a
href="./{u.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a>
<button
on:click={() => {
active_deletes[u.id] = true;
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
</td>
{/if}
</tr>
{/if}
{/each}
</tbody>
</table>
</div> </div>
{/await} {/if}
{/if} {:catch error}
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
<span class="inline-block align-middle mr-8">
<b class="capitalize">{$_('general_promise_error')}</b>
{error}
</span>
</div>
{/await}

View File

@ -27,8 +27,6 @@ const store = () => {
AuthService.authControllerRefresh({ token: state.auth.refresh_token }).then((auth) => { AuthService.authControllerRefresh({ token: state.auth.refresh_token }).then((auth) => {
console.log('got new auth'); console.log('got new auth');
OpenAPI.TOKEN = auth.access_token; OpenAPI.TOKEN = auth.access_token;
const jwtinfo = JSON.parse(atob(auth.access_token.split('.')[1]));
state.jwtinfo = jwtinfo;
localForage.setItem('logindata', auth); localForage.setItem('logindata', auth);
}); });
}, },
@ -41,8 +39,8 @@ const store = () => {
// //
state.refreshInterval = setInterval(() => { state.refreshInterval = setInterval(() => {
this.refreshAuth(); this.refreshAuth();
// 2min // 4min
}, 2 * 60000); }, 4 * 60000);
// //
return state; return state;
}); });

View File

@ -2,7 +2,7 @@ module.exports = {
purge: { purge: {
content: [ './src/**/*.svelte' ] content: [ './src/**/*.svelte' ]
}, },
// darkMode: 'media', darkMode: 'media',
variants: {}, variants: {},
plugins: [], plugins: [],
theme: { theme: {