Merge branch 'dev' into feature/14-team-management

This commit is contained in:
Philipp Dormann 2021-01-15 20:37:30 +01:00
commit fbbbaa5d49
15 changed files with 593 additions and 93 deletions

View File

@ -2,14 +2,40 @@
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.3.0](https://git.odit.services/lfk/frontend/compare/0.2.1...0.3.0)
- Merge pull request 'feature/16-org-management' (#32) from feature/16-org-management into dev [`#16`](https://git.odit.services/lfk/frontend/issues/16)
- Merge commit 'fcd657c10ea14290455cfb0bf2de89375a664143' into dev [`#31`](https://git.odit.services/lfk/frontend/issues/31)
- ✨ added Org base components [`bdc0de6`](https://git.odit.services/lfk/frontend/commit/bdc0de6adab2db95e6075a993bd50317e9e36eb5)
- 🏬 OrgDetail ui [`7a09869`](https://git.odit.services/lfk/frontend/commit/7a09869b0ca9d5dd38cf0c0010b71ab9ce6c6f40)
- 🏁 finish basic functionality of AddOrgModal + OrgDetail [`9324925`](https://git.odit.services/lfk/frontend/commit/93249258c6b0f34da22f0ed5d290b437d221a8fd)
- ✨ basic functionality in OrgDetail [`0e2a10f`](https://git.odit.services/lfk/frontend/commit/0e2a10fe94075b3cda8ef3ebae6a6159a2e6bbf9)
- 🐞 fix sidebar mobile-md scaling [`fcd657c`](https://git.odit.services/lfk/frontend/commit/fcd657c10ea14290455cfb0bf2de89375a664143)
- 🔨 reorder CI build order for correct license exporting [`7d58657`](https://git.odit.services/lfk/frontend/commit/7d58657c800e9e494c1d1f098ad0dc34d1f0cd8d)
- 💬 AddOrgModal bindings [`bc239ee`](https://git.odit.services/lfk/frontend/commit/bc239eead1d1a29c9662d94db797c6bf23e43166)
- ✨ improvements in OrgOverview [`0b9f3de`](https://git.odit.services/lfk/frontend/commit/0b9f3de47c0c8b750c38da07e53927ba55ef3499)
- 🔨 config compatibility for new Snowpack V3 bundler [`32ffa34`](https://git.odit.services/lfk/frontend/commit/32ffa345cde67b1affe2750add620522c0a24577)
- 🧹 general component cleanup [`157c7c6`](https://git.odit.services/lfk/frontend/commit/157c7c66b57c3a5053c780682402d3615fbc046a)
- ⏫ basic dependency bump [`6fc3c16`](https://git.odit.services/lfk/frontend/commit/6fc3c16073555fffd55773218c5c2eed361f076b)
- 🌎 i18n [`01c01a4`](https://git.odit.services/lfk/frontend/commit/01c01a46faa9332a2e437861fdb42afe962da833)
- ⏫ bump gridjs to 3.2.2 [`6ff9069`](https://git.odit.services/lfk/frontend/commit/6ff90694e288356e16f5226a6e0a054e6fec8b3f)
- [tmp] - disable serviceworker [`0fa107a`](https://git.odit.services/lfk/frontend/commit/0fa107a75bc33046758bc42523262a566da9f60f)
- new license file version [CI SKIP] [`ad34e45`](https://git.odit.services/lfk/frontend/commit/ad34e455ceedc0e0ccca5ccd86f7f011a7667873)
- ⏫ Bump Dockerfile builder to 15.5.1-alpine3.12 [`01fdd0b`](https://git.odit.services/lfk/frontend/commit/01fdd0bee2199bb58373aecc9942591a2d45011a)
- new license file version [CI SKIP] [`87926e6`](https://git.odit.services/lfk/frontend/commit/87926e69dbd5b93b2c98cd68fb31913259e3cc00)
- 🐳 Dockerfile - drop js sourcemaps [`4b80f30`](https://git.odit.services/lfk/frontend/commit/4b80f30afbfb8c16b9395fb310f309c516c48a17)
#### [0.2.1](https://git.odit.services/lfk/frontend/compare/0.2.0...0.2.1) #### [0.2.1](https://git.odit.services/lfk/frontend/compare/0.2.0...0.2.1)
> 13 January 2021
- 🔒 UserDetail - WIP on Permissions [`36a084e`](https://git.odit.services/lfk/frontend/commit/36a084eab6bd0c922da29ebb2d260ba803bf9675) - 🔒 UserDetail - WIP on Permissions [`36a084e`](https://git.odit.services/lfk/frontend/commit/36a084eab6bd0c922da29ebb2d260ba803bf9675)
- 👪 UserDetail - group edit support [`a9e319e`](https://git.odit.services/lfk/frontend/commit/a9e319e0c0f2bfaba42bc3af875462e394489dc2) - 👪 UserDetail - group edit support [`a9e319e`](https://git.odit.services/lfk/frontend/commit/a9e319e0c0f2bfaba42bc3af875462e394489dc2)
- 🙋‍♂️ UserDetails - group updating [`041c24a`](https://git.odit.services/lfk/frontend/commit/041c24a837d58ff46362699b54e8088f22ba2daa) - 🙋‍♂️ UserDetails - group updating [`041c24a`](https://git.odit.services/lfk/frontend/commit/041c24a837d58ff46362699b54e8088f22ba2daa)
- ⚡ shared state reactivity - AddUserModal-Users-UsersOverview [`f7acbb1`](https://git.odit.services/lfk/frontend/commit/f7acbb1eaa14ddf41e29ff1db631520123218289) - ⚡ shared state reactivity - AddUserModal-Users-UsersOverview [`f7acbb1`](https://git.odit.services/lfk/frontend/commit/f7acbb1eaa14ddf41e29ff1db631520123218289)
- ✨ AddUserModal + UserDetail - optional username field [`7df76f9`](https://git.odit.services/lfk/frontend/commit/7df76f9642b528586fd654f27148b5502400ffdf) - ✨ AddUserModal + UserDetail - optional username field [`7df76f9`](https://git.odit.services/lfk/frontend/commit/7df76f9642b528586fd654f27148b5502400ffdf)
- UserDetail - fixed group updating [`e6fbf7a`](https://git.odit.services/lfk/frontend/commit/e6fbf7aa5b230733ffd92fdfe851b9f86001c859) - UserDetail - fixed group updating [`e6fbf7a`](https://git.odit.services/lfk/frontend/commit/e6fbf7aa5b230733ffd92fdfe851b9f86001c859)
- 🚀RELEASE v0.2.1 [`2bbaa50`](https://git.odit.services/lfk/frontend/commit/2bbaa500f4ca56e41613cac12228f4e3327180ab)
- 💬 UserDetail - info Toasts [`ea23b97`](https://git.odit.services/lfk/frontend/commit/ea23b972315db39e1f800366d52e3bacf9eaf58b) - 💬 UserDetail - info Toasts [`ea23b97`](https://git.odit.services/lfk/frontend/commit/ea23b972315db39e1f800366d52e3bacf9eaf58b)
- 🔨 optimized release script [`23c3cd6`](https://git.odit.services/lfk/frontend/commit/23c3cd605db950a5620ea709748216f7ea034385) - 🔨 optimized release script [`23c3cd6`](https://git.odit.services/lfk/frontend/commit/23c3cd605db950a5620ea709748216f7ea034385)
- 🐞 fix package release script: locales directory [`722a20e`](https://git.odit.services/lfk/frontend/commit/722a20e141079302da8876be1ccc55026c588048) - 🐞 fix package release script: locales directory [`722a20e`](https://git.odit.services/lfk/frontend/commit/722a20e141079302da8876be1ccc55026c588048)

View File

@ -1,6 +1,6 @@
{ {
"name": "@odit/lfk-frontend", "name": "@odit/lfk-frontend",
"version": "0.2.1", "version": "0.3.0",
"scripts": { "scripts": {
"i18n-order": "node order.js", "i18n-order": "node order.js",
"dev": "snowpack dev", "dev": "snowpack dev",
@ -12,7 +12,7 @@
"dependencies": { "dependencies": {
"@odit/lfk-client-js": "0.0.12", "@odit/lfk-client-js": "0.0.12",
"filepond": "4.25.1", "filepond": "4.25.1",
"gridjs": "3.2.1", "gridjs": "3.2.2",
"localforage": "1.9.0", "localforage": "1.9.0",
"lodash.isequal": "^4.5.0", "lodash.isequal": "^4.5.0",
"svelte-filepond": "0.0.1", "svelte-filepond": "0.0.1",

View File

@ -13,7 +13,7 @@
</head> </head>
<body> <body>
<span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.2.1-RELEASE_INFO</span> <span style="display: none;visibility: hidden;" id="buildinfo">RELEASE_INFO-0.3.0-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>

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,7 @@
<script> <script>
import "./TailwindStyles.svelte"; import "./TailwindStyles.svelte";
import "toastify-js/src/toastify.css"; import "toastify-js/src/toastify.css";
import "gridjs/dist/theme/mermaid.css";
import { Route, router } from "tinro"; import { Route, router } from "tinro";
router.subscribe((routeInfo) => { router.subscribe((routeInfo) => {
window.scrollTo(0, 0); window.scrollTo(0, 0);

View File

@ -0,0 +1,162 @@
<script>
import { _ } from "svelte-i18n";
import { clickOutside } from "./outsideclick";
import { focusTrap } from "svelte-focus-trap";
import { RunnerOrganisationService } from "@odit/lfk-client-js";
import Toastify from "toastify-js";
export let modal_open;
export let current_organizations;
let name_input_dom;
function focus(el) {
el.focus();
}
$: name = "";
$: processed_last_submit = true;
$: isOrgnameValid = name.trim().length !== 0;
$: createbtnenabled = isOrgnameValid;
(() => {
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: "Organization is being added...",
duration: -1,
}).showToast();
RunnerOrganisationService.runnerOrganisationControllerPost({
name,
address: undefined,
contact: undefined,
})
.then((result) => {
console.log(result);
name = "";
modal_open = false;
//
Toastify({
text: "Organization added",
duration: 500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
current_organizations = current_organizations.concat([result]);
})
.catch((err) => {
//
})
.finally(() => {
processed_last_submit = true;
//
toast.hideToast();
});
}
}
</script>
{#if modal_open}
<div
class="fixed z-10 inset-0 overflow-y-auto"
use:focusTrap
use:clickOutside
on:click_outside={() => {
modal_open = false;
}}>
<div
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div
class="absolute inset-0 bg-gray-500 opacity-75"
data-id="modal_backdrop" />
</div>
<span
class="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true">&#8203;</span>
<div
class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
role="dialog"
aria-modal="true"
aria-labelledby="modal-headline">
<div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
<div class="sm:flex sm:items-start">
<div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-blue-100 sm:mx-0 sm:h-10 sm:w-10">
<svg
class="h-6 w-6 text-blue-600"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"><path
d="M17 19h2v-8h-6v8h2v-6h2v6zM3 19V4a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v5h2v10h1v2H2v-2h1zm4-8v2h2v-2H7zm0 4v2h2v-2H7zm0-8v2h2V7H7z" /></svg>
</div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900">
Create a new Organization
</h3>
<div class="mt-2 mb-6">
<p class="text-sm text-gray-500">
Please provide the required information to add a new
organization.
</p>
</div>
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6">
<label
for="firstname"
class="block text-sm font-medium text-gray-700">Name</label>
<input
use:focus
autocomplete="off"
placeholder="Name"
class:border-red-500={!isOrgnameValid}
class:focus:border-red-500={!isOrgnameValid}
class:focus:ring-red-500={!isOrgnameValid}
bind:value={name}
bind:this={name_input_dom}
type="text"
name="firstname"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2" />
{#if !isOrgnameValid}
<span
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
Organization name is required
</span>
{/if}
</div>
</div>
</div>
</div>
</div>
<div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
<button
disabled={!createbtnenabled}
class:opacity-50={!createbtnenabled}
on:click={submit}
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">
{$_('create')}
</button>
<button
on:click={() => {
modal_open = false;
}}
type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
{$_('cancel')}
</button>
</div>
</div>
</div>
</div>
{/if}

View File

@ -2,7 +2,6 @@
import { _, json } from "svelte-i18n"; import { _, json } from "svelte-i18n";
import { getlang } from "./datatable_i18n"; import { getlang } from "./datatable_i18n";
import { Grid } from "gridjs"; import { Grid } from "gridjs";
import "gridjs/dist/theme/mermaid.css";
// //
let table; let table;
const datatable = new Grid({ const datatable = new Grid({

View File

@ -1,83 +1,205 @@
<script> <script>
import { RunnerOrganisationService } from "@odit/lfk-client-js";
import { _ } from "svelte-i18n";
import Toastify from "toastify-js";
import store from "../store";
import PromiseError from "./PromiseError.svelte";
$: delete_triggered = false;
$: save_enabled = !data_changed;
export let params; export let params;
let orgdata = {};
let original = {};
$: data_loaded = false;
$: data_changed = JSON.stringify(orgdata) === JSON.stringify(original);
const promise = RunnerOrganisationService.runnerOrganisationControllerGetOne(
params.orgid
).then((value) => {
data_loaded = true;
orgdata = Object.assign(orgdata, value);
original = Object.assign(original, value);
});
function deleteOrganisation() {
RunnerOrganisationService.runnerOrganisationControllerRemove(
original.id,
true
)
.then((resp) => {
location.replace("./");
})
.catch((err) => {});
}
function submit() {
if (data_loaded === true && save_enabled) {
Toastify({
text: "updating organization",
duration: 2500,
}).showToast();
RunnerOrganisationService.runnerOrganisationControllerPut(
original.id,
orgdata
)
.then((resp) => {
Object.assign(original, orgdata);
original = orgdata;
Object.assign(original, orgdata);
//
Toastify({
text: "updated organization",
duration: 2500,
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast();
})
.catch((err) => {});
} else {
}
}
</script> </script>
<section class="container p-5"> {#if data_loaded}
<span class="mb-1 text-3xl font-extrabold leading-tight"> <section class="container p-5">
Orgs <div class="mb-8 text-3xl font-extrabold leading-tight">
</span> {original.name}
<p class="mb-8 text-lg text-gray-500"> <span data-id="org_actions_${orgdata.id}">
configure the tracks & minimum lap times {#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
</p> {#if delete_triggered}
<div class="flex flex-row mb-4"> <button
<div class="w-full"> on:click={deleteOrganisation}
<nav class="w-full flex"> 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>
<ol class="list-none flex flex-row items-center justify-start"> <button
<li class="mr-2 flex items-center"> on:click={() => {
<svg delete_triggered = !delete_triggered;
stroke="currentColor" }}
fill="none" 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>
stroke-width="2" {/if}
viewBox="0 0 24 24" {#if !delete_triggered}
stroke-linecap="round" <button
stroke-linejoin="round" on:click={() => {
class="h-3 w-3 stroke-current" delete_triggered = true;
height="1em" }}
width="1em" type="button"
xmlns="http://www.w3.org/2000/svg"><path 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-organization')}</button>
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /> {/if}
<polyline points="9 22 9 12 15 12 15 22" /></svg> {/if}
</li> {#if !delete_triggered}
<li class="flex items-center"> <button
<a class="mr-2" href="/">Home</a><svg on:click={submit}
stroke="currentColor" disabled={!save_enabled}
fill="none" class:opacity-50={!save_enabled}
stroke-width="2" type="button"
viewBox="0 0 24 24" 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>
stroke-linecap="round" {/if}
stroke-linejoin="round" </span>
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"><line
x1="5"
y1="12"
x2="19"
y2="12" />
<polyline points="12 5 19 12 12 19" /></svg>
</li>
<li class="mr-2 flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
d="M21 20h2v2H1v-2h2V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v17zm-2 0V4H5v16h14zM8 11h3v2H8v-2zm0-4h3v2H8V7zm0 8h3v2H8v-2zm5 0h3v2h-3v-2zm0-4h3v2h-3v-2zm0-4h3v2h-3V7z" /></svg>
</li>
<li class="flex items-center">
<a class="mr-2" href="./">Orgs</a><svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"><line
x1="5"
y1="12"
x2="19"
y2="12" />
<polyline points="12 5 19 12 12 19" /></svg>
</li>
<li class="flex items-center">
<span class="mr-2">Org-Details #{params.orgid}</span>
</li>
</ol>
</nav>
</div> </div>
</div> <div class="flex flex-row mb-4">
</section> <div class="w-full">
<nav class="w-full flex">
<ol class="list-none flex flex-row items-center justify-start">
<li class="mr-2 flex items-center">
<svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"><path
d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
<polyline points="9 22 9 12 15 12 15 22" /></svg>
</li>
<li class="flex items-center">
<a class="mr-2" href="/">Home</a><svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"><line
x1="5"
y1="12"
x2="19"
y2="12" />
<polyline points="12 5 19 12 12 19" /></svg>
</li>
<li class="mr-2 flex items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"><path fill="none" d="M0 0h24v24H0z" />
<path
d="M21 20h2v2H1v-2h2V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v17zm-2 0V4H5v16h14zM8 11h3v2H8v-2zm0-4h3v2H8V7zm0 8h3v2H8v-2zm5 0h3v2h-3v-2zm0-4h3v2h-3v-2zm0-4h3v2h-3V7z" /></svg>
</li>
<li class="flex items-center">
<a class="mr-2" href="./">Orgs</a><svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="h-3 w-3 mr-2 stroke-current"
height="1em"
width="1em"
xmlns="http://www.w3.org/2000/svg"><line
x1="5"
y1="12"
x2="19"
y2="12" />
<polyline points="12 5 19 12 12 19" /></svg>
</li>
<li class="flex items-center">
<span class="mr-2">Org-Details #{params.orgid}</span>
</li>
</ol>
</nav>
</div>
</div>
<div class="text-sm w-full">
<label for="name" class="font-medium text-gray-700">Name</label>
<input
autocomplete="off"
placeholder="Name"
type="text"
bind:value={orgdata.name}
name="name"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="contact"
class="font-medium text-gray-700">{$_('contact')}</label>
<input
autocomplete="off"
placeholder={$_('contact')}
type="text"
bind:value={orgdata.contact}
name="contact"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
<div class="text-sm w-full">
<label
for="address"
class="font-medium text-gray-700">{$_('address')}</label>
<input
autocomplete="off"
placeholder={$_('address')}
type="text"
bind:value={orgdata.address}
name="address"
class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 dark:bg-gray-900 dark:text-gray-100 rounded-md p-2" />
</div>
</section>
{:else}
{#await promise}
organization detail is being loaded...
{:catch error}
<PromiseError />
{/await}
{/if}

View File

@ -0,0 +1,157 @@
<script>
import { _ } from "svelte-i18n";
import { RunnerOrganisationService } from "@odit/lfk-client-js";
import "gridjs/dist/theme/mermaid.css";
import store from "../store";
import OrgsEmptyState from "./OrgsEmptyState.svelte";
$: searchvalue = "";
$: active_deletes = [];
export let current_organizations = [];
const promise = RunnerOrganisationService.runnerOrganisationControllerGetAll().then(
(val) => {
current_organizations = val;
}
);
</script>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:GET')}
{#await promise}
<div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert">
<p class="font-bold">organizations are being loaded...</p>
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
</div>
{:then}
{#if current_organizations.length === 0}
<OrgsEmptyState />
{:else}
<input
type="search"
bind:value={searchvalue}
placeholder={$_('datatable.search')}
aria-label={$_('datatable.search')}
class="gridjs-input gridjs-search-input mb-4" />
<div
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
<table class="divide-y divide-gray-200 w-full">
<thead class="bg-gray-50">
<tr>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Name
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Address
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Contact
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Action</span>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{#each current_organizations as o}
{#if Object.values(o)
.toString()
.toLowerCase()
.includes(searchvalue)}
<tr data-rowid="org_{o.id}">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="ml-4">
<div
class="text-sm font-medium text-gray-900 dark:text-gray-100">
{o.name}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="ml-4">
<div
class="text-sm font-medium text-gray-900 dark:text-gray-100">
{#if o.address}
{JSON.stringify(o.address)}
{:else}no address specified{/if}
</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="ml-4">
<div
class="text-sm font-medium text-gray-900 dark:text-gray-100">
{#if o.contact}
{JSON.stringify(o.contact)}
{:else}no contact specified{/if}
</div>
</div>
</div>
</td>
{#if active_deletes[o.id] === true}
<td
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={() => {
active_deletes[o.id] = false;
}}
tabindex="0"
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
Delete</button>
<button
on:click={() => {
RunnerOrganisationService.runnerOrganisationControllerRemove(o.id, true)
.then((resp) => {
current_organizations = current_organizations.filter((obj) => obj.id !== o.id);
})
.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="./{o.id}"
class="text-indigo-600 hover:text-indigo-900">Edit</a>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:DELETE')}
<button
on:click={() => {
active_deletes[o.id] = true;
}}
tabindex="0"
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
{/if}
</td>
{/if}
</tr>
{/if}
{/each}
</tbody>
</table>
</div>
{/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}
{/if}

View File

@ -1,13 +1,31 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import store from "../store";
import AddOrgModal from "./AddOrgModal.svelte";
export let modal_open = false;
import OrgOverview from "./OrgOverview.svelte";
console.log(store.state.jwtinfo.userdetails.permissions);
let current_organizations = [];
</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">
Orgs {$_('organizations')}
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:CREATE')}
<button
on:click={() => {
modal_open = true;
}}
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">
{$_('create-organization')}
</button>
{/if}
</span> </span>
<p class="mb-8 text-lg text-gray-500"> <p class="mb-8 text-lg text-gray-500">manage runner organizations</p>
add, delete, edit organizations <OrgOverview bind:current_organizations />
</p>
<nav><a class="underline" href="./1">Org 1</a></nav>
</section> </section>
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANISATION:CREATE')}
<AddOrgModal bind:current_organizations bind:modal_open />
{/if}

View File

@ -0,0 +1,15 @@
<script>
import { _ } from "svelte-i18n";
import AddOrgModal from "./AddOrgModal.svelte";
let modal_open = false;
let current_organizations = [];
</script>
<div class="text-center items-center justify-center">
<p class="mb-16 text-lg text-gray-500">
<span class="font-bold">There are no organizations added yet.</span><br />
<span>Add your first organization</span>
</p>
</div>
<AddOrgModal bind:modal_open bind:current_organizations />

View File

@ -6,7 +6,6 @@
const tracks_promise = TrackService.trackControllerGetAll(); const tracks_promise = TrackService.trackControllerGetAll();
import { getlang } from "./datatable_i18n"; import { getlang } from "./datatable_i18n";
import { Grid, html } from "gridjs"; import { Grid, html } from "gridjs";
import "gridjs/dist/theme/mermaid.css";
import { tracks as tracksstore } from "../store.js"; import { tracks as tracksstore } from "../store.js";
$: trackscache = []; $: trackscache = [];
$: blocked = []; $: blocked = [];

View File

@ -7,7 +7,6 @@
UserGroupService, UserGroupService,
PermissionService, PermissionService,
} from "@odit/lfk-client-js"; } from "@odit/lfk-client-js";
import "gridjs/dist/theme/mermaid.css";
import Toastify from "toastify-js"; import Toastify from "toastify-js";
import PromiseError from "./PromiseError.svelte"; import PromiseError from "./PromiseError.svelte";
export let params; export let params;

View File

@ -1,16 +1,13 @@
<script> <script>
import { _ } from "svelte-i18n"; import { _ } from "svelte-i18n";
import Toastify from "toastify-js";
import { UserService } from "@odit/lfk-client-js"; import { UserService } from "@odit/lfk-client-js";
const users_promise = UserService.userControllerGetAll(); const users_promise = UserService.userControllerGetAll();
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 store from "../store";
import UsersEmptyState from "./UsersEmptyState.svelte"; import UsersEmptyState from "./UsersEmptyState.svelte";
$: searchvalue = ""; $: searchvalue = "";
$: active_deletes = []; $: active_deletes = [];
export let current_users=[]; export let current_users=[];
$: userscache = [];
$: advanced_search = false; $: advanced_search = false;
usersstore.subscribe((val) => { usersstore.subscribe((val) => {
userscache = val; userscache = val;

View File

@ -4,6 +4,7 @@
"about": "About", "about": "About",
"action": "Action", "action": "Action",
"add-your-first-track": "Add your first track", "add-your-first-track": "Add your first track",
"address": "Address",
"application_name": "Lauf für Kaya! - Admin", "application_name": "Lauf für Kaya! - Admin",
"author": "Author", "author": "Author",
"browse": "Browse", "browse": "Browse",
@ -13,10 +14,12 @@
"changelog": "Changelog", "changelog": "Changelog",
"close": "Close", "close": "Close",
"confirm-delete": "Confirm Delete", "confirm-delete": "Confirm Delete",
"contact": "Contact",
"count_organizations": "# Organizations", "count_organizations": "# Organizations",
"count_teams": "# Teams", "count_teams": "# Teams",
"create": "Create", "create": "Create",
"create-a-new-track": "Create a new Track", "create-a-new-track": "Create a new Track",
"create-organization": "Create Organization",
"create-user": "Create User", "create-user": "Create User",
"credits": "Credits", "credits": "Credits",
"dashboard-greeting": "hello there", "dashboard-greeting": "hello there",
@ -36,6 +39,7 @@
"no_matching_records_found": "No matching records found", "no_matching_records_found": "No matching records found",
"an_error_happened_while_fetching_the_data": "An error happened while fetching the data" "an_error_happened_while_fetching_the_data": "An error happened while fetching the data"
}, },
"delete-organization": "Delete Organization",
"delete-user": "Delete User", "delete-user": "Delete User",
"dependency_name": "Name", "dependency_name": "Name",
"dont-have-your-email-connected": "Don't have your email connected?", "dont-have-your-email-connected": "Don't have your email connected?",
@ -90,6 +94,7 @@
"minimum-lap-time-in-s": "minimum lap time in s", "minimum-lap-time-in-s": "minimum lap time in s",
"no-license-text-could-be-found": "No license text could be found 😢", "no-license-text-could-be-found": "No license text could be found 😢",
"no-tracks-added-yet": "there are no tracks added yet.", "no-tracks-added-yet": "there are no tracks added yet.",
"organizations": "Organizations",
"orgs": "Orgs", "orgs": "Orgs",
"oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!", "oss_credit_description": "We use a lot of open source software on these projects, and would like to thank the following projects and contributors who help make open source great!",
"password": "Password", "password": "Password",