Merge commit '6d0bca6d6783d3f7bbff5d413b158c6b60720bd8' into feature/48-usergroup-management
ref #48
362
LICENSE
Normal file
@ -0,0 +1,362 @@
|
|||||||
|
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Creative
|
||||||
|
Commons Corporation ("Creative Commons") is not a law firm and does not provide
|
||||||
|
legal services or legal advice. Distribution of Creative Commons public licenses
|
||||||
|
does not create a lawyer-client or other relationship. Creative Commons makes
|
||||||
|
its licenses and related information available on an "as-is" basis. Creative
|
||||||
|
Commons gives no warranties regarding its licenses, any material licensed
|
||||||
|
under their terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the fullest
|
||||||
|
extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and conditions
|
||||||
|
that creators and other rights holders may use to share original works of
|
||||||
|
authorship and other material subject to copyright and certain other rights
|
||||||
|
specified in the public license below. The following considerations are for
|
||||||
|
informational purposes only, are not exhaustive, and do not form part of our
|
||||||
|
licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are intended for use by
|
||||||
|
those authorized to give the public permission to use material in ways otherwise
|
||||||
|
restricted by copyright and certain other rights. Our licenses are irrevocable.
|
||||||
|
Licensors should read and understand the terms and conditions of the license
|
||||||
|
they choose before applying it. Licensors should also secure all rights necessary
|
||||||
|
before applying our licenses so that the public can reuse the material as
|
||||||
|
expected. Licensors should clearly mark any material not subject to the license.
|
||||||
|
This includes other CC-licensed material, or material used under an exception
|
||||||
|
or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public licenses, a licensor
|
||||||
|
grants the public permission to use the licensed material under specified
|
||||||
|
terms and conditions. If the licensor's permission is not necessary for any
|
||||||
|
reason–for example, because of any applicable exception or limitation to copyright–then
|
||||||
|
that use is not regulated by the license. Our licenses grant only permissions
|
||||||
|
under copyright and certain other rights that a licensor has authority to
|
||||||
|
grant. Use of the licensed material may still be restricted for other reasons,
|
||||||
|
including because others have copyright or other rights in the material. A
|
||||||
|
licensor may make special requests, such as asking that all changes be marked
|
||||||
|
or described. Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations for the public
|
||||||
|
: wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public
|
||||||
|
License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree to
|
||||||
|
be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike
|
||||||
|
4.0 International Public License ("Public License"). To the extent this Public
|
||||||
|
License may be interpreted as a contract, You are granted the Licensed Rights
|
||||||
|
in consideration of Your acceptance of these terms and conditions, and the
|
||||||
|
Licensor grants You such rights in consideration of benefits the Licensor
|
||||||
|
receives from making the Licensed Material available under these terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
Section 1 – Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar Rights
|
||||||
|
that is derived from or based upon the Licensed Material and in which the
|
||||||
|
Licensed Material is translated, altered, arranged, transformed, or otherwise
|
||||||
|
modified in a manner requiring permission under the Copyright and Similar
|
||||||
|
Rights held by the Licensor. For purposes of this Public License, where the
|
||||||
|
Licensed Material is a musical work, performance, or sound recording, Adapted
|
||||||
|
Material is always produced where the Licensed Material is synched in timed
|
||||||
|
relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright and Similar
|
||||||
|
Rights in Your contributions to Adapted Material in accordance with the terms
|
||||||
|
and conditions of this Public License.
|
||||||
|
|
||||||
|
c. BY-NC-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,
|
||||||
|
approved by Creative Commons as essentially the equivalent of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
d. Copyright and Similar Rights means copyright and/or similar rights closely
|
||||||
|
related to copyright including, without limitation, performance, broadcast,
|
||||||
|
sound recording, and Sui Generis Database Rights, without regard to how the
|
||||||
|
rights are labeled or categorized. For purposes of this Public License, the
|
||||||
|
rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
|
||||||
|
|
||||||
|
e. Effective Technological Measures means those measures that, in the absence
|
||||||
|
of proper authority, may not be circumvented under laws fulfilling obligations
|
||||||
|
under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996,
|
||||||
|
and/or similar international agreements.
|
||||||
|
|
||||||
|
f. Exceptions and Limitations means fair use, fair dealing, and/or any other
|
||||||
|
exception or limitation to Copyright and Similar Rights that applies to Your
|
||||||
|
use of the Licensed Material.
|
||||||
|
|
||||||
|
g. License Elements means the license attributes listed in the name of a Creative
|
||||||
|
Commons Public License. The License Elements of this Public License are Attribution,
|
||||||
|
NonCommercial, and ShareAlike.
|
||||||
|
|
||||||
|
h. Licensed Material means the artistic or literary work, database, or other
|
||||||
|
material to which the Licensor applied this Public License.
|
||||||
|
|
||||||
|
i. Licensed Rights means the rights granted to You subject to the terms and
|
||||||
|
conditions of this Public License, which are limited to all Copyright and
|
||||||
|
Similar Rights that apply to Your use of the Licensed Material and that the
|
||||||
|
Licensor has authority to license.
|
||||||
|
|
||||||
|
j. Licensor means the individual(s) or entity(ies) granting rights under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
k. NonCommercial means not primarily intended for or directed towards commercial
|
||||||
|
advantage or monetary compensation. For purposes of this Public License, the
|
||||||
|
exchange of the Licensed Material for other material subject to Copyright
|
||||||
|
and Similar Rights by digital file-sharing or similar means is NonCommercial
|
||||||
|
provided there is no payment of monetary compensation in connection with the
|
||||||
|
exchange.
|
||||||
|
|
||||||
|
l. Share means to provide material to the public by any means or process that
|
||||||
|
requires permission under the Licensed Rights, such as reproduction, public
|
||||||
|
display, public performance, distribution, dissemination, communication, or
|
||||||
|
importation, and to make material available to the public including in ways
|
||||||
|
that members of the public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
m. Sui Generis Database Rights means rights other than copyright resulting
|
||||||
|
from Directive 96/9/EC of the European Parliament and of the Council of 11
|
||||||
|
March 1996 on the legal protection of databases, as amended and/or succeeded,
|
||||||
|
as well as other essentially equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
n. You means the individual or entity exercising the Licensed Rights under
|
||||||
|
this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
Section 2 – Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License, the Licensor
|
||||||
|
hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive,
|
||||||
|
irrevocable license to exercise the Licensed Rights in the Licensed Material
|
||||||
|
to:
|
||||||
|
|
||||||
|
A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial
|
||||||
|
purposes only; and
|
||||||
|
|
||||||
|
B. produce, reproduce, and Share Adapted Material for NonCommercial purposes
|
||||||
|
only.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
|
||||||
|
and Limitations apply to Your use, this Public License does not apply, and
|
||||||
|
You do not need to comply with its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section 6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The Licensor authorizes
|
||||||
|
You to exercise the Licensed Rights in all media and formats whether now known
|
||||||
|
or hereafter created, and to make technical modifications necessary to do
|
||||||
|
so. The Licensor waives and/or agrees not to assert any right or authority
|
||||||
|
to forbid You from making technical modifications necessary to exercise the
|
||||||
|
Licensed Rights, including technical modifications necessary to circumvent
|
||||||
|
Effective Technological Measures. For purposes of this Public License, simply
|
||||||
|
making modifications authorized by this Section 2(a)(4) never produces Adapted
|
||||||
|
Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed
|
||||||
|
Material automatically receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
B. Additional offer from the Licensor – Adapted Material. Every recipient
|
||||||
|
of Adapted Material from You automatically receives an offer from the Licensor
|
||||||
|
to exercise the Licensed Rights in the Adapted Material under the conditions
|
||||||
|
of the Adapter's License You apply.
|
||||||
|
|
||||||
|
C. No downstream restrictions. You may not offer or impose any additional
|
||||||
|
or different terms or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, the Licensed Material if doing so restricts exercise of the Licensed
|
||||||
|
Rights by any recipient of the Licensed Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or may be construed
|
||||||
|
as permission to assert or imply that You are, or that Your use of the Licensed
|
||||||
|
Material is, connected with, or sponsored, endorsed, or granted official status
|
||||||
|
by, the Licensor or others designated to receive attribution as provided in
|
||||||
|
Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not licensed under this
|
||||||
|
Public License, nor are publicity, privacy, and/or other similar personality
|
||||||
|
rights; however, to the extent possible, the Licensor waives and/or agrees
|
||||||
|
not to assert any such rights held by the Licensor to the limited extent necessary
|
||||||
|
to allow You to exercise the Licensed Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to collect royalties
|
||||||
|
from You for the exercise of the Licensed Rights, whether directly or through
|
||||||
|
a collecting society under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly reserves any right
|
||||||
|
to collect such royalties, including when the Licensed Material is used other
|
||||||
|
than for NonCommercial purposes.
|
||||||
|
|
||||||
|
Section 3 – License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the following
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified form), You must:
|
||||||
|
|
||||||
|
A. retain the following if it is supplied by the Licensor with the Licensed
|
||||||
|
Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed Material and any others
|
||||||
|
designated to receive attribution, in any reasonable manner requested by the
|
||||||
|
Licensor (including by pseudonym if designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of warranties;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
|
||||||
|
|
||||||
|
B. indicate if You modified the Licensed Material and retain an indication
|
||||||
|
of any previous modifications; and
|
||||||
|
|
||||||
|
C. indicate the Licensed Material is licensed under this Public License, and
|
||||||
|
include the text of, or the URI or hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner
|
||||||
|
based on the medium, means, and context in which You Share the Licensed Material.
|
||||||
|
For example, it may be reasonable to satisfy the conditions by providing a
|
||||||
|
URI or hyperlink to a resource that includes the required information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the information required
|
||||||
|
by Section 3(a)(1)(A) to the extent reasonably practicable.
|
||||||
|
|
||||||
|
b. ShareAlike.In addition to the conditions in Section 3(a), if You Share
|
||||||
|
Adapted Material You produce, the following conditions also apply.
|
||||||
|
|
||||||
|
1. The Adapter's License You apply must be a Creative Commons license with
|
||||||
|
the same License Elements, this version or later, or a BY-NC-SA Compatible
|
||||||
|
License.
|
||||||
|
|
||||||
|
2. You must include the text of, or the URI or hyperlink to, the Adapter's
|
||||||
|
License You apply. You may satisfy this condition in any reasonable manner
|
||||||
|
based on the medium, means, and context in which You Share Adapted Material.
|
||||||
|
|
||||||
|
3. You may not offer or impose any additional or different terms or conditions
|
||||||
|
on, or apply any Effective Technological Measures to, Adapted Material that
|
||||||
|
restrict exercise of the rights granted under the Adapter's License You apply.
|
||||||
|
|
||||||
|
Section 4 – Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that apply to
|
||||||
|
Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
|
||||||
|
reuse, reproduce, and Share all or a substantial portion of the contents of
|
||||||
|
the database for NonCommercial purposes only;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database contents in
|
||||||
|
a database in which You have Sui Generis Database Rights, then the database
|
||||||
|
in which You have Sui Generis Database Rights (but not its individual contents)
|
||||||
|
is Adapted Material, including for purposes of Section 3(b); and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share all or
|
||||||
|
a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not replace
|
||||||
|
Your obligations under this Public License where the Licensed Rights include
|
||||||
|
other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. Unless otherwise separately undertaken by the Licensor, to the extent possible,
|
||||||
|
the Licensor offers the Licensed Material as-is and as-available, and makes
|
||||||
|
no representations or warranties of any kind concerning the Licensed Material,
|
||||||
|
whether express, implied, statutory, or other. This includes, without limitation,
|
||||||
|
warranties of title, merchantability, fitness for a particular purpose, non-infringement,
|
||||||
|
absence of latent or other defects, accuracy, or the presence or absence of
|
||||||
|
errors, whether or not known or discoverable. Where disclaimers of warranties
|
||||||
|
are not allowed in full or in part, this disclaimer may not apply to You.
|
||||||
|
|
||||||
|
b. To the extent possible, in no event will the Licensor be liable to You
|
||||||
|
on any legal theory (including, without limitation, negligence) or otherwise
|
||||||
|
for any direct, special, indirect, incidental, consequential, punitive, exemplary,
|
||||||
|
or other losses, costs, expenses, or damages arising out of this Public License
|
||||||
|
or use of the Licensed Material, even if the Licensor has been advised of
|
||||||
|
the possibility of such losses, costs, expenses, or damages. Where a limitation
|
||||||
|
of liability is not allowed in full or in part, this limitation may not apply
|
||||||
|
to You.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided above
|
||||||
|
shall be interpreted in a manner that, to the extent possible, most closely
|
||||||
|
approximates an absolute disclaimer and waiver of all liability.
|
||||||
|
|
||||||
|
Section 6 – Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and Similar Rights
|
||||||
|
licensed here. However, if You fail to comply with this Public License, then
|
||||||
|
Your rights under this Public License terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under Section
|
||||||
|
6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided it is cured
|
||||||
|
within 30 days of Your discovery of the violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any right the
|
||||||
|
Licensor may have to seek remedies for Your violations of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the Licensed Material
|
||||||
|
under separate terms or conditions or stop distributing the Licensed Material
|
||||||
|
at any time; however, doing so will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
||||||
|
|
||||||
|
Section 7 – Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different terms or
|
||||||
|
conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the Licensed
|
||||||
|
Material not stated herein are separate from and independent of the terms
|
||||||
|
and conditions of this Public License.
|
||||||
|
|
||||||
|
Section 8 – Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and shall not
|
||||||
|
be interpreted to, reduce, limit, restrict, or impose conditions on any use
|
||||||
|
of the Licensed Material that could lawfully be made without permission under
|
||||||
|
this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is deemed
|
||||||
|
unenforceable, it shall be automatically reformed to the minimum extent necessary
|
||||||
|
to make it enforceable. If the provision cannot be reformed, it shall be severed
|
||||||
|
from this Public License without affecting the enforceability of the remaining
|
||||||
|
terms and conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no failure
|
||||||
|
to comply consented to unless expressly agreed to by the Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted as a limitation
|
||||||
|
upon, or waiver of, any privileges and immunities that apply to the Licensor
|
||||||
|
or You, including from the legal processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public licenses. Notwithstanding, Creative
|
||||||
|
Commons may elect to apply one of its public licenses to material it publishes
|
||||||
|
and in those instances will be considered the "Licensor." The text of the
|
||||||
|
Creative Commons public licenses is dedicated to the public domain under the
|
||||||
|
CC0 Public Domain Dedication. Except for the limited purpose of indicating
|
||||||
|
that material is shared under a Creative Commons public license or as otherwise
|
||||||
|
permitted by the Creative Commons policies published at creativecommons.org/policies,
|
||||||
|
Creative Commons does not authorize the use of the trademark "Creative Commons"
|
||||||
|
or any other trademark or logo of Creative Commons without its prior written
|
||||||
|
consent including, without limitation, in connection with any unauthorized
|
||||||
|
modifications to any of its public licenses or any other arrangements, understandings,
|
||||||
|
or agreements concerning use of licensed material. For the avoidance of doubt,
|
||||||
|
this paragraph does not form part of the public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
@ -11,15 +11,14 @@
|
|||||||
"release": "release-it",
|
"release": "release-it",
|
||||||
"licenses:export": "license-exporter --json -o public"
|
"licenses:export": "license-exporter --json -o public"
|
||||||
},
|
},
|
||||||
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@odit/lfk-client-js": "0.4.5",
|
"@odit/lfk-client-js": "0.4.5",
|
||||||
"csvtojson": "^2.0.10",
|
"csvtojson": "^2.0.10",
|
||||||
"filepond": "4.25.1",
|
|
||||||
"gridjs": "3.3.0",
|
"gridjs": "3.3.0",
|
||||||
"localforage": "1.9.0",
|
"localforage": "1.9.0",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"marked": "^2.0.0",
|
"marked": "^2.0.0",
|
||||||
"svelte-filepond": "0.0.1",
|
|
||||||
"svelte-focus-trap": "1.0.1",
|
"svelte-focus-trap": "1.0.1",
|
||||||
"svelte-i18n": "3.3.2",
|
"svelte-i18n": "3.3.2",
|
||||||
"svelte-select": "^3.16.1",
|
"svelte-select": "^3.16.1",
|
||||||
@ -30,7 +29,7 @@
|
|||||||
"xlsx": "^0.16.9"
|
"xlsx": "^0.16.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@odit/license-exporter": "0.0.9",
|
"@odit/license-exporter": "^0.0.10",
|
||||||
"@snowpack/plugin-svelte": "3.5.2",
|
"@snowpack/plugin-svelte": "3.5.2",
|
||||||
"auto-changelog": "^2.2.1",
|
"auto-changelog": "^2.2.1",
|
||||||
"autoprefixer": "10.2.4",
|
"autoprefixer": "10.2.4",
|
||||||
|
@ -28,33 +28,33 @@
|
|||||||
description: "LfK! admin dashbaord",
|
description: "LfK! admin dashbaord",
|
||||||
});
|
});
|
||||||
//
|
//
|
||||||
import Login from "./components/Login.svelte";
|
import Login from "./components/auth/Login.svelte";
|
||||||
import Dashboard from "./components/Dashboard.svelte";
|
import Dashboard from "./components/dashboard/Dashboard.svelte";
|
||||||
import store from "./store.js";
|
import store from "./store.js";
|
||||||
import ForgotPassword from "./components/ForgotPassword.svelte";
|
import ForgotPassword from "./components/auth/ForgotPassword.svelte";
|
||||||
import MainDashContent from "./components/MainDashContent.svelte";
|
import MainDashContent from "./components/dashboard/MainDashContent.svelte";
|
||||||
import Users from "./components/Users.svelte";
|
import Users from "./components/users/Users.svelte";
|
||||||
import About from "./components/About.svelte";
|
import About from "./components/general/About.svelte";
|
||||||
import Settings from "./components/Settings.svelte";
|
import Settings from "./components/general/Settings.svelte";
|
||||||
import Transition from "./components/Transition.svelte";
|
import Transition from "./components/base/Transition.svelte";
|
||||||
import Orgs from "./components/Orgs.svelte";
|
import Orgs from "./components/orgs/Orgs.svelte";
|
||||||
import Runners from "./components/Runners.svelte";
|
import Runners from "./components/runners/Runners.svelte";
|
||||||
import Footer from "./components/Footer.svelte";
|
import Footer from "./components/general/Footer.svelte";
|
||||||
import TracksOverview from "./components/TracksOverview.svelte";
|
import TracksOverview from "./components/tracks/TracksOverview.svelte";
|
||||||
import OrgDetail from "./components/OrgDetail.svelte";
|
import OrgDetail from "./components/orgs/OrgDetail.svelte";
|
||||||
import Teams from "./components/Teams.svelte";
|
import Teams from "./components/teams/Teams.svelte";
|
||||||
import { OpenAPI } from "@odit/lfk-client-js";
|
import { OpenAPI } from "@odit/lfk-client-js";
|
||||||
import UserDetail from "./components/UserDetail.svelte";
|
import UserDetail from "./components/users/UserDetail.svelte";
|
||||||
OpenAPI.BASE = config.baseurl;
|
OpenAPI.BASE = config.baseurl;
|
||||||
import { register as registerSW } from "./swmodule";
|
import { register as registerSW } from "./swmodule";
|
||||||
import TeamDetail from "./components/TeamDetail.svelte";
|
import TeamDetail from "./components/teams/TeamDetail.svelte";
|
||||||
import UserPermissions from "./components/UserPermissions.svelte";
|
import UserPermissions from "./components/users/UserPermissions.svelte";
|
||||||
import RunnerDetail from "./components/RunnerDetail.svelte";
|
import RunnerDetail from "./components/runners/RunnerDetail.svelte";
|
||||||
import Imprint from "./components/Imprint.svelte";
|
import Imprint from "./components/general/Imprint.svelte";
|
||||||
import Privacy from "./components/Privacy.svelte";
|
import Privacy from "./components/general/Privacy.svelte";
|
||||||
import ResetPassword from "./components/ResetPassword.svelte";
|
import ResetPassword from "./components/auth/ResetPassword.svelte";
|
||||||
import Groups from "./components/Groups.svelte";
|
import Contacts from "./components/contacts/Contacts.svelte";
|
||||||
import GroupDetail from "./components/GroupDetail.svelte";
|
import ContactDetail from "./components/contacts/ContactDetail.svelte";
|
||||||
store.init();
|
store.init();
|
||||||
registerSW();
|
registerSW();
|
||||||
</script>
|
</script>
|
||||||
@ -113,14 +113,6 @@ import GroupDetail from "./components/GroupDetail.svelte";
|
|||||||
<RunnerDetail {params} />
|
<RunnerDetail {params} />
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/groups/*">
|
|
||||||
<Route path="/">
|
|
||||||
<Groups />
|
|
||||||
</Route>
|
|
||||||
<Route path="/:groupid" let:params>
|
|
||||||
<GroupDetail {params} />
|
|
||||||
</Route>
|
|
||||||
</Route>
|
|
||||||
<Route path="/teams/*">
|
<Route path="/teams/*">
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<Teams />
|
<Teams />
|
||||||
@ -129,6 +121,14 @@ import GroupDetail from "./components/GroupDetail.svelte";
|
|||||||
<TeamDetail {params} />
|
<TeamDetail {params} />
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/contacts/*">
|
||||||
|
<Route path="/">
|
||||||
|
<Contacts />
|
||||||
|
</Route>
|
||||||
|
<Route path="/:contact" let:params>
|
||||||
|
<ContactDetail {params} />
|
||||||
|
</Route>
|
||||||
|
</Route>
|
||||||
<Route path="/orgs/*">
|
<Route path="/orgs/*">
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<Orgs />
|
<Orgs />
|
||||||
|
@ -1,162 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { _ } from "svelte-i18n";
|
|
||||||
import { clickOutside } from "./outsideclick";
|
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
|
||||||
import { RunnerOrganizationService } 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();
|
|
||||||
RunnerOrganizationService.runnerOrganizationControllerPost({
|
|
||||||
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">​</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}
|
|
@ -1,74 +0,0 @@
|
|||||||
<script>
|
|
||||||
import "filepond/dist/filepond.css";
|
|
||||||
import FilePond from "svelte-filepond";
|
|
||||||
import { _ } from "svelte-i18n";
|
|
||||||
let pond;
|
|
||||||
// pond.getFiles() will return the active files
|
|
||||||
// the name to use for the internal file input
|
|
||||||
let name = "filepond";
|
|
||||||
function handleInit() {
|
|
||||||
// console.log("FilePond has initialised");
|
|
||||||
}
|
|
||||||
function handleAddFile(err, fileItem) {
|
|
||||||
// console.log("A file has been added", fileItem);
|
|
||||||
}
|
|
||||||
const labelInvalidField = $_("filepond__field-contains-invalid-files");
|
|
||||||
const labelFileWaitingForSize = $_("filepond__waiting-for-size");
|
|
||||||
const labelFileSizeNotAvailable = $_("filepond__size-not-available");
|
|
||||||
const labelFileLoading = $_("filepond__loading");
|
|
||||||
const labelFileLoadError = $_("filepond__error-during-load");
|
|
||||||
const labelFileProcessing = $_("filepond__uploading");
|
|
||||||
const labelFileProcessingComplete = $_("filepond__upload-complete");
|
|
||||||
const labelFileProcessingAborted = $_("filepond__upload-cancelled");
|
|
||||||
const labelFileProcessingError = $_("filepond__error-during-upload");
|
|
||||||
const labelFileProcessingRevertError = $_("filepond__error-during-revert");
|
|
||||||
const labelFileRemoveError = $_("filepond__error-during-remove");
|
|
||||||
const labelTapToCancel = $_("filepond__tap-to-cancel");
|
|
||||||
const labelTapToRetry = $_("filepond__tap-to-retry");
|
|
||||||
const labelTapToUndo = $_("filepond__tap-to-undo");
|
|
||||||
const labelButtonRemoveItem = $_("filepond__remove");
|
|
||||||
const labelButtonAbortItemLoad = $_("filepond__abort");
|
|
||||||
const labelButtonRetryItemLoad = $_("filepond__retry");
|
|
||||||
const labelButtonAbortItemProcessing = $_("filepond__cancel");
|
|
||||||
const labelButtonUndoItemProcessing = $_("filepond__undo");
|
|
||||||
const labelButtonRetryItemProcessing = $_("filepond__retry");
|
|
||||||
const labelButtonProcessItem = $_("filepond__upload");
|
|
||||||
const labelIdle =
|
|
||||||
$_("drag-and-drop-your-files-or") +
|
|
||||||
` <span class="filepond--label-action"> ` +
|
|
||||||
$_("browse") +
|
|
||||||
` </span>`;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="app">
|
|
||||||
<FilePond
|
|
||||||
bind:this={pond}
|
|
||||||
{name}
|
|
||||||
{labelFileWaitingForSize}
|
|
||||||
{labelFileSizeNotAvailable}
|
|
||||||
{labelFileLoading}
|
|
||||||
{labelFileLoadError}
|
|
||||||
{labelFileProcessing}
|
|
||||||
{labelFileProcessingComplete}
|
|
||||||
{labelFileProcessingAborted}
|
|
||||||
{labelFileProcessingError}
|
|
||||||
{labelFileProcessingRevertError}
|
|
||||||
{labelFileRemoveError}
|
|
||||||
{labelTapToCancel}
|
|
||||||
{labelTapToRetry}
|
|
||||||
{labelTapToUndo}
|
|
||||||
{labelButtonRemoveItem}
|
|
||||||
{labelButtonAbortItemLoad}
|
|
||||||
{labelButtonRetryItemLoad}
|
|
||||||
{labelButtonAbortItemProcessing}
|
|
||||||
{labelButtonUndoItemProcessing}
|
|
||||||
{labelButtonRetryItemProcessing}
|
|
||||||
{labelButtonProcessItem}
|
|
||||||
{labelIdle}
|
|
||||||
{labelInvalidField}
|
|
||||||
server="/api"
|
|
||||||
allowMultiple={false}
|
|
||||||
credits={false}
|
|
||||||
oninit={handleInit}
|
|
||||||
onaddfile={handleAddFile} />
|
|
||||||
</div>
|
|
@ -1,239 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
|
||||||
import { _ } from "svelte-i18n";
|
|
||||||
import Toastify from "toastify-js";
|
|
||||||
import store from "../store";
|
|
||||||
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
|
||||||
import ImportRunnerModal from "./ImportRunnerModal.svelte";
|
|
||||||
import PromiseError from "./PromiseError.svelte";
|
|
||||||
$: delete_triggered = false;
|
|
||||||
$: save_enabled = !data_changed;
|
|
||||||
export let params;
|
|
||||||
let orgdata = {};
|
|
||||||
let original = {};
|
|
||||||
$: data_loaded = false;
|
|
||||||
$: data_changed = JSON.stringify(orgdata) === JSON.stringify(original);
|
|
||||||
const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne(
|
|
||||||
params.orgid
|
|
||||||
).then((value) => {
|
|
||||||
data_loaded = true;
|
|
||||||
orgdata = Object.assign(orgdata, value);
|
|
||||||
original = Object.assign(original, value);
|
|
||||||
});
|
|
||||||
let modal_open = false;
|
|
||||||
let delete_org = {};
|
|
||||||
function deleteOrganization() {
|
|
||||||
// RunnerOrganizationService.runnerOrganizationControllerRemove(
|
|
||||||
// original.id,
|
|
||||||
// false
|
|
||||||
// )
|
|
||||||
// .then((resp) => {
|
|
||||||
// Toastify({
|
|
||||||
// text: "Organization deleted",
|
|
||||||
// duration: 500,
|
|
||||||
// backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
|
||||||
// }).showToast();
|
|
||||||
// location.replace("./");
|
|
||||||
// })
|
|
||||||
// .catch((err) => {
|
|
||||||
modal_open = true;
|
|
||||||
delete_org = original;
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
function submit() {
|
|
||||||
if (data_loaded === true && save_enabled) {
|
|
||||||
Toastify({
|
|
||||||
text: "updating organization",
|
|
||||||
duration: 2500,
|
|
||||||
}).showToast();
|
|
||||||
RunnerOrganizationService.runnerOrganizationControllerPut(
|
|
||||||
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 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export let import_modal_open = false;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<ImportRunnerModal
|
|
||||||
on:cancelDelete={(event) => {
|
|
||||||
import_modal_open = false;
|
|
||||||
}}
|
|
||||||
current_runners={[]}
|
|
||||||
passed_team={{}}
|
|
||||||
passed_orgs={[]}
|
|
||||||
passed_org={orgdata}
|
|
||||||
opened_from="OrgDetail"
|
|
||||||
bind:import_modal_open />
|
|
||||||
<ConfirmOrgDeletion bind:modal_open bind:delete_org />
|
|
||||||
{#if data_loaded}
|
|
||||||
<section class="container p-5">
|
|
||||||
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
|
||||||
{original.name}
|
|
||||||
<span data-id="org_actions_${orgdata.id}">
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
import_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">
|
|
||||||
{$_('import-runners')}
|
|
||||||
</button>
|
|
||||||
{/if}
|
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
|
|
||||||
{#if delete_triggered}
|
|
||||||
<button
|
|
||||||
on:click={deleteOrganization}
|
|
||||||
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
|
|
||||||
on:click={() => {
|
|
||||||
delete_triggered = !delete_triggered;
|
|
||||||
}}
|
|
||||||
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>
|
|
||||||
{/if}
|
|
||||||
{#if !delete_triggered}
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
delete_triggered = true;
|
|
||||||
}}
|
|
||||||
type="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-organization')}</button>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
{#if !delete_triggered}
|
|
||||||
<button
|
|
||||||
on:click={submit}
|
|
||||||
disabled={!save_enabled}
|
|
||||||
class:opacity-50={!save_enabled}
|
|
||||||
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>
|
|
||||||
{/if}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row mb-4">
|
|
||||||
<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 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 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 rounded-md p-2" />
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{:else}
|
|
||||||
{#await promise}
|
|
||||||
organization detail is being loaded...
|
|
||||||
{:catch error}
|
|
||||||
<PromiseError />
|
|
||||||
{/await}
|
|
||||||
{/if}
|
|
@ -1,5 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { _, locale } from "svelte-i18n";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div>$locale $_('hallo')</div>
|
|
@ -11,18 +11,13 @@
|
|||||||
if (isEmail(usersEmail)) {
|
if (isEmail(usersEmail)) {
|
||||||
AuthService.authControllerGetResetToken({ email: usersEmail })
|
AuthService.authControllerGetResetToken({ email: usersEmail })
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
console.log(resp);
|
|
||||||
console.log(resp.resetToken);
|
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_("mail-validation-in-progress"),
|
text: $_("mail-validation-in-progress"),
|
||||||
duration: 3500,
|
duration: 3500,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
reset_mail_sent = true;
|
reset_mail_sent = true;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {});
|
||||||
console.log(err.body.name);
|
|
||||||
console.log(err.body.message);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_("invalid-mail-reset"),
|
text: $_("invalid-mail-reset"),
|
||||||
@ -40,9 +35,7 @@
|
|||||||
{$_('application_name')}
|
{$_('application_name')}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 mb-2 text-sm text-center text-gray-900">
|
<p class="mt-2 mb-2 text-sm text-center text-gray-900">
|
||||||
Passwort-Reset Mail wurde an
|
{$_('password-reset-mail-sent', { values: { usersEmail: usersEmail } })}
|
||||||
{usersEmail}
|
|
||||||
geschickt
|
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
@ -63,7 +56,7 @@
|
|||||||
{$_('application_name')}
|
{$_('application_name')}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-6 text-sm text-center text-gray-900">
|
<p class="mt-6 text-sm text-center text-gray-900">
|
||||||
{$_('forgot_password?')}
|
{$_('forgot_password')}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 mb-2 text-sm text-center text-gray-900">
|
<p class="mt-2 mb-2 text-sm text-center text-gray-900">
|
||||||
{$_('dont-panic-were-resetting-it')}
|
{$_('dont-panic-were-resetting-it')}
|
@ -1,10 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import store from "../store.js";
|
import store from "../../store.js";
|
||||||
import localForage from "localforage";
|
import localForage from "localforage";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
store.init();
|
store.init();
|
||||||
import { OpenAPI, AuthService } from "@odit/lfk-client-js";
|
import { OpenAPI, AuthService } from "@odit/lfk-client-js";
|
||||||
import Footer from "./Footer.svelte";
|
import Footer from "../general/Footer.svelte";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
// ------
|
// ------
|
||||||
let username = "demo";
|
let username = "demo";
|
||||||
@ -136,7 +136,7 @@
|
|||||||
<a
|
<a
|
||||||
href="/forgot_password"
|
href="/forgot_password"
|
||||||
class="block w-full text-center py-2 px-3 border border-gray-300 rounded-md font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm">
|
class="block w-full text-center py-2 px-3 border border-gray-300 rounded-md font-medium hover:border-gray-400 focus:outline-none focus:border-gray-400 sm:text-sm">
|
||||||
{$_('forgot_password?')}
|
{$_('forgot_password')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -7,12 +7,12 @@
|
|||||||
<div class="w-full bg-white flex items-center justify-center ">
|
<div class="w-full bg-white flex items-center justify-center ">
|
||||||
<div class="max-w-sm m-8">
|
<div class="max-w-sm m-8">
|
||||||
<div class="text-black text-5xl md:text-15xl font-black">
|
<div class="text-black text-5xl md:text-15xl font-black">
|
||||||
Internal Error
|
{$_('internal-error')}
|
||||||
</div>
|
</div>
|
||||||
<div class="w-16 h-1 bg-purple-light my-3 md:my-6" />
|
<div class="w-16 h-1 bg-purple-light my-3 md:my-6" />
|
||||||
<p
|
<p
|
||||||
class="text-grey-darker text-2xl md:text-3xl font-light mb-8 leading-normal">
|
class="text-grey-darker text-2xl md:text-3xl font-light mb-8 leading-normal">
|
||||||
Something went wrong in the UI logic
|
{$_('generic-ui-logic-error')}
|
||||||
</p>
|
</p>
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
436
src/components/contacts/AddContactModal.svelte
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
|
import {
|
||||||
|
GroupContactService,
|
||||||
|
RunnerTeamService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
|
import isMobilePhone from "validator/es/lib/isMobilePhone";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
export let modal_open;
|
||||||
|
export let current_contacts;
|
||||||
|
$: selected_team = [];
|
||||||
|
let firstname_input;
|
||||||
|
let lastname_input;
|
||||||
|
let middlename_input;
|
||||||
|
let phone_input;
|
||||||
|
let email_input;
|
||||||
|
let address_input1;
|
||||||
|
let address_input2;
|
||||||
|
let address_zipcode;
|
||||||
|
let address_city;
|
||||||
|
let teams = [];
|
||||||
|
let orgs = [];
|
||||||
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
|
teams = val;
|
||||||
|
});
|
||||||
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||||
|
orgs = val;
|
||||||
|
});
|
||||||
|
function focus(el) {
|
||||||
|
el.focus();
|
||||||
|
}
|
||||||
|
$: middlename_input_value = "";
|
||||||
|
$: phone_input_value = "";
|
||||||
|
$: email_input_value = "";
|
||||||
|
$: lastname_input_value = "";
|
||||||
|
$: firstname_input_value = "";
|
||||||
|
$: address_input1_value = "";
|
||||||
|
$: address_input2_value = "";
|
||||||
|
$: address_zipcode_value = "";
|
||||||
|
$: address_city_value = "";
|
||||||
|
$: processed_last_submit = true;
|
||||||
|
$: address_checked = true;
|
||||||
|
$: isPhoneValidOrEmpty =
|
||||||
|
(phone_input_value.includes("+") &&
|
||||||
|
isMobilePhone(
|
||||||
|
phone_input_value
|
||||||
|
.replaceAll("(", "")
|
||||||
|
.replaceAll(")", "")
|
||||||
|
.replaceAll("-", "")
|
||||||
|
.replaceAll(" ", "")
|
||||||
|
)) ||
|
||||||
|
phone_input_value === "";
|
||||||
|
$: isEmailValidOrEmpty =
|
||||||
|
isEmail(email_input_value) || email_input_value === "";
|
||||||
|
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
||||||
|
$: isFirstnameValid = firstname_input_value.trim().length !== 0;
|
||||||
|
$: isAddress1Valid = address_input1_value.trim().length !== 0;
|
||||||
|
$: iszipcodevalid = address_zipcode_value.trim().length !== 0;
|
||||||
|
$: iscityvalid = address_city_value.trim().length !== 0;
|
||||||
|
$: createbtnenabled =
|
||||||
|
isFirstnameValid &&
|
||||||
|
isLastnameValid &&
|
||||||
|
isEmailValidOrEmpty &&
|
||||||
|
isPhoneValidOrEmpty &&
|
||||||
|
((isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
||||||
|
address_checked === false);
|
||||||
|
(() => {
|
||||||
|
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: "Contact is being added...",
|
||||||
|
duration: -1,
|
||||||
|
}).showToast();
|
||||||
|
let address = {};
|
||||||
|
if (address_checked === true) {
|
||||||
|
address = {
|
||||||
|
address1: address_input1_value,
|
||||||
|
address2: address_input2_value || "",
|
||||||
|
postalcode: address_zipcode_value,
|
||||||
|
city: address_city_value,
|
||||||
|
country: "DE",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let postdata = {
|
||||||
|
groups: selected_team,
|
||||||
|
firstname: firstname_input_value,
|
||||||
|
lastname: lastname_input_value,
|
||||||
|
address,
|
||||||
|
};
|
||||||
|
if (middlename_input_value) {
|
||||||
|
postdata.middlename = middlename_input_value;
|
||||||
|
}
|
||||||
|
if (phone_input_value) {
|
||||||
|
postdata.phone = phone_input_value;
|
||||||
|
}
|
||||||
|
if (email_input_value) {
|
||||||
|
postdata.email = email_input_value;
|
||||||
|
}
|
||||||
|
GroupContactService.groupContactControllerPost(postdata)
|
||||||
|
.then((result) => {
|
||||||
|
firstname_input_value = "";
|
||||||
|
lastname_input_value = "";
|
||||||
|
middlename_input_value = "";
|
||||||
|
email_input_value = "";
|
||||||
|
modal_open = false;
|
||||||
|
//
|
||||||
|
Toastify({
|
||||||
|
text: "Contact added",
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
current_contacts.push(result);
|
||||||
|
current_contacts = current_contacts;
|
||||||
|
})
|
||||||
|
.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">​</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 fill="none" d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z" /></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-contact')}
|
||||||
|
</h3>
|
||||||
|
<div class="mt-2 mb-6">
|
||||||
|
<p class="text-sm text-gray-500">
|
||||||
|
{$_('please-provide-the-required-information-to-add-a-new-contact')}
|
||||||
|
</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">{$_('first-name')}</label>
|
||||||
|
<input
|
||||||
|
use:focus
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('first-name')}
|
||||||
|
class:border-red-500={!isFirstnameValid}
|
||||||
|
class:focus:border-red-500={!isFirstnameValid}
|
||||||
|
class:focus:ring-red-500={!isFirstnameValid}
|
||||||
|
bind:value={firstname_input_value}
|
||||||
|
bind:this={firstname_input}
|
||||||
|
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 !isFirstnameValid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('first-name-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="trackname"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('middle-name')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('middle-name')}
|
||||||
|
bind:value={middlename_input_value}
|
||||||
|
bind:this={middlename_input}
|
||||||
|
type="text"
|
||||||
|
name="trackname"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="lastname"
|
||||||
|
class="block text-sm font-medium text-gray-700">Last Name</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Last Name"
|
||||||
|
class:border-red-500={!isLastnameValid}
|
||||||
|
class:focus:border-red-500={!isLastnameValid}
|
||||||
|
class:focus:ring-red-500={!isLastnameValid}
|
||||||
|
bind:value={lastname_input_value}
|
||||||
|
bind:this={lastname_input}
|
||||||
|
type="text"
|
||||||
|
name="lastname"
|
||||||
|
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 !isLastnameValid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('last-name-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="team"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('team')}</label>
|
||||||
|
<select
|
||||||
|
name="team"
|
||||||
|
multiple
|
||||||
|
bind:value={selected_team}
|
||||||
|
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">
|
||||||
|
{#each teams as team}
|
||||||
|
<option value={team.id}>
|
||||||
|
{team.parentGroup.name}
|
||||||
|
>
|
||||||
|
{team.name}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
{#each orgs as org}
|
||||||
|
<option value={org.id}>{org.name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="phone"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('phone')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('phone')}
|
||||||
|
class:border-red-500={!isPhoneValidOrEmpty}
|
||||||
|
class:focus:border-red-500={!isPhoneValidOrEmpty}
|
||||||
|
class:focus:ring-red-500={!isPhoneValidOrEmpty}
|
||||||
|
bind:value={phone_input_value}
|
||||||
|
bind:this={phone_input}
|
||||||
|
type="tel"
|
||||||
|
name="phone"
|
||||||
|
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 !isPhoneValidOrEmpty}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{@html $_('the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="email"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('e-mail-adress')}
|
||||||
|
class:border-red-500={!isEmailValidOrEmpty}
|
||||||
|
class:focus:border-red-500={!isEmailValidOrEmpty}
|
||||||
|
class:focus:ring-red-500={!isEmailValidOrEmpty}
|
||||||
|
bind:value={email_input_value}
|
||||||
|
bind:this={email_input}
|
||||||
|
type="email"
|
||||||
|
name="email"
|
||||||
|
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 !isEmailValidOrEmpty}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-email-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start">
|
||||||
|
<div class="flex items-center h-5">
|
||||||
|
<input
|
||||||
|
bind:checked={address_checked}
|
||||||
|
id="comments"
|
||||||
|
name="comments"
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-3 text-sm">
|
||||||
|
<label
|
||||||
|
for="comments"
|
||||||
|
class="font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if address_checked === true}
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address1"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Address"
|
||||||
|
class:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:ring-red-500={!isAddress1Valid}
|
||||||
|
bind:value={address_input1_value}
|
||||||
|
bind:this={address_input1}
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
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 !isAddress1Valid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('address-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address2"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('apartment-suite-etc')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('apartment-suite-etc')}
|
||||||
|
bind:value={address_input2_value}
|
||||||
|
bind:this={address_input2}
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="zipcode"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('zip-postal-code')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('zip-postal-code')}
|
||||||
|
class:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:ring-red-500={!iszipcodevalid}
|
||||||
|
bind:value={address_zipcode_value}
|
||||||
|
bind:this={address_zipcode}
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
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 !iszipcodevalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-zipcode-postal-code-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="city"
|
||||||
|
class="block text-sm font-medium text-gray-700">City</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="City"
|
||||||
|
class:border-red-500={!iscityvalid}
|
||||||
|
class:focus:border-red-500={!iscityvalid}
|
||||||
|
class:focus:ring-red-500={!iscityvalid}
|
||||||
|
bind:value={address_city_value}
|
||||||
|
bind:this={address_city}
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
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 !iscityvalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-city-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</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}
|
394
src/components/contacts/ContactDetail.svelte
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import store from "../../store";
|
||||||
|
import {
|
||||||
|
GroupContactService,
|
||||||
|
RunnerTeamService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
|
let data_loaded = false;
|
||||||
|
let orgs = [];
|
||||||
|
let teams = [];
|
||||||
|
export let params;
|
||||||
|
$: delete_triggered = false;
|
||||||
|
$: original_data = {};
|
||||||
|
$: editable = {};
|
||||||
|
$: changes_performed = !(
|
||||||
|
JSON.stringify(original_data) === JSON.stringify(editable)
|
||||||
|
);
|
||||||
|
$: isEmailValid =
|
||||||
|
(editable.email || "") === "" ||
|
||||||
|
(editable.email && isEmail(editable.email || ""));
|
||||||
|
$: isFirstnameValid = editable.firstname !== "";
|
||||||
|
$: isLastnameValid = editable.lastname !== "";
|
||||||
|
$: save_enabled =
|
||||||
|
changes_performed &&
|
||||||
|
isFirstnameValid &&
|
||||||
|
isLastnameValid &&
|
||||||
|
isEmailValid &&
|
||||||
|
isPhoneValidOrEmpty &&
|
||||||
|
((isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
||||||
|
editable.address_checked === false);
|
||||||
|
const promise = GroupContactService.groupContactControllerGetOne(
|
||||||
|
params.contact
|
||||||
|
).then((data) => {
|
||||||
|
data_loaded = true;
|
||||||
|
original_data = Object.assign(original_data, data);
|
||||||
|
editable = Object.assign(editable, original_data);
|
||||||
|
editable.groups = editable.groups.map((g) => g.id);
|
||||||
|
original_data.groups = original_data.groups.map((g) => g.id);
|
||||||
|
editable.address_checked = editable.address.address1 !== null;
|
||||||
|
original_data.address_checked = editable.address.address1 !== null;
|
||||||
|
if(editable.address_checked===false){
|
||||||
|
editable.address = {
|
||||||
|
address1: "",
|
||||||
|
address2: "",
|
||||||
|
city: "",
|
||||||
|
postalcode: "",
|
||||||
|
country: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||||
|
orgs = val;
|
||||||
|
});
|
||||||
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
|
teams = val;
|
||||||
|
});
|
||||||
|
$: isPhoneValidOrEmpty =
|
||||||
|
editable.phone?.includes("+") ||
|
||||||
|
editable.phone === "" ||
|
||||||
|
editable.phone === null;
|
||||||
|
$: isAddress1Valid = editable.address?.address1?.trim().length !== 0;
|
||||||
|
$: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0;
|
||||||
|
$: iscityvalid = editable.address?.city?.trim().length !== 0;
|
||||||
|
function submit() {
|
||||||
|
if (data_loaded === true && save_enabled) {
|
||||||
|
Toastify({
|
||||||
|
text: $_("contact-is-being-updated"),
|
||||||
|
duration: 2500,
|
||||||
|
}).showToast();
|
||||||
|
editable.address.country = "DE";
|
||||||
|
if (editable.address_checked === false) {
|
||||||
|
editable.address = null;
|
||||||
|
}
|
||||||
|
if (editable.email) editable.email = editable.email;
|
||||||
|
if (editable.phone) editable.phone = editable.phone;
|
||||||
|
if (editable.middlename) editable.middlename = editable.middlename;
|
||||||
|
GroupContactService.groupContactControllerPut(original_data.id, editable)
|
||||||
|
.then((resp) => {
|
||||||
|
Object.assign(original_data, editable);
|
||||||
|
original_data=original_data;
|
||||||
|
Toastify({
|
||||||
|
text: $_("updated-contact"),
|
||||||
|
duration: 2500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function deleteContact() {
|
||||||
|
GroupContactService.groupContactControllerRemove(original_data.id, true)
|
||||||
|
.then((resp) => {
|
||||||
|
location.replace("./");
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await promise}
|
||||||
|
{$_('loading-contact-details')}
|
||||||
|
{:then}
|
||||||
|
<section class="container p-5 select-none">
|
||||||
|
<div class="flex flex-row mb-4">
|
||||||
|
<div class="w-full">
|
||||||
|
<nav class="w-full flex">
|
||||||
|
<ol class="list-none flex flex-row items-center justify-start">
|
||||||
|
<li class="flex items-center">
|
||||||
|
<svg
|
||||||
|
fill="currentColor"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
height="24"><path fill="none" d="M0 0h24v24H0z" />
|
||||||
|
<path
|
||||||
|
d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z" /></svg>
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center ml-2">
|
||||||
|
<a class="mr-2" href="./">{$_('contacts')}</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">{original_data.firstname}
|
||||||
|
{original_data.middlename || ''}
|
||||||
|
{original_data.lastname}</span>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
|
{original_data.firstname}
|
||||||
|
{original_data.middlename || ''}
|
||||||
|
{original_data.lastname}
|
||||||
|
<span data-id="contact_actions_${editable.id}">
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:DELETE')}
|
||||||
|
{#if delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={deleteContact}
|
||||||
|
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-deletion')}</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
delete_triggered = !delete_triggered;
|
||||||
|
}}
|
||||||
|
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>
|
||||||
|
{/if}
|
||||||
|
{#if !delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
delete_triggered = true;
|
||||||
|
}}
|
||||||
|
type="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-contact')}</button>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{#if !delete_triggered}
|
||||||
|
<button
|
||||||
|
disabled={!save_enabled}
|
||||||
|
class:opacity-50={!save_enabled}
|
||||||
|
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>
|
||||||
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label
|
||||||
|
for="firstname"
|
||||||
|
class="font-medium text-gray-700">{$_('first-name')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('first-name')}
|
||||||
|
type="text"
|
||||||
|
class:border-red-500={!isFirstnameValid}
|
||||||
|
class:focus:border-red-500={!isFirstnameValid}
|
||||||
|
class:focus:ring-red-500={!isFirstnameValid}
|
||||||
|
bind:value={editable.firstname}
|
||||||
|
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 !isFirstnameValid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('first-name-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label
|
||||||
|
for="middlename"
|
||||||
|
class="font-medium text-gray-700">{$_('middle-name')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('middle-name')}
|
||||||
|
type="text"
|
||||||
|
bind:value={editable.middlename}
|
||||||
|
name="middlename"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label
|
||||||
|
for="lastname"
|
||||||
|
class="font-medium text-gray-700">{$_('last-name')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('last-name')}
|
||||||
|
type="text"
|
||||||
|
bind:value={editable.lastname}
|
||||||
|
class:border-red-500={!isLastnameValid}
|
||||||
|
class:focus:border-red-500={!isLastnameValid}
|
||||||
|
class:focus:ring-red-500={!isLastnameValid}
|
||||||
|
name="lastname"
|
||||||
|
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 !isLastnameValid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('last-name-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label
|
||||||
|
for="email"
|
||||||
|
class="font-medium text-gray-700">{$_('e-mail-adress')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('e-mail-adress')}
|
||||||
|
type="email"
|
||||||
|
bind:value={editable.email}
|
||||||
|
class:border-red-500={!isEmailValid}
|
||||||
|
class:focus:border-red-500={!isEmailValid}
|
||||||
|
class:focus:ring-red-500={!isEmailValid}
|
||||||
|
name="email"
|
||||||
|
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 !isEmailValid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-email-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label for="phone" class="font-medium text-gray-700">{$_('phone')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('phone')}
|
||||||
|
type="tel"
|
||||||
|
class:border-red-500={!isPhoneValidOrEmpty}
|
||||||
|
class:focus:border-red-500={!isPhoneValidOrEmpty}
|
||||||
|
class:focus:ring-red-500={!isPhoneValidOrEmpty}
|
||||||
|
bind:value={editable.phone}
|
||||||
|
name="phone"
|
||||||
|
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 !isPhoneValidOrEmpty}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-international-phone-number-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<span class="font-medium text-gray-700">{$_('groups')}</span>
|
||||||
|
<select
|
||||||
|
bind:value={editable.groups}
|
||||||
|
name="team"
|
||||||
|
multiple
|
||||||
|
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">
|
||||||
|
{#each teams as team}
|
||||||
|
<option value={team.id}>
|
||||||
|
{team.parentGroup.name}
|
||||||
|
>
|
||||||
|
{team.name}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
{#each orgs as org}
|
||||||
|
<option value={org.id}>{org.name}</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
<div class="flex items-start mt-2">
|
||||||
|
<div class="flex items-center h-5">
|
||||||
|
<input
|
||||||
|
bind:checked={editable.address_checked}
|
||||||
|
id="comments"
|
||||||
|
name="comments"
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-3 text-sm">
|
||||||
|
<label
|
||||||
|
for="comments"
|
||||||
|
class="font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if editable.address_checked === true}
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address1"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Address"
|
||||||
|
class:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:ring-red-500={!isAddress1Valid}
|
||||||
|
bind:value={editable.address.address1}
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
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 !isAddress1Valid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('address-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address2"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('apartment-suite-etc')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('apartment-suite-etc')}
|
||||||
|
bind:value={editable.address.address2}
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="zipcode"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('zip-postal-code')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('zip-postal-code')}
|
||||||
|
class:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:ring-red-500={!iszipcodevalid}
|
||||||
|
bind:value={editable.address.postalcode}
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
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 !iszipcodevalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-zipcode-postal-code-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="city"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('city')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('city')}
|
||||||
|
class:border-red-500={!iscityvalid}
|
||||||
|
class:focus:border-red-500={!iscityvalid}
|
||||||
|
class:focus:ring-red-500={!iscityvalid}
|
||||||
|
bind:value={editable.address.city}
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
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 !iscityvalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-city-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
{:catch error}
|
||||||
|
<PromiseError {error} />
|
||||||
|
{/await}
|
29
src/components/contacts/Contacts.svelte
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import store from "../../store";
|
||||||
|
import AddContactModal from "./AddContactModal.svelte";
|
||||||
|
import ContactsOverview from "./ContactsOverview.svelte";
|
||||||
|
export let modal_open = false;
|
||||||
|
let current_contacts = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="container p-5">
|
||||||
|
<span class="mb-1 text-3xl font-extrabold leading-tight">
|
||||||
|
{$_('contacts')}
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT: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-a-new-contact')}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
<ContactsOverview bind:current_contacts />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:CREATE')}
|
||||||
|
<AddContactModal bind:current_contacts bind:modal_open />
|
||||||
|
{/if}
|
17
src/components/contacts/ContactsEmptyState.svelte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import AddContactModal from "./AddContactModal.svelte";
|
||||||
|
import team_empty from "../teams/team_empty.svg";
|
||||||
|
let modal_open = false;
|
||||||
|
let current_contacts = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="text-center items-center justify-center">
|
||||||
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
|
<img class="w-full h-44" src={team_empty} alt="" />
|
||||||
|
<span class="font-bold">{$_('there-are-no-contacts-added-yet')}</span><br />
|
||||||
|
<span>{$_('add-your-first-contact')}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<AddContactModal bind:modal_open bind:current_contacts />
|
177
src/components/contacts/ContactsOverview.svelte
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import { GroupContactService } from "@odit/lfk-client-js";
|
||||||
|
const promise = GroupContactService.groupContactControllerGetAll().then(
|
||||||
|
(result) => {
|
||||||
|
current_contacts = result;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
import store from "../../store";
|
||||||
|
import ContactsEmptyState from "./ContactsEmptyState.svelte";
|
||||||
|
$: searchvalue = "";
|
||||||
|
$: active_deletes = [];
|
||||||
|
export let current_contacts = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM: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">{$_('contacts-are-being-loaded')}</p>
|
||||||
|
<p class="text-sm">{$_('this-might-take-a-moment')}</p>
|
||||||
|
</div>
|
||||||
|
{:then}
|
||||||
|
{#if current_contacts.length === 0}
|
||||||
|
<ContactsEmptyState />
|
||||||
|
{: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">
|
||||||
|
{$_('groups')}
|
||||||
|
</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="relative px-6 py-3">
|
||||||
|
<span class="sr-only">{$_('action')}</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-gray-200">
|
||||||
|
{#each current_contacts as t}
|
||||||
|
{#if Object.values(t)
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchvalue)}
|
||||||
|
<tr data-rowid="team_{t.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">
|
||||||
|
{t.firstname}
|
||||||
|
{t.middlename || ''}
|
||||||
|
{t.lastname}
|
||||||
|
</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">
|
||||||
|
{#if t.groups.length > 0}
|
||||||
|
{#each t.groups as g}
|
||||||
|
{#if g.responseType === 'RUNNERORGANIZATION'}
|
||||||
|
<a
|
||||||
|
href="../orgs/{g.id}"
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{g.name}</a>
|
||||||
|
{:else}
|
||||||
|
<a
|
||||||
|
href="../teams/{g.id}"
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{g.parentGroup.name}
|
||||||
|
>
|
||||||
|
{g.name}</a>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
{:else}
|
||||||
|
{$_('contact-is-not-a-member-in-any-group')}
|
||||||
|
{/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">
|
||||||
|
{#if t.address.address1 !== null}
|
||||||
|
{t.address.address1}<br />
|
||||||
|
{t.address.address2 || ''}<br />
|
||||||
|
{t.address.postalcode}
|
||||||
|
{t.address.city}
|
||||||
|
{t.address.country}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{#if active_deletes[t.id] === true}
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[t.id] = false;
|
||||||
|
}}
|
||||||
|
tabindex="0"
|
||||||
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
GroupContactService.groupContactControllerRemove(t.id, false).then(
|
||||||
|
(resp) => {
|
||||||
|
current_contacts = current_contacts.filter(
|
||||||
|
(obj) => obj.id !== t.id
|
||||||
|
);
|
||||||
|
Toastify({
|
||||||
|
text: $_('contact-deleted'),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor:
|
||||||
|
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||||
|
}).showToast();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
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="./{t.id}"
|
||||||
|
class="text-indigo-600 hover:text-indigo-900">{$_('edit')}</a>
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
active_deletes[t.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}
|
@ -1,11 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import localForage from "localforage";
|
import localForage from "localforage";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
import { router } from "tinro";
|
import { router } from "tinro";
|
||||||
import NoComponentLoaded from "./NoComponentLoaded.svelte";
|
import NoComponentLoaded from "../base/NoComponentLoaded.svelte";
|
||||||
import { AuthService } from "@odit/lfk-client-js";
|
import { AuthService } from "@odit/lfk-client-js";
|
||||||
let dropdown1 = false;
|
|
||||||
$: navOpen = false;
|
$: navOpen = false;
|
||||||
function logout() {
|
function logout() {
|
||||||
localForage.clear();
|
localForage.clear();
|
||||||
@ -131,6 +130,13 @@
|
|||||||
<span>UserGroups</span>
|
<span>UserGroups</span>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
|
<a
|
||||||
|
class:bg-gray-100={$router.path === '/contacts/'}
|
||||||
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
||||||
|
href="/contacts/">
|
||||||
|
<svg fill="currentColor" class="flex-shrink-0 w-5 h-5 mr-2 text-gray-400 transition group-hover:text-gray-600" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2 22a8 8 0 1 1 16 0H2zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6 6 2.685 6 6-2.685 6-6 6zm10 4h4v2h-4v-2zm-3-5h7v2h-7v-2zm2-5h5v2h-5V7z"/></svg>
|
||||||
|
<span>{$_('contacts')}</span>
|
||||||
|
</a>
|
||||||
<a
|
<a
|
||||||
class:bg-gray-100={$router.path === '/settings/'}
|
class:bg-gray-100={$router.path === '/settings/'}
|
||||||
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
class="flex items-center px-4 py-3 transition cursor-pointer group hover:bg-gray-100 hover:text-gray-900"
|
@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import StatCards from "./StatCards.svelte";
|
import StatCards from "./StatCards.svelte";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
let navOpen = false;
|
let navOpen = false;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -10,9 +10,9 @@
|
|||||||
on:click={() => {
|
on:click={() => {
|
||||||
navOpen = false;
|
navOpen = false;
|
||||||
}}>
|
}}>
|
||||||
<!-- <div class="border-4 border-dashed rounded h-96" /> -->
|
|
||||||
<h1 class="text-3xl leading-tight">
|
<h1 class="text-3xl leading-tight">
|
||||||
<span class="font-extrabold">{$_('dashboard-title')}</span> <span>
|
<span class="font-extrabold">{$_('dashboard-title')}</span>
|
||||||
|
<span>
|
||||||
-
|
-
|
||||||
{$_('dashboard-greeting')},
|
{$_('dashboard-greeting')},
|
||||||
<span
|
<span
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
export let modal_open;
|
export let modal_open;
|
||||||
(function () {
|
(function () {
|
@ -1,11 +1,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _, getLocaleFromNavigator } from "svelte-i18n";
|
import { _, getLocaleFromNavigator } from "svelte-i18n";
|
||||||
import * as css from "./simple.css";
|
|
||||||
import marked from "marked";
|
import marked from "marked";
|
||||||
import Footer from "./Footer.svelte";
|
import Footer from "./Footer.svelte";
|
||||||
|
import * as css from "../base/simple.css";
|
||||||
let html = "";
|
let html = "";
|
||||||
async function load() {
|
async function load() {
|
||||||
let md = await fetch("/imprint_" + getLocaleFromNavigator() + ".md");
|
let md = await fetch("/imprint_" + getLocaleFromNavigator() + ".md");
|
||||||
|
if((await md.text()).includes("<meta")){
|
||||||
|
md.ok=false
|
||||||
|
}
|
||||||
if (!md.ok) {
|
if (!md.ok) {
|
||||||
md = await fetch("/imprint_en.md");
|
md = await fetch("/imprint_en.md");
|
||||||
}
|
}
|
@ -1,11 +1,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _, getLocaleFromNavigator } from "svelte-i18n";
|
import { _, getLocaleFromNavigator } from "svelte-i18n";
|
||||||
import * as css from "./simple.css";
|
|
||||||
import marked from "marked";
|
import marked from "marked";
|
||||||
import Footer from "./Footer.svelte";
|
import Footer from "./Footer.svelte";
|
||||||
|
import * as css from "../base/simple.css";
|
||||||
let html = "";
|
let html = "";
|
||||||
async function load() {
|
async function load() {
|
||||||
let md = await fetch("/privacy_" + getLocaleFromNavigator() + ".md");
|
let md = await fetch("/privacy_" + getLocaleFromNavigator() + ".md");
|
||||||
|
if((await md.text()).includes("<meta")){
|
||||||
|
md.ok=false
|
||||||
|
}
|
||||||
if (!md.ok) {
|
if (!md.ok) {
|
||||||
md = await fetch("/privacy_en.md");
|
md = await fetch("/privacy_en.md");
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import FormLayout from "./FormLayout.svelte";
|
import FormLayout from "../base/FormLayout.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="pt-12 px-4 sm:px-6 lg:px-8 lg:pt-20 bg-gray-900 pb-12">
|
<div class="pt-12 px-4 sm:px-6 lg:px-8 lg:pt-20 bg-gray-900 pb-12">
|
||||||
@ -32,4 +32,4 @@ import FormLayout from "./FormLayout.svelte";
|
|||||||
</div>
|
</div>
|
||||||
<FormLayout />
|
<FormLayout />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
281
src/components/orgs/AddOrgModal.svelte
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
<script>
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import { clickOutside } from "../base/outsideclick";
|
||||||
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
|
import { RunnerOrganizationService } 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;
|
||||||
|
$: isAddress1Valid = address_input1_value.trim().length !== 0;
|
||||||
|
$: iszipcodevalid = address_zipcode_value.trim().length !== 0;
|
||||||
|
$: iscityvalid = address_city_value.trim().length !== 0;
|
||||||
|
$: createbtnenabled =
|
||||||
|
isOrgnameValid &&
|
||||||
|
((isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
||||||
|
address_checked === false);
|
||||||
|
$: address_input1_value = "";
|
||||||
|
$: address_input2_value = "";
|
||||||
|
$: address_zipcode_value = "";
|
||||||
|
$: address_city_value = "";
|
||||||
|
$: address_checked = true;
|
||||||
|
|
||||||
|
let address_input1;
|
||||||
|
let address_input2;
|
||||||
|
let address_zipcode;
|
||||||
|
let address_city;
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
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();
|
||||||
|
let address = {};
|
||||||
|
if (address_checked === true) {
|
||||||
|
address = {
|
||||||
|
address1: address_input1_value,
|
||||||
|
address2: address_input2_value || "",
|
||||||
|
postalcode: address_zipcode_value,
|
||||||
|
city: address_city_value,
|
||||||
|
country: "DE",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
RunnerOrganizationService.runnerOrganizationControllerPost({
|
||||||
|
name,
|
||||||
|
address: address,
|
||||||
|
contact: undefined,
|
||||||
|
})
|
||||||
|
.then((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">​</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 class="flex items-start">
|
||||||
|
<div class="flex items-center h-5">
|
||||||
|
<input
|
||||||
|
bind:checked={address_checked}
|
||||||
|
id="comments"
|
||||||
|
name="comments"
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-3 text-sm">
|
||||||
|
<label
|
||||||
|
for="comments"
|
||||||
|
class="font-medium text-gray-700">Address</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if address_checked === true}
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address1"
|
||||||
|
class="block text-sm font-medium text-gray-700">Address</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Address"
|
||||||
|
class:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:ring-red-500={!isAddress1Valid}
|
||||||
|
bind:value={address_input1_value}
|
||||||
|
bind:this={address_input1}
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
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 !isAddress1Valid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
Address is required
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address2"
|
||||||
|
class="block text-sm font-medium text-gray-700">Apartment,
|
||||||
|
suite, etc.</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Apartment, suite, etc."
|
||||||
|
bind:value={address_input2_value}
|
||||||
|
bind:this={address_input2}
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="zipcode"
|
||||||
|
class="block text-sm font-medium text-gray-700">ZIP/ postal
|
||||||
|
code</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="ZIP/ postal code"
|
||||||
|
class:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:ring-red-500={!iszipcodevalid}
|
||||||
|
bind:value={address_zipcode_value}
|
||||||
|
bind:this={address_zipcode}
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
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 !iszipcodevalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
Valid zipcode/ postal code is required
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="city"
|
||||||
|
class="block text-sm font-medium text-gray-700">City</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="City"
|
||||||
|
class:border-red-500={!iscityvalid}
|
||||||
|
class:focus:border-red-500={!iscityvalid}
|
||||||
|
class:focus:ring-red-500={!iscityvalid}
|
||||||
|
bind:value={address_city_value}
|
||||||
|
bind:this={address_city}
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
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 !iscityvalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
Valid city is required
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</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}
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
@ -25,9 +25,7 @@
|
|||||||
}).showToast();
|
}).showToast();
|
||||||
location.replace("./");
|
location.replace("./");
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {});
|
||||||
//
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -68,13 +66,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<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">
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
Attention!
|
{$_('attention')}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="mt-2 mb-6">
|
<div class="mt-2 mb-6">
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500">
|
||||||
Do you want to delete the organization
|
{$_(
|
||||||
{delete_org.name}?<br />All associated teams and runners will
|
'do-you-want-to-delete-the-organization-delete_org-name',
|
||||||
be deleted too!
|
{
|
||||||
|
values: { orgname: delete_org.name },
|
||||||
|
}
|
||||||
|
)}<br />
|
||||||
|
{$_('all-associated-teams-and-runners-will-be-deleted-too')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -85,13 +87,13 @@
|
|||||||
on:click={deleteOrg}
|
on:click={deleteOrg}
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full inline-flex 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">
|
class="w-full inline-flex 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 organization and associated teams+runners.
|
{$_('confirm-delete-organization-and-associated-teams-runners')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
on:click={cancelDelete}
|
on:click={cancelDelete}
|
||||||
type="button"
|
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">
|
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, keep organization
|
{$_('cancel-keep-organization')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
361
src/components/orgs/OrgDetail.svelte
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
<script>
|
||||||
|
import {
|
||||||
|
GroupContactService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import { _ } from "svelte-i18n";
|
||||||
|
import Toastify from "toastify-js";
|
||||||
|
import store from "../../store";
|
||||||
|
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
||||||
|
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||||
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
|
$: delete_triggered = false;
|
||||||
|
$: address_valid_or_none =
|
||||||
|
(isAddress1Valid && iszipcodevalid && iscityvalid) ||
|
||||||
|
editable.address_checked === false;
|
||||||
|
$: save_enabled = data_changed && address_valid_or_none;
|
||||||
|
let original = "";
|
||||||
|
let original_object = {};
|
||||||
|
let contacts = [];
|
||||||
|
export let params;
|
||||||
|
$: editable = {};
|
||||||
|
$: data_loaded = false;
|
||||||
|
$: data_changed = !(JSON.stringify(editable) === original);
|
||||||
|
$: isAddress1Valid = editable.address?.address1?.trim().length !== 0;
|
||||||
|
$: iszipcodevalid = editable.address?.postalcode?.trim().length !== 0;
|
||||||
|
$: iscityvalid = editable.address?.city?.trim().length !== 0;
|
||||||
|
|
||||||
|
const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne(
|
||||||
|
params.orgid
|
||||||
|
).then((value) => {
|
||||||
|
data_loaded = true;
|
||||||
|
if (value.contact) {
|
||||||
|
if (value.contact !== "null") {
|
||||||
|
value.contact = value.contact.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value.address_checked = value.address.address1 !== null;
|
||||||
|
if(value.address_checked===false){
|
||||||
|
value.address = {
|
||||||
|
address1: "",
|
||||||
|
address2: "",
|
||||||
|
city: "",
|
||||||
|
postalcode: "",
|
||||||
|
country: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editable = Object.assign(editable, value);
|
||||||
|
editable = editable;
|
||||||
|
original_object = Object.assign(editable, value);
|
||||||
|
original = JSON.stringify(value);
|
||||||
|
});
|
||||||
|
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||||
|
contacts = val;
|
||||||
|
});
|
||||||
|
let modal_open = false;
|
||||||
|
let delete_org = {};
|
||||||
|
function deleteOrganization() {
|
||||||
|
RunnerOrganizationService.runnerOrganizationControllerRemove(
|
||||||
|
original_object.id,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
.then((resp) => {
|
||||||
|
Toastify({
|
||||||
|
text: $_("organization-deleted"),
|
||||||
|
duration: 500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
location.replace("./");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
modal_open = true;
|
||||||
|
delete_org = original_object;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function submit() {
|
||||||
|
if (data_loaded === true && save_enabled) {
|
||||||
|
Toastify({
|
||||||
|
text: $_("updating-organization"),
|
||||||
|
duration: 2500,
|
||||||
|
}).showToast();
|
||||||
|
let postdata = Object.assign({}, editable);
|
||||||
|
if (postdata.address_checked === false) {
|
||||||
|
postdata.address = null;
|
||||||
|
}
|
||||||
|
console.log(postdata)
|
||||||
|
postdata.contact = postdata.contact === "null" ? null : postdata.contact;
|
||||||
|
RunnerOrganizationService.runnerOrganizationControllerPut(
|
||||||
|
original_object.id,
|
||||||
|
postdata
|
||||||
|
)
|
||||||
|
.then((resp) => {
|
||||||
|
original = JSON.stringify(editable);
|
||||||
|
Toastify({
|
||||||
|
text: $_("updated-organization"),
|
||||||
|
duration: 2500,
|
||||||
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
}).showToast();
|
||||||
|
})
|
||||||
|
.catch((err) => {});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export let import_modal_open = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ImportRunnerModal
|
||||||
|
on:cancelDelete={(event) => {
|
||||||
|
import_modal_open = false;
|
||||||
|
}}
|
||||||
|
current_runners={[]}
|
||||||
|
passed_team={{}}
|
||||||
|
passed_orgs={[]}
|
||||||
|
passed_org={editable}
|
||||||
|
opened_from="OrgDetail"
|
||||||
|
bind:import_modal_open />
|
||||||
|
<ConfirmOrgDeletion bind:modal_open bind:delete_org />
|
||||||
|
{#if data_loaded}
|
||||||
|
<section class="container p-5">
|
||||||
|
<div class="mb-8 text-3xl font-extrabold leading-tight">
|
||||||
|
{original_object.name}
|
||||||
|
<span data-id="org_actions_${editable.id}">
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:IMPORT')}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
import_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">
|
||||||
|
{$_('import-runners')}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
|
||||||
|
{#if delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={deleteOrganization}
|
||||||
|
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
|
||||||
|
on:click={() => {
|
||||||
|
delete_triggered = !delete_triggered;
|
||||||
|
}}
|
||||||
|
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>
|
||||||
|
{/if}
|
||||||
|
{#if !delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
delete_triggered = true;
|
||||||
|
}}
|
||||||
|
type="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-organization')}</button>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
{#if !delete_triggered}
|
||||||
|
<button
|
||||||
|
on:click={submit}
|
||||||
|
disabled={!save_enabled}
|
||||||
|
class:opacity-50={!save_enabled}
|
||||||
|
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>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row mb-4">
|
||||||
|
<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="./">{$_('organizations')}</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={editable.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 rounded-md p-2" />
|
||||||
|
</div>
|
||||||
|
<div class="text-sm w-full">
|
||||||
|
<label
|
||||||
|
for="contact"
|
||||||
|
class="font-medium text-gray-700">{$_('contact')}</label>
|
||||||
|
<select
|
||||||
|
name="contact"
|
||||||
|
bind:value={editable.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 rounded-md p-2">
|
||||||
|
<option value="null">no contact</option>
|
||||||
|
{#each contacts as c}
|
||||||
|
<option value={c.id}>
|
||||||
|
{c.firstname}
|
||||||
|
{c.middlename || ''}
|
||||||
|
{c.lastname}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- -->
|
||||||
|
<div class="flex items-start mt-2">
|
||||||
|
<div class="flex items-center h-5">
|
||||||
|
<input
|
||||||
|
bind:checked={editable.address_checked}
|
||||||
|
id="comments"
|
||||||
|
name="comments"
|
||||||
|
type="checkbox"
|
||||||
|
class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-3 text-sm">
|
||||||
|
<label
|
||||||
|
for="comments"
|
||||||
|
class="font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#if editable.address_checked === true}
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address1"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('address')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Address"
|
||||||
|
class:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:border-red-500={!isAddress1Valid}
|
||||||
|
class:focus:ring-red-500={!isAddress1Valid}
|
||||||
|
bind:value={editable.address.address1}
|
||||||
|
type="text"
|
||||||
|
name="address1"
|
||||||
|
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 !isAddress1Valid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('address-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="address2"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('apartment-suite-etc')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('apartment-suite-etc')}
|
||||||
|
bind:value={editable.address.address2}
|
||||||
|
type="text"
|
||||||
|
name="address2"
|
||||||
|
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" />
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="zipcode"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('zip-postal-code')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('zip-postal-code')}
|
||||||
|
class:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:border-red-500={!iszipcodevalid}
|
||||||
|
class:focus:ring-red-500={!iszipcodevalid}
|
||||||
|
bind:value={editable.address.postalcode}
|
||||||
|
type="text"
|
||||||
|
name="zipcode"
|
||||||
|
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 !iszipcodevalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-zipcode-postal-code-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="col-span-6">
|
||||||
|
<label
|
||||||
|
for="city"
|
||||||
|
class="block text-sm font-medium text-gray-700">{$_('city')}</label>
|
||||||
|
<input
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder={$_('city')}
|
||||||
|
class:border-red-500={!iscityvalid}
|
||||||
|
class:focus:border-red-500={!iscityvalid}
|
||||||
|
class:focus:ring-red-500={!iscityvalid}
|
||||||
|
bind:value={editable.address.city}
|
||||||
|
type="text"
|
||||||
|
name="city"
|
||||||
|
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 !iscityvalid}
|
||||||
|
<span
|
||||||
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
|
{$_('valid-city-is-required')}
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</section>
|
||||||
|
{:else}
|
||||||
|
{#await promise}
|
||||||
|
{$_('organization-detail-is-being-loaded')}
|
||||||
|
{:catch error}
|
||||||
|
<PromiseError />
|
||||||
|
{/await}
|
||||||
|
{/if}
|
@ -3,7 +3,7 @@
|
|||||||
let modal_open = false;
|
let modal_open = false;
|
||||||
let delete_org = {};
|
let delete_org = {};
|
||||||
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
import { RunnerOrganizationService } from "@odit/lfk-client-js";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
import OrgsEmptyState from "./OrgsEmptyState.svelte";
|
import OrgsEmptyState from "./OrgsEmptyState.svelte";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
import ConfirmOrgDeletion from "./ConfirmOrgDeletion.svelte";
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<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">organizations are being loaded...</p>
|
<p class="font-bold">{$_('organizations-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}
|
{:then}
|
||||||
@ -51,20 +51,20 @@
|
|||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Name
|
{$_('name')}
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Address
|
{$_('address')}
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Contact
|
{$_('contact')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
<th scope="col" class="relative px-6 py-3">
|
||||||
<span class="sr-only">Action</span>
|
<span class="sr-only">{$_('action')}</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -78,8 +78,7 @@
|
|||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<div
|
<div class="text-sm font-medium text-gray-900">
|
||||||
class="text-sm font-medium text-gray-900">
|
|
||||||
{o.name}
|
{o.name}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -88,11 +87,14 @@
|
|||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<div
|
<div class="text-sm font-medium text-gray-900">
|
||||||
class="text-sm font-medium text-gray-900">
|
{#if o.address.address1 !== null}
|
||||||
{#if o.address}
|
{o.address.address1}<br />
|
||||||
{JSON.stringify(o.address)}
|
{o.address.address2 || ''}<br />
|
||||||
{:else}no address specified{/if}
|
{o.address.postalcode}
|
||||||
|
{o.address.city}
|
||||||
|
{o.address.country}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -100,11 +102,14 @@
|
|||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<div
|
<div class="text-sm font-medium text-gray-900">
|
||||||
class="text-sm font-medium text-gray-900">
|
|
||||||
{#if o.contact}
|
{#if o.contact}
|
||||||
{JSON.stringify(o.contact)}
|
<a
|
||||||
{:else}no contact specified{/if}
|
href="../contacts/{o.contact.id}"
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{o.contact.firstname}
|
||||||
|
{o.contact.middlename || ''}
|
||||||
|
{o.contact.lastname}</a>
|
||||||
|
{:else}{$_('no-contact-specified')}{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -117,8 +122,7 @@
|
|||||||
active_deletes[o.id] = false;
|
active_deletes[o.id] = false;
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
Delete</button>
|
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false)
|
RunnerOrganizationService.runnerOrganizationControllerRemove(o.id, false)
|
||||||
@ -137,22 +141,21 @@
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Confirm
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
Delete</button>
|
|
||||||
</td>
|
</td>
|
||||||
{:else}
|
{:else}
|
||||||
<td
|
<td
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<a
|
<a
|
||||||
href="./{o.id}"
|
href="./{o.id}"
|
||||||
class="text-indigo-600 hover:text-indigo-900">Edit</a>
|
class="text-indigo-600 hover:text-indigo-900">{$_('edit')}</a>
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('ORGANIZATION:DELETE')}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
active_deletes[o.id] = true;
|
active_deletes[o.id] = true;
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
@ -1,10 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
import AddOrgModal from "./AddOrgModal.svelte";
|
import AddOrgModal from "./AddOrgModal.svelte";
|
||||||
export let modal_open = false;
|
export let modal_open = false;
|
||||||
import OrgOverview from "./OrgOverview.svelte";
|
import OrgOverview from "./OrgOverview.svelte";
|
||||||
import ImportRunnerModal from "./ImportRunnerModal.svelte";
|
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||||
let current_organizations = [];
|
let current_organizations = [];
|
||||||
export let import_modal_open = false;
|
export let import_modal_open = false;
|
||||||
</script>
|
</script>
|
||||||
@ -33,7 +33,6 @@
|
|||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
<p class="mb-8 text-lg text-gray-500">manage runner organizations</p>
|
|
||||||
<OrgOverview bind:current_organizations />
|
<OrgOverview bind:current_organizations />
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -9,8 +9,9 @@
|
|||||||
<div class="text-center items-center justify-center">
|
<div class="text-center items-center justify-center">
|
||||||
<p class="mb-16 text-lg text-gray-500">
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
<img class="w-full h-44" src={org_empty} alt="" />
|
<img class="w-full h-44" src={org_empty} alt="" />
|
||||||
<span class="font-bold">There are no organizations added yet.</span><br />
|
<span
|
||||||
<span>Add your first organization</span>
|
class="font-bold">{$_('there-are-no-organizations-added-yet')}</span><br />
|
||||||
|
<span>{$_('add-your-first-organization')}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@ -28,7 +28,7 @@
|
|||||||
Role
|
Role
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
<th scope="col" class="relative px-6 py-3">
|
||||||
<span class="sr-only">Edit</span>
|
<span class="sr-only">{$_('edit')}</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -71,7 +71,7 @@
|
|||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="text-indigo-600 hover:text-indigo-900">Edit</a>
|
class="text-indigo-600 hover:text-indigo-900">{$_('edit')}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
import {
|
import {
|
||||||
RunnerService,
|
RunnerService,
|
||||||
@ -36,13 +36,15 @@
|
|||||||
$: firstname_input_value = "";
|
$: firstname_input_value = "";
|
||||||
$: processed_last_submit = true;
|
$: processed_last_submit = true;
|
||||||
$: isPhoneValidOrEmpty =
|
$: isPhoneValidOrEmpty =
|
||||||
isMobilePhone(
|
(phone_input_value.includes("+") &&
|
||||||
phone_input_value
|
isMobilePhone(
|
||||||
.replaceAll("(", "")
|
phone_input_value
|
||||||
.replaceAll(")", "")
|
.replaceAll("(", "")
|
||||||
.replaceAll("-", "")
|
.replaceAll(")", "")
|
||||||
.replaceAll(" ", "")
|
.replaceAll("-", "")
|
||||||
) || phone_input_value === "";
|
.replaceAll(" ", "")
|
||||||
|
)) ||
|
||||||
|
phone_input_value === "";
|
||||||
$: isEmailValidOrEmpty =
|
$: isEmailValidOrEmpty =
|
||||||
isEmail(email_input_value) || email_input_value === "";
|
isEmail(email_input_value) || email_input_value === "";
|
||||||
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
$: isLastnameValid = lastname_input_value.trim().length !== 0;
|
||||||
@ -70,7 +72,7 @@
|
|||||||
if (processed_last_submit === true) {
|
if (processed_last_submit === true) {
|
||||||
processed_last_submit = false;
|
processed_last_submit = false;
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: "Runner is being added...",
|
text: $_("runner-is-being-added"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
let postdata = {
|
let postdata = {
|
||||||
@ -96,7 +98,7 @@
|
|||||||
modal_open = false;
|
modal_open = false;
|
||||||
//
|
//
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "Runner added",
|
text: $_("runner-added"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@ -258,7 +260,7 @@
|
|||||||
{#if !isPhoneValidOrEmpty}
|
{#if !isPhoneValidOrEmpty}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
{$_('the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number')}
|
{@html $_('the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number')}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
@ -2,7 +2,7 @@
|
|||||||
import csv from "csvtojson";
|
import csv from "csvtojson";
|
||||||
import { read as readXlsx, utils as xlsx_utils } from "xlsx";
|
import { read as readXlsx, utils as xlsx_utils } from "xlsx";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import {
|
import {
|
||||||
@ -77,7 +77,7 @@
|
|||||||
function importAction() {
|
function importAction() {
|
||||||
if (recent_processed === true) {
|
if (recent_processed === true) {
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: "Runners are being imported...",
|
text: $_("runners-are-being-imported"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
recent_processed = false;
|
recent_processed = false;
|
||||||
@ -104,7 +104,7 @@
|
|||||||
toast.hideToast();
|
toast.hideToast();
|
||||||
recent_processed = true;
|
recent_processed = true;
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "Import finished",
|
text: $_("import-finished"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@ -121,7 +121,7 @@
|
|||||||
toast.hideToast();
|
toast.hideToast();
|
||||||
recent_processed = true;
|
recent_processed = true;
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "Import finished",
|
text: $_("import-finished"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@ -144,7 +144,7 @@
|
|||||||
toast.hideToast();
|
toast.hideToast();
|
||||||
recent_processed = true;
|
recent_processed = true;
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "Import finished",
|
text: $_("import-finished"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@ -201,7 +201,7 @@
|
|||||||
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
class="hidden sm:inline-block sm:align-middle sm:h-screen"
|
||||||
aria-hidden="true">​</span>
|
aria-hidden="true">​</span>
|
||||||
<div
|
<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"
|
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-max sm:w-full"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
aria-labelledby="modal-headline">
|
aria-labelledby="modal-headline">
|
||||||
@ -253,7 +253,7 @@
|
|||||||
<p>{$_('bitte-bestaetige-diese-laeufer-fuer-den-import')}</p>
|
<p>{$_('bitte-bestaetige-diese-laeufer-fuer-den-import')}</p>
|
||||||
{/if}
|
{/if}
|
||||||
{#if opened_from === 'RunnerOverview'}
|
{#if opened_from === 'RunnerOverview'}
|
||||||
<p>Group</p>
|
<p>{$_('group')}</p>
|
||||||
<select
|
<select
|
||||||
name="team"
|
name="team"
|
||||||
bind:value={selected_org_or_team}
|
bind:value={selected_org_or_team}
|
@ -1,14 +1,14 @@
|
|||||||
<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 store from "../../store";
|
||||||
import {
|
import {
|
||||||
RunnerService,
|
RunnerService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import PromiseError from "./PromiseError.svelte";
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
import isEmail from "validator/es/lib/isEmail";
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
let data_loaded = false;
|
let data_loaded = false;
|
||||||
export let params;
|
export let params;
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
import AddRunnerModal from "./AddRunnerModal.svelte";
|
import AddRunnerModal from "./AddRunnerModal.svelte";
|
||||||
import ImportRunnerModal from "./ImportRunnerModal.svelte";
|
import ImportRunnerModal from "./ImportRunnerModal.svelte";
|
||||||
import RunnersOverview from "./RunnersOverview.svelte";
|
import RunnersOverview from "./RunnersOverview.svelte";
|
||||||
@ -19,7 +19,7 @@
|
|||||||
}}
|
}}
|
||||||
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">
|
||||||
Läufer hinzufügen
|
{$_('laeufer-hinzufuegen')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
@ -27,7 +27,7 @@
|
|||||||
}}
|
}}
|
||||||
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">
|
||||||
Läufer importieren
|
{$_('laeufer-importieren')}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
@ -1,16 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
// import AddUserModal from "./AddUserModal.svelte";
|
|
||||||
import runners_empty from "./runners_empty.svg";
|
import runners_empty from "./runners_empty.svg";
|
||||||
// let modal_open = false;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="text-center items-center justify-center">
|
<div class="text-center items-center justify-center">
|
||||||
<p class="mb-16 text-lg text-gray-500">
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
<img class="w-full h-44" src={runners_empty} alt="" />
|
<img class="w-full h-44" src={runners_empty} alt="" />
|
||||||
<span class="font-bold">There are no runners added yet.</span><br />
|
<span class="font-bold">{$_('there-are-no-runners-added-yet')}</span><br />
|
||||||
<span>Add your first runner</span>
|
<span>{$_('add-your-first-runner')}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <AddUserModal bind:modal_open /> -->
|
|
@ -1,10 +1,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { RunnerService,RunnerTeamService,
|
import {
|
||||||
RunnerOrganizationService, } from "@odit/lfk-client-js";
|
RunnerService,
|
||||||
import store from "../store";
|
RunnerTeamService,
|
||||||
|
RunnerOrganizationService,
|
||||||
|
} from "@odit/lfk-client-js";
|
||||||
|
import store from "../../store";
|
||||||
import RunnersEmptyState from "./RunnersEmptyState.svelte";
|
import RunnersEmptyState from "./RunnersEmptyState.svelte";
|
||||||
import Select from 'svelte-select';
|
import Select from "svelte-select";
|
||||||
$: searchvalue = "";
|
$: searchvalue = "";
|
||||||
$: active_deletes = [];
|
$: active_deletes = [];
|
||||||
export let current_runners = [];
|
export let current_runners = [];
|
||||||
@ -13,17 +16,19 @@
|
|||||||
});
|
});
|
||||||
$: selectedFilter_teams = null;
|
$: selectedFilter_teams = null;
|
||||||
$: selectedFilter = null;
|
$: selectedFilter = null;
|
||||||
$: filter__teams = selectedFilter_teams||[];
|
$: filter__teams = selectedFilter_teams || [];
|
||||||
$: filter__orgs = selectedFilter||[];
|
$: filter__orgs = selectedFilter || [];
|
||||||
$:filterGroupIDs=filter__teams.concat(filter__orgs).map(i=>i.value)
|
$: filterGroupIDs = filter__teams.concat(filter__orgs).map((i) => i.value);
|
||||||
$: teams = [];
|
$: teams = [];
|
||||||
$: orgs = [];
|
$: orgs = [];
|
||||||
$:mappedteams=teams.map(function(g){
|
$: mappedteams = teams.map(function (g) {
|
||||||
return {value:g.id,label:g.parentGroup.name+" > "+g.name}
|
return { value: g.id, label: g.parentGroup.name + " > " + g.name };
|
||||||
})
|
});
|
||||||
$:selectgroups=(orgs.map(function(g){
|
$: selectgroups = orgs
|
||||||
return {value:g.id,label:g.name}
|
.map(function (g) {
|
||||||
})).concat(mappedteams)
|
return { value: g.id, label: g.name };
|
||||||
|
})
|
||||||
|
.concat(mappedteams);
|
||||||
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
RunnerTeamService.runnerTeamControllerGetAll().then((val) => {
|
||||||
teams = val;
|
teams = val;
|
||||||
});
|
});
|
||||||
@ -31,10 +36,10 @@
|
|||||||
orgs = val;
|
orgs = val;
|
||||||
});
|
});
|
||||||
function should_display_based_on_id(id) {
|
function should_display_based_on_id(id) {
|
||||||
if(searchvalue.toString().slice(-1)==="*"){
|
if (searchvalue.toString().slice(-1) === "*") {
|
||||||
return id.toString().startsWith(searchvalue.replace("*",""))
|
return id.toString().startsWith(searchvalue.replace("*", ""));
|
||||||
}
|
}
|
||||||
return id.toString()===searchvalue;
|
return id.toString() === searchvalue;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -43,7 +48,7 @@
|
|||||||
<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">runners are being loaded...</p>
|
<p class="font-bold">{$_('runners-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}
|
{:then}
|
||||||
@ -57,10 +62,18 @@
|
|||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="gridjs-input gridjs-search-input mb-4" />
|
||||||
<div class="block mb-1">
|
<div class="block mb-1">
|
||||||
<label for="country" class="text-sm font-medium text-gray-700">Filter by Organization/ Team</label>
|
<label
|
||||||
<Select on:select={(event)=>{
|
for="country"
|
||||||
selectedFilter=event.detail
|
class="text-sm font-medium text-gray-700">{$_('filter-by-organization-team')}</label>
|
||||||
}} selectedValue={selectedFilter} placeholder="Filter by Organization/ Team" containerClasses="mt-1 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" items={selectgroups} isMulti={true}></Select>
|
<Select
|
||||||
|
on:select={(event) => {
|
||||||
|
selectedFilter = event.detail;
|
||||||
|
}}
|
||||||
|
selectedValue={selectedFilter}
|
||||||
|
placeholder={$_('filter-by-organization-team')}
|
||||||
|
containerClasses="mt-1 py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||||
|
items={selectgroups}
|
||||||
|
isMulti={true} />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
|
||||||
@ -94,20 +107,34 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y divide-gray-200">
|
<tbody class="divide-y divide-gray-200">
|
||||||
{#each current_runners as runner}
|
{#each current_runners as runner}
|
||||||
{#if runner.firstname.toLowerCase().includes(searchvalue.toLowerCase())||runner.middlename.toLowerCase().includes(searchvalue.toLowerCase())||runner.lastname.toLowerCase().includes(searchvalue.toLowerCase())||should_display_based_on_id(runner.id)}
|
{#if runner.firstname
|
||||||
{#if filterGroupIDs.includes(runner.group.id)||filterGroupIDs.includes(runner.group.parentGroup?.id)||filterGroupIDs.length===0}
|
.toLowerCase()
|
||||||
<tr data-rowid="user_{runner.id}" data-groupid={runner.group.id}>
|
.includes(
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
searchvalue.toLowerCase()
|
||||||
<div class="flex items-center">
|
) || runner.middlename
|
||||||
<div class="ml-4">
|
.toLowerCase()
|
||||||
<div class="text-sm font-medium text-gray-900">
|
.includes(
|
||||||
{runner.firstname}
|
searchvalue.toLowerCase()
|
||||||
{runner.middlename || ''}
|
) || runner.lastname
|
||||||
{runner.lastname}
|
.toLowerCase()
|
||||||
|
.includes(
|
||||||
|
searchvalue.toLowerCase()
|
||||||
|
) || should_display_based_on_id(runner.id)}
|
||||||
|
{#if filterGroupIDs.includes(runner.group.id) || filterGroupIDs.includes(runner.group.parentGroup?.id) || filterGroupIDs.length === 0}
|
||||||
|
<tr
|
||||||
|
data-rowid="user_{runner.id}"
|
||||||
|
data-groupid={runner.group.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">
|
||||||
|
{runner.firstname}
|
||||||
|
{runner.middlename || ''}
|
||||||
|
{runner.lastname}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</td>
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
{#if runner.email}
|
{#if runner.email}
|
||||||
<div class="text-sm text-gray-500">{runner.email}</div>
|
<div class="text-sm text-gray-500">{runner.email}</div>
|
||||||
@ -115,6 +142,13 @@
|
|||||||
{#if runner.phone}
|
{#if runner.phone}
|
||||||
<div class="text-sm text-gray-500">{runner.phone}</div>
|
<div class="text-sm text-gray-500">{runner.phone}</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if runner.address.address1 !== null}
|
||||||
|
{runner.address.address1}<br />
|
||||||
|
{runner.address.address2 || ''}<br />
|
||||||
|
{runner.address.postalcode}
|
||||||
|
{runner.address.city}
|
||||||
|
{runner.address.country}
|
||||||
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
{#if runner.group.responseType === 'RUNNERTEAM'}
|
{#if runner.group.responseType === 'RUNNERTEAM'}
|
||||||
@ -151,24 +185,24 @@
|
|||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
</td>
|
</td>
|
||||||
{:else}
|
{:else}
|
||||||
<td
|
<td
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<a
|
<a
|
||||||
href="./{runner.id}"
|
href="./{runner.id}"
|
||||||
class="text-indigo-600 hover:text-indigo-900">Edit</a>
|
class="text-indigo-600 hover:text-indigo-900">{$_('edit')}</a>
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('RUNNER:DELETE')}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
active_deletes[runner.id] = true;
|
active_deletes[runner.id] = true;
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
||||||
</tr>
|
</tr>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
import {
|
import {
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
@ -110,11 +110,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<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">
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
Create a new team
|
{$_('create-a-new-team')}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="mt-2 mb-6">
|
<div class="mt-2 mb-6">
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500">
|
||||||
Please provide the required information to add a new team.
|
{$_('please-provide-the-required-information-to-add-a-new-team')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-6 gap-6">
|
<div class="grid grid-cols-6 gap-6">
|
||||||
@ -137,7 +137,7 @@
|
|||||||
{#if !isTeamNameValid}
|
{#if !isTeamNameValid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
team name is required
|
{$_('team-name-is-required')}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
import { RunnerTeamService } from "@odit/lfk-client-js";
|
import { RunnerTeamService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
@ -22,9 +22,7 @@
|
|||||||
}).showToast();
|
}).showToast();
|
||||||
location.replace("./");
|
location.replace("./");
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {});
|
||||||
//
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -65,13 +63,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<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">
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
Attention!
|
{$_('attention')}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="mt-2 mb-6">
|
<div class="mt-2 mb-6">
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500">
|
||||||
Do you want to delete the team
|
{$_('do-you-want-to-delete-the-team-delete_team-name', {
|
||||||
{delete_team.name}?<br />All associated runners will be
|
values: { teamname: delete_team.name },
|
||||||
deleted too!
|
})}<br />{$_('all-associated-runners-will-be-deleted-too')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,13 +80,13 @@
|
|||||||
on:click={deleteTeam}
|
on:click={deleteTeam}
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full inline-flex 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">
|
class="w-full inline-flex 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 team and associated runners.
|
{$_('confirm-delete-team-and-associated-runners')}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
on:click={cancelDelete}
|
on:click={cancelDelete}
|
||||||
type="button"
|
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">
|
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, keep team
|
{$_('cancel-keep-team')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -1,22 +1,24 @@
|
|||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
|
GroupContactService,
|
||||||
RunnerOrganizationService,
|
RunnerOrganizationService,
|
||||||
RunnerTeamService,
|
RunnerTeamService,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
import ImportRunnerModal from "./ImportRunnerModal.svelte";
|
import ImportRunnerModal from "../runners/ImportRunnerModal.svelte";
|
||||||
import PromiseError from "./PromiseError.svelte";
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
||||||
export let params;
|
let [teamdata, original, delete_team, orgs, contacts, modal_open] = [
|
||||||
let [teamdata, original, delete_team, orgs, modal_open] = [
|
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
[],
|
[],
|
||||||
|
[],
|
||||||
false,
|
false,
|
||||||
];
|
];
|
||||||
|
export let params;
|
||||||
export let import_modal_open = false;
|
export let import_modal_open = false;
|
||||||
$: delete_triggered = false;
|
$: delete_triggered = false;
|
||||||
$: save_enabled = !data_changed;
|
$: save_enabled = !data_changed;
|
||||||
@ -27,12 +29,20 @@
|
|||||||
params.teamid
|
params.teamid
|
||||||
).then((value) => {
|
).then((value) => {
|
||||||
data_loaded = true;
|
data_loaded = true;
|
||||||
|
if (value.contact) {
|
||||||
|
if (value.contact !== "null") {
|
||||||
|
value.contact = value.contact.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
teamdata = Object.assign(teamdata, value);
|
teamdata = Object.assign(teamdata, value);
|
||||||
original = Object.assign(original, value);
|
original = Object.assign(original, value);
|
||||||
});
|
});
|
||||||
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
RunnerOrganizationService.runnerOrganizationControllerGetAll().then((val) => {
|
||||||
orgs = val;
|
orgs = val;
|
||||||
});
|
});
|
||||||
|
GroupContactService.groupContactControllerGetAll().then((val) => {
|
||||||
|
contacts = val;
|
||||||
|
});
|
||||||
function deleteTeam() {
|
function deleteTeam() {
|
||||||
RunnerTeamService.runnerTeamControllerRemove(original.id, false)
|
RunnerTeamService.runnerTeamControllerRemove(original.id, false)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
@ -55,7 +65,9 @@
|
|||||||
duration: 2500,
|
duration: 2500,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
teamdata.parentGroup = teamdata.parentGroup.id;
|
teamdata.parentGroup = teamdata.parentGroup.id;
|
||||||
RunnerTeamService.runnerTeamControllerPut(original.id, teamdata)
|
let postdata = teamdata;
|
||||||
|
postdata.contact = postdata.contact === "null" ? null : postdata.contact;
|
||||||
|
RunnerTeamService.runnerTeamControllerPut(original.id, postdata)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
Object.assign(original, teamdata);
|
Object.assign(original, teamdata);
|
||||||
original = teamdata;
|
original = teamdata;
|
||||||
@ -68,7 +80,6 @@
|
|||||||
}).showToast();
|
}).showToast();
|
||||||
})
|
})
|
||||||
.catch((err) => {});
|
.catch((err) => {});
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -216,13 +227,19 @@
|
|||||||
<label
|
<label
|
||||||
for="contact"
|
for="contact"
|
||||||
class="font-medium text-gray-700">{$_('contact')}</label>
|
class="font-medium text-gray-700">{$_('contact')}</label>
|
||||||
<input
|
<select
|
||||||
autocomplete="off"
|
|
||||||
placeholder={$_('contact')}
|
|
||||||
type="text"
|
|
||||||
bind:value={teamdata.contact}
|
|
||||||
name="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 rounded-md p-2" />
|
bind:value={teamdata.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 rounded-md p-2">
|
||||||
|
<option value="null">no contact</option>
|
||||||
|
{#each contacts as c}
|
||||||
|
<option value={c.id}>
|
||||||
|
{c.firstname}
|
||||||
|
{c.middlename || ''}
|
||||||
|
{c.lastname}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-sm w-full">
|
<div class="text-sm w-full">
|
||||||
<label for="org" class="font-medium text-gray-700">Parent Organization</label>
|
<label for="org" class="font-medium text-gray-700">Parent Organization</label>
|
@ -1,11 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import store from "../store";
|
import store from "../../store";
|
||||||
import AddTeamModal from "./AddTeamModal.svelte";
|
import AddTeamModal from "./AddTeamModal.svelte";
|
||||||
export let modal_open = false;
|
export let modal_open = false;
|
||||||
import TeamsOverview from "./TeamsOverview.svelte";
|
import TeamsOverview from "./TeamsOverview.svelte";
|
||||||
console.log(store.state.jwtinfo.userdetails.permissions);
|
let current_teams = [];
|
||||||
let current_teams=[];
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="container p-5">
|
<section class="container p-5">
|
||||||
@ -18,11 +17,13 @@
|
|||||||
}}
|
}}
|
||||||
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 Team
|
{$_('create-team')}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
<p class="mb-8 text-lg text-gray-500">everything is more fun together 🏃♂️🏃♀️🏃♂️</p>
|
<p class="mb-8 text-lg text-gray-500">
|
||||||
|
{$_('everything-is-more-fun-together')}
|
||||||
|
</p>
|
||||||
<TeamsOverview bind:current_teams />
|
<TeamsOverview bind:current_teams />
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -9,8 +9,8 @@
|
|||||||
<div class="text-center items-center justify-center">
|
<div class="text-center items-center justify-center">
|
||||||
<p class="mb-16 text-lg text-gray-500">
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
<img class="w-full h-44" src={team_empty} alt="" />
|
<img class="w-full h-44" src={team_empty} alt="" />
|
||||||
<span class="font-bold">There are no teams added yet.</span><br />
|
<span class="font-bold">{$_('there-are-no-teams-added-yet')}</span><br />
|
||||||
<span>Add your first team</span>
|
<span>{$_('add-your-first-team')}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -3,8 +3,7 @@
|
|||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import { RunnerTeamService } from "@odit/lfk-client-js";
|
import { RunnerTeamService } from "@odit/lfk-client-js";
|
||||||
const teams_promise = RunnerTeamService.runnerTeamControllerGetAll();
|
const teams_promise = RunnerTeamService.runnerTeamControllerGetAll();
|
||||||
import { users as usersstore } from "../store.js";
|
import store, { users as usersstore } from "../../store.js";
|
||||||
import store from "../store";
|
|
||||||
import TeamsEmptyState from "./TeamsEmptyState.svelte";
|
import TeamsEmptyState from "./TeamsEmptyState.svelte";
|
||||||
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
import ConfirmTeamDeletion from "./ConfirmTeamDeletion.svelte";
|
||||||
$: searchvalue = "";
|
$: searchvalue = "";
|
||||||
@ -32,7 +31,7 @@
|
|||||||
<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">teams are being loaded...</p>
|
<p class="font-bold">{$_('teams-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}
|
{:then}
|
||||||
@ -53,7 +52,7 @@
|
|||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Name
|
{$_('name')}
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
@ -63,10 +62,10 @@
|
|||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Contact
|
{$_('contact')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
<th scope="col" class="relative px-6 py-3">
|
||||||
<span class="sr-only">Action</span>
|
<span class="sr-only">{$_('action')}</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -94,7 +93,7 @@
|
|||||||
<a
|
<a
|
||||||
href="../orgs/{t.parentGroup.id}"
|
href="../orgs/{t.parentGroup.id}"
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.parentGroup.name}</a>
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.parentGroup.name}</a>
|
||||||
{:else}no organization specified{/if}
|
{:else}{$_('no-organization-specified')}{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -104,8 +103,12 @@
|
|||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<div class="text-sm font-medium text-gray-900">
|
<div class="text-sm font-medium text-gray-900">
|
||||||
{#if t.contact}
|
{#if t.contact}
|
||||||
{JSON.stringify(t.contact)}
|
<a
|
||||||
{:else}no contact specified{/if}
|
href="../contacts/{t.contact.id}"
|
||||||
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{t.contact.firstname}
|
||||||
|
{t.contact.middlename || ''}
|
||||||
|
{t.contact.lastname}</a>
|
||||||
|
{:else}{$_('no-contact-specified')}{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -126,7 +129,7 @@
|
|||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
current_teams = current_teams.filter((obj) => obj.id !== t.id);
|
current_teams = current_teams.filter((obj) => obj.id !== t.id);
|
||||||
Toastify({
|
Toastify({
|
||||||
text: 'Organization deleted',
|
text: $_('organization-deleted'),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
'linear-gradient(to right, #00b09b, #96c93d)',
|
'linear-gradient(to right, #00b09b, #96c93d)',
|
||||||
@ -138,22 +141,21 @@
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Confirm
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
Delete</button>
|
|
||||||
</td>
|
</td>
|
||||||
{:else}
|
{:else}
|
||||||
<td
|
<td
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<a
|
<a
|
||||||
href="./{t.id}"
|
href="./{t.id}"
|
||||||
class="text-indigo-600 hover:text-indigo-900">Edit</a>
|
class="text-indigo-600 hover:text-indigo-900">{$_('edit')}</a>
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
active_deletes[t.id] = true;
|
active_deletes[t.id] = true;
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
@ -1,8 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
import { tracks as tracksstore } from "../store.js";
|
import { tracks as tracksstore } from "../../store.js";
|
||||||
import { TrackService } from "@odit/lfk-client-js";
|
import { TrackService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import "toastify-js/src/toastify.css";
|
import "toastify-js/src/toastify.css";
|
||||||
@ -51,7 +51,6 @@
|
|||||||
track_min_duration = 0;
|
track_min_duration = 0;
|
||||||
tracklength = 0;
|
tracklength = 0;
|
||||||
modal_open = false;
|
modal_open = false;
|
||||||
//
|
|
||||||
Toastify({
|
Toastify({
|
||||||
text: $_("track-added"),
|
text: $_("track-added"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
@ -64,12 +63,9 @@
|
|||||||
storeval.push(result);
|
storeval.push(result);
|
||||||
tracksstore.set(storeval);
|
tracksstore.set(storeval);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {})
|
||||||
//
|
|
||||||
})
|
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
processed_last_submit = true;
|
processed_last_submit = true;
|
||||||
//
|
|
||||||
toast.hideToast();
|
toast.hideToast();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -142,7 +138,7 @@
|
|||||||
{#if isTracknameValid}
|
{#if isTracknameValid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
Track name must not be empty
|
{$_('track-name-must-not-be-empty')}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@ -167,7 +163,7 @@
|
|||||||
{#if isTracklengthValid}
|
{#if isTracklengthValid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
Track length must be greater than 0
|
{$_('track-length-must-be-greater-than-0')}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@ -192,7 +188,7 @@
|
|||||||
{#if !trackMintimevalid}
|
{#if !trackMintimevalid}
|
||||||
<span
|
<span
|
||||||
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
class="flex items-center font-medium tracking-wide text-red-500 text-xs mt-1 ml-1">
|
||||||
minimum lap time must be a positive number or 0
|
{$_('minimum-lap-time-must-be-a-positive-number-or-0')}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@ -215,7 +211,7 @@
|
|||||||
}}
|
}}
|
||||||
type="button"
|
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">
|
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
|
{$_('cancel')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -4,9 +4,9 @@
|
|||||||
import TracksEmptyState from "./TracksEmptyState.svelte";
|
import TracksEmptyState from "./TracksEmptyState.svelte";
|
||||||
import { TrackService } from "@odit/lfk-client-js";
|
import { TrackService } from "@odit/lfk-client-js";
|
||||||
const tracks_promise = TrackService.trackControllerGetAll();
|
const tracks_promise = TrackService.trackControllerGetAll();
|
||||||
import { getlang } from "./datatable_i18n";
|
import { getlang } from "../base/datatable_i18n";
|
||||||
import { Grid, html } from "gridjs";
|
import { Grid, html } from "gridjs";
|
||||||
import { tracks as tracksstore } from "../store.js";
|
import { tracks as tracksstore } from "../../store.js";
|
||||||
$: trackscache = [];
|
$: trackscache = [];
|
||||||
$: blocked = [];
|
$: blocked = [];
|
||||||
let table;
|
let table;
|
||||||
@ -61,9 +61,7 @@
|
|||||||
elem.childNodes[1].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[1].childNodes[0].value}</td>`;
|
elem.childNodes[1].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[1].childNodes[0].value}</td>`;
|
||||||
elem.childNodes[2].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[2].childNodes[0].value}</td>`;
|
elem.childNodes[2].innerHTML = `<td data-column-id="trackName" class="gridjs-td">${elem.childNodes[2].childNodes[0].value}</td>`;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {});
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.track__delete_handler = () => {
|
window.track__delete_handler = () => {
|
||||||
@ -92,9 +90,7 @@
|
|||||||
tracksstore.set(newStoreVal);
|
tracksstore.set(newStoreVal);
|
||||||
renderdatatable();
|
renderdatatable();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {});
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
window.track__edit_handler = () => {
|
window.track__edit_handler = () => {
|
||||||
const trackid = parseInt(window.event.target.getAttribute("data-trackid"));
|
const trackid = parseInt(window.event.target.getAttribute("data-trackid"));
|
||||||
@ -124,16 +120,30 @@
|
|||||||
track.minimumLapTime || 0,
|
track.minimumLapTime || 0,
|
||||||
html(`
|
html(`
|
||||||
<div class="hidden" data-id="triggered_table_actions_${track.id}">
|
<div class="hidden" data-id="triggered_table_actions_${track.id}">
|
||||||
<button class="w-full inline-flex 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" data-trackid="${track.id}" onclick="track__edit_save()">Save</button>
|
<button class="w-full inline-flex 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" data-trackid="${
|
||||||
<button class="w-full inline-flex 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" data-trackid="${track.id}" onclick="track__edit_cancel()">Cancel</button>
|
track.id
|
||||||
|
}" onclick="track__edit_save()">${$_("save")}</button>
|
||||||
|
<button class="w-full inline-flex 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" data-trackid="${
|
||||||
|
track.id
|
||||||
|
}" onclick="track__edit_cancel()">${$_("cancel")}</button>
|
||||||
</div>
|
</div>
|
||||||
<div data-id="default_table_actions_${track.id}">
|
<div data-id="default_table_actions_${track.id}">
|
||||||
<button class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-400 text-base font-medium text-white sm:w-auto sm:text-sm" data-trackid="${track.id}" onclick="track__edit_handler()">Edit</button>
|
<button class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-400 text-base font-medium text-white sm:w-auto sm:text-sm" data-trackid="${
|
||||||
<button class="w-full inline-flex 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" data-trackid="${track.id}" onclick="track__delete_handler()">Delete</button>
|
track.id
|
||||||
|
}" onclick="track__edit_handler()">${$_("edit")}</button>
|
||||||
|
<button class="w-full inline-flex 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" data-trackid="${
|
||||||
|
track.id
|
||||||
|
}" onclick="track__delete_handler()">${$_("delete")}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden" data-id="deleteconfirmation_table_actions_${track.id}">
|
<div class="hidden" data-id="deleteconfirmation_table_actions_${
|
||||||
<button class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-400 text-base font-medium text-white sm:w-auto sm:text-sm" data-trackid="${track.id}" onclick="track__delete_cancel()">Cancel</button>
|
track.id
|
||||||
<button class="w-full inline-flex 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" data-trackid="${track.id}" onclick="track__delete_confirm()">Confirm</button>
|
}">
|
||||||
|
<button class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-400 text-base font-medium text-white sm:w-auto sm:text-sm" data-trackid="${
|
||||||
|
track.id
|
||||||
|
}" onclick="track__delete_cancel()">${$_("cancel")}</button>
|
||||||
|
<button class="w-full inline-flex 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" data-trackid="${
|
||||||
|
track.id
|
||||||
|
}" onclick="track__delete_confirm()">${$_("confirm")}</button>
|
||||||
</div>
|
</div>
|
||||||
`),
|
`),
|
||||||
]);
|
]);
|
@ -14,11 +14,11 @@
|
|||||||
}}
|
}}
|
||||||
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 Track
|
{$_('create-track')}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<p class="mb-8 text-lg text-gray-500">
|
<p class="mb-8 text-lg text-gray-500">
|
||||||
configure the tracks & minimum lap times
|
{$_('configure-the-tracks-and-minimum-lap-times')}
|
||||||
</p>
|
</p>
|
||||||
<Tracks />
|
<Tracks />
|
||||||
</section>
|
</section>
|
@ -1,6 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import { clickOutside } from "./outsideclick";
|
import { clickOutside } from "../base/outsideclick";
|
||||||
import { focusTrap } from "svelte-focus-trap";
|
import { focusTrap } from "svelte-focus-trap";
|
||||||
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";
|
||||||
@ -47,7 +47,7 @@
|
|||||||
if (processed_last_submit === true) {
|
if (processed_last_submit === true) {
|
||||||
processed_last_submit = false;
|
processed_last_submit = false;
|
||||||
const toast = Toastify({
|
const toast = Toastify({
|
||||||
text: "User is being added...",
|
text: $_("user-is-being-added"),
|
||||||
duration: -1,
|
duration: -1,
|
||||||
}).showToast();
|
}).showToast();
|
||||||
UserService.userControllerPost({
|
UserService.userControllerPost({
|
||||||
@ -67,19 +67,16 @@
|
|||||||
modal_open = false;
|
modal_open = false;
|
||||||
//
|
//
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "User added",
|
text: $_("user-added"),
|
||||||
duration: 500,
|
duration: 500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
current_users.push(result);
|
current_users.push(result);
|
||||||
current_users = current_users;
|
current_users = current_users;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {})
|
||||||
//
|
|
||||||
})
|
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
processed_last_submit = true;
|
processed_last_submit = true;
|
||||||
//
|
|
||||||
toast.hideToast();
|
toast.hideToast();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -125,11 +122,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<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">
|
<h3 class="text-lg leading-6 font-medium text-gray-900">
|
||||||
Create a new User
|
{$_('create-a-new-user')}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="mt-2 mb-6">
|
<div class="mt-2 mb-6">
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500">
|
||||||
Please provide the required information to add a new user.
|
{$_('please-provide-the-required-information-to-add-a-new-user')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-6 gap-6">
|
<div class="grid grid-cols-6 gap-6">
|
@ -1,11 +1,11 @@
|
|||||||
<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 store from "../../store";
|
||||||
import isEmail from "validator/es/lib/isEmail";
|
import isEmail from "validator/es/lib/isEmail";
|
||||||
import { UserService, UserGroupService } from "@odit/lfk-client-js";
|
import { UserService, UserGroupService } from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import PromiseError from "./PromiseError.svelte";
|
import PromiseError from "../base/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;
|
@ -6,7 +6,7 @@
|
|||||||
CreatePermission,
|
CreatePermission,
|
||||||
} from "@odit/lfk-client-js";
|
} from "@odit/lfk-client-js";
|
||||||
import Toastify from "toastify-js";
|
import Toastify from "toastify-js";
|
||||||
import PromiseError from "./PromiseError.svelte";
|
import PromiseError from "../base/PromiseError.svelte";
|
||||||
export let params;
|
export let params;
|
||||||
let [
|
let [
|
||||||
grantedPermissions_initial,
|
grantedPermissions_initial,
|
||||||
@ -51,7 +51,7 @@
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
Toastify({
|
Toastify({
|
||||||
text: "Permissions updated!",
|
text: $_("permissions-updated"),
|
||||||
duration: 2500,
|
duration: 2500,
|
||||||
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
}).showToast();
|
}).showToast();
|
||||||
@ -134,14 +134,14 @@
|
|||||||
<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">Permissions</span>
|
<span class="mr-2">{$_('permissions')}</span>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-8 text-3xl font-extrabold">
|
<div class="mb-8 text-3xl font-extrabold">
|
||||||
Permissions:
|
{$_('permissions')}:
|
||||||
{original_data.firstname}
|
{original_data.firstname}
|
||||||
{original_data.middlename || ''}
|
{original_data.middlename || ''}
|
||||||
{original_data.lastname}
|
{original_data.lastname}
|
||||||
@ -156,16 +156,21 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:ml-3 sm:w-auto sm:text-sm">Applying
|
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-yellow-600 text-base font-medium text-white hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500 sm:ml-3 sm:w-auto sm:text-sm">{$_('applying-changes')}</button>
|
||||||
Changes</button>
|
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div class="flex flex-wrap -mx-1 overflow-hidden">
|
<div class="flex flex-wrap -mx-1 overflow-hidden">
|
||||||
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">verfügbare</div>
|
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
|
||||||
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">erteilte</div>
|
{$_('verfuegbare')}
|
||||||
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">geerbte</div>
|
</div>
|
||||||
|
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
|
||||||
|
{$_('erteilte')}
|
||||||
|
</div>
|
||||||
|
<div class="my-1 px-1 w-full overflow-hidden sm:w-1/3">
|
||||||
|
{$_('geerbte')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- -->
|
<!-- -->
|
||||||
<div class="flex flex-wrap -mx-1 overflow-hidden">
|
<div class="flex flex-wrap -mx-1 overflow-hidden">
|
@ -1,10 +1,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
import store from "../store";
|
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);
|
|
||||||
let current_users=[];
|
let current_users=[];
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -8,8 +8,8 @@
|
|||||||
<div class="text-center items-center justify-center">
|
<div class="text-center items-center justify-center">
|
||||||
<p class="mb-16 text-lg text-gray-500">
|
<p class="mb-16 text-lg text-gray-500">
|
||||||
<img class="w-full h-44" src={users_empty} alt="" />
|
<img class="w-full h-44" src={users_empty} alt="" />
|
||||||
<span class="font-bold">There are no users added yet.</span><br />
|
<span class="font-bold">{$_('there-are-no-users-added-yet')}</span><br />
|
||||||
<span>Add your first user</span>
|
<span>{$_('add-your-first-user')}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2,15 +2,14 @@
|
|||||||
import { _ } from "svelte-i18n";
|
import { _ } from "svelte-i18n";
|
||||||
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 { users as usersstore } from "../store.js";
|
import store, { 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 = [];
|
||||||
export let current_users=[];
|
export let current_users = [];
|
||||||
$: advanced_search = false;
|
$: advanced_search = false;
|
||||||
usersstore.subscribe((val) => {
|
usersstore.subscribe((val) => {
|
||||||
current_users=val;
|
current_users = val;
|
||||||
});
|
});
|
||||||
users_promise.then((data) => {
|
users_promise.then((data) => {
|
||||||
usersstore.set(data);
|
usersstore.set(data);
|
||||||
@ -32,12 +31,12 @@
|
|||||||
<!-- {#if advanced_search}
|
<!-- {#if advanced_search}
|
||||||
advanced search
|
advanced search
|
||||||
{:else} -->
|
{:else} -->
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
bind:value={searchvalue}
|
bind:value={searchvalue}
|
||||||
placeholder={$_('datatable.search')}
|
placeholder={$_('datatable.search')}
|
||||||
aria-label={$_('datatable.search')}
|
aria-label={$_('datatable.search')}
|
||||||
class="gridjs-input gridjs-search-input mb-4" />
|
class="gridjs-input gridjs-search-input mb-4" />
|
||||||
<!-- {/if} -->
|
<!-- {/if} -->
|
||||||
<!-- <button
|
<!-- <button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
@ -57,20 +56,20 @@
|
|||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Name
|
{$_('name')}
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Status
|
{$_('status')}
|
||||||
</th>
|
</th>
|
||||||
<th
|
<th
|
||||||
scope="col"
|
scope="col"
|
||||||
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||||
Groups
|
{$_('groups')}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="relative px-6 py-3">
|
<th scope="col" class="relative px-6 py-3">
|
||||||
<span class="sr-only">Action</span>
|
<span class="sr-only">{$_('action')}</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -92,8 +91,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<div
|
<div class="text-sm font-medium text-gray-900">
|
||||||
class="text-sm font-medium text-gray-900">
|
|
||||||
{u.firstname}
|
{u.firstname}
|
||||||
{u.middlename || ''}
|
{u.middlename || ''}
|
||||||
{u.lastname}
|
{u.lastname}
|
||||||
@ -107,10 +105,10 @@
|
|||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td class="px-6 py-4 whitespace-nowrap">
|
||||||
{#if u.enabled}
|
{#if u.enabled}
|
||||||
<span
|
<span
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">Active</span>
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('active')}</span>
|
||||||
{:else}
|
{:else}
|
||||||
<span
|
<span
|
||||||
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">Inactive</span>
|
class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('inactive')}</span>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||||
@ -128,35 +126,31 @@
|
|||||||
active_deletes[u.id] = false;
|
active_deletes[u.id] = false;
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">Cancel
|
class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
|
||||||
Delete</button>
|
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
UserService.userControllerRemove(u.id, true)
|
UserService.userControllerRemove(u.id, true)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
current_users=current_users.filter(obj=>obj.id!==u.id);
|
current_users = current_users.filter((obj) => obj.id !== u.id);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {});
|
||||||
// error deleting user
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Confirm
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
|
||||||
Delete</button>
|
|
||||||
</td>
|
</td>
|
||||||
{:else}
|
{:else}
|
||||||
<td
|
<td
|
||||||
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<a
|
<a
|
||||||
href="./{u.id}"
|
href="./{u.id}"
|
||||||
class="text-indigo-600 hover:text-indigo-900">Edit</a>
|
class="text-indigo-600 hover:text-indigo-900">{$_('edit')}</a>
|
||||||
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
|
{#if store.state.jwtinfo.userdetails.permissions.includes('USER:DELETE')}
|
||||||
<button
|
<button
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
active_deletes[u.id] = true;
|
active_deletes[u.id] = true;
|
||||||
}}
|
}}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">Delete</button>
|
class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
|
||||||
{/if}
|
{/if}
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
@ -2,18 +2,66 @@
|
|||||||
"404message": "Die gesuchte Seite wurde leider nicht gefunden.",
|
"404message": "Die gesuchte Seite wurde leider nicht gefunden.",
|
||||||
"404title": "Fehler 404",
|
"404title": "Fehler 404",
|
||||||
"about": "Über",
|
"about": "Über",
|
||||||
|
"action": "Aktionen",
|
||||||
|
"active": "Aktiv",
|
||||||
|
"add-your-first-contact": "Erstelle den ersten Kontakt",
|
||||||
|
"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",
|
||||||
|
"add-your-first-track": "Erstelle den ersten Track (Laufstrecke).",
|
||||||
|
"add-your-first-user": "Erstelle die erste Benutzer:in",
|
||||||
|
"address": "Adresse",
|
||||||
|
"address-is-required": "Du musst eine Adresse angeben",
|
||||||
|
"all-associated-runners-will-be-deleted-too": "Alle zugehörigen Läufer:innen werden auch gelöscht!",
|
||||||
|
"all-associated-teams-and-runners-will-be-deleted-too": "Alle assoziierten Teams und Läufer:innen werden auch gelöscht!",
|
||||||
|
"apartment-suite-etc": "Apartment, Wohnung, etc.",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer für den import bestätigen.",
|
"applying-changes": "Änderungen anwenden",
|
||||||
|
"attention": "Achtung!",
|
||||||
|
"author": "Autor:in",
|
||||||
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Bitte die Läufer:innen für den Import bestätigen.",
|
||||||
"by": "von",
|
"by": "von",
|
||||||
"cancel": "Abbrechen",
|
"cancel": "Abbrechen",
|
||||||
|
"cancel-delete": "Löschen abbrechen",
|
||||||
|
"cancel-keep-organization": "Abbrechen und Organisation bearbeiten",
|
||||||
|
"cancel-keep-team": "Abbrechen, Team behalten",
|
||||||
"cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.",
|
"cannot-reset-your-password-directly": "Schade. \nWir können das Passwort leider nicht direkt zurücksetzen.\nBitte sende uns eine Mail in der du deine Identität bestätigst.",
|
||||||
"credits": "",
|
"city": "Stadt",
|
||||||
|
"close": "Schließen",
|
||||||
|
"configure-the-tracks-and-minimum-lap-times": "Bearbeite die Tracks und ihre minimale Rundenzeit",
|
||||||
|
"confirm": "Bestätigen",
|
||||||
|
"confirm-delete": "Löschung Bestätigen",
|
||||||
|
"confirm-delete-organization-and-associated-teams-runners": "Bestätugung, lösche die Organisation und alle zugehörigen Teams und Läufer:innen.",
|
||||||
|
"confirm-delete-team-and-associated-runners": "Bestätigung, lösche das Team mitsamt seinen Läufer:innen.",
|
||||||
|
"confirm-deletion": "Löschung Bestätigen",
|
||||||
|
"contact": "Kontakt",
|
||||||
|
"contact-deleted": "Kontakt gelöscht",
|
||||||
|
"contact-information": "Kontaktinformation",
|
||||||
|
"contact-is-being-updated": "Kontakt wird aktualisiert ...",
|
||||||
|
"contact-is-not-a-member-in-any-group": "Kontakt gehört zu keiner Gruppe",
|
||||||
|
"contacts": "Kontakte",
|
||||||
|
"contacts-are-being-loaded": "Kontakte werden geladen ...",
|
||||||
|
"count_organizations": "Organisationen (Anzahl)",
|
||||||
|
"count_teams": "Teams (Anzahl)",
|
||||||
|
"create": "Erstellen",
|
||||||
|
"create-a-new-contact": "Kontakt erstellen",
|
||||||
|
"create-a-new-organization": "Neue Organisatio anlegen",
|
||||||
|
"create-a-new-runner": "Neue Läufer:in erstellen",
|
||||||
|
"create-a-new-team": "Erstelle ein neues Team",
|
||||||
|
"create-a-new-track": "Neuen Track erstellen",
|
||||||
|
"create-a-new-user": "Neue Benutzer:in anlegen",
|
||||||
|
"create-organization": "Organisation erstellen",
|
||||||
|
"create-team": "Team erstellen",
|
||||||
|
"create-track": "Track erstellen",
|
||||||
|
"create-user": "Benutzer anlegen",
|
||||||
|
"credits": "Credits",
|
||||||
"csv_import__class": "Klasse",
|
"csv_import__class": "Klasse",
|
||||||
"csv_import__firstname": "Vorname",
|
"csv_import__firstname": "Vorname",
|
||||||
"csv_import__lastname": "Nachname",
|
"csv_import__lastname": "Nachname",
|
||||||
"csv_import__middlename": "Mittelname",
|
"csv_import__middlename": "Mittelname",
|
||||||
"csv_import__team": "Team",
|
"csv_import__team": "Team",
|
||||||
"dashboard-greeting": "Moin",
|
"dashboard-greeting": "Moin",
|
||||||
|
"dashboard-title": "Dashboard",
|
||||||
"datatable": {
|
"datatable": {
|
||||||
"search": "🔍 Suche ...",
|
"search": "🔍 Suche ...",
|
||||||
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
"an_error_happened_while_fetching_the_data": "Beim Abrufen der Daten ist ein Fehler aufgetreten",
|
||||||
@ -22,39 +70,171 @@
|
|||||||
"of": "von",
|
"of": "von",
|
||||||
"previous": "Vorherige",
|
"previous": "Vorherige",
|
||||||
"to": "bis",
|
"to": "bis",
|
||||||
"showing": "Zeige"
|
"showing": "Zeige",
|
||||||
|
"no_matching_records_found": "Keine passenden Einträge gefunden",
|
||||||
|
"page": "Seite",
|
||||||
|
"records": "Einträge",
|
||||||
|
"sort_column_ascending": "Spalte aufsteigend sortieren",
|
||||||
|
"sort_column_descending": "Spalte absteigend sortieren"
|
||||||
},
|
},
|
||||||
|
"delete": "Löschen",
|
||||||
|
"delete-contact": "Kontakt 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",
|
||||||
|
"distance": "Distanz",
|
||||||
|
"distance-in-km": "Distanz (in KM)",
|
||||||
|
"do-you-want-to-delete-the-organization-delete_org-name": "Möchtest du die Organisation {orgname} löschen?",
|
||||||
|
"do-you-want-to-delete-the-team-delete_team-name": "Möchtest du das Team {teamname} löschen?",
|
||||||
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
"dont-have-your-email-connected": "Deine E-Mail ist nicht verknüpft?",
|
||||||
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
"dont-panic-were-resetting-it": "Keine Panik, wir setzen es zurück ✌",
|
||||||
"e-mail-adress": "E-Mail-Adresse",
|
"e-mail-adress": "E-Mail-Adresse",
|
||||||
"email_address_or_username": "E-Mail-Addresse/ Benutzername",
|
"edit": "Bearbeiten",
|
||||||
|
"edit-permissions": "Berechtigungen bearbeiten",
|
||||||
|
"email_address_or_username": "E-Mail-Adresse/ Benutzername",
|
||||||
"error_on_login": "😢Fehler beim Login",
|
"error_on_login": "😢Fehler beim Login",
|
||||||
"forgot_password?": "Passwort vergessen?",
|
"erteilte": "Direkt erteilte",
|
||||||
|
"everything-is-more-fun-together": "Im Team macht's mehr Spaß 🏃♂️🏃♀️🏃♂️",
|
||||||
|
"faq": "FAQ",
|
||||||
|
"filter-by-organization-team": "Filtern nach Organisation / Team",
|
||||||
|
"first-name": "Vorname",
|
||||||
|
"first-name-is-required": "Vorname muss angegeben werden",
|
||||||
|
"forgot_password": "Passwort vergessen?",
|
||||||
|
"geerbte": "geerbte",
|
||||||
"general-stats": "Allgemeine Statistiken",
|
"general-stats": "Allgemeine Statistiken",
|
||||||
|
"general_promise_error": "😢 Ein unbekannter Fehler ist aufgetreten",
|
||||||
|
"generic-ui-logic-error": "Etwas ist in der Benutzeroberfläche schiefgelaufen.",
|
||||||
|
"go-to-login": "Zum Login",
|
||||||
"goback": "Zur Startseite",
|
"goback": "Zur Startseite",
|
||||||
"hallo": "hallo",
|
"group": "Gruppe",
|
||||||
|
"groups": "Gruppen",
|
||||||
|
"home": "Start",
|
||||||
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
"icon-image-credits": "Wir möchten uns außerdem für die verwendeten Icons und Bilder bedanken bei:",
|
||||||
"import-runners": "Läufer importieren",
|
"import-finished": "Import abgeschlossen",
|
||||||
|
"import-runners": "Läufer:innen importieren",
|
||||||
"import__target-organization": "Ziel Organisation",
|
"import__target-organization": "Ziel Organisation",
|
||||||
|
"imprint": "Impressum ",
|
||||||
|
"imprint-loading": "Impressum lädt...",
|
||||||
|
"inactive": "Inaktiv",
|
||||||
|
"installed-version": "Installierte Version",
|
||||||
|
"internal-error": "Interner Fehler",
|
||||||
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
"invalid-mail-reset": "Das ist keine gültige E-Mail",
|
||||||
|
"laeufer-hinzufuegen": "Läufer:in hinzufügen",
|
||||||
|
"laeufer-importieren": "Läufer:innen importieren",
|
||||||
|
"last-name": "Nachname",
|
||||||
|
"last-name-is-required": "Nachname muss angegeben werden",
|
||||||
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
"lfk-is-os": "Das \"Lauf für Kaya!\" Frontend ist (wie alle anderen Projekte für den \"LfK!\" auch) ein OpenSource Projekt.",
|
||||||
|
"license": "Lizenz",
|
||||||
|
"licenses-are-being-loaded": "Lizenzen werden geladen...",
|
||||||
|
"loading-contact-details": "Kontaktdaten werden geladen ...",
|
||||||
|
"loading-runners": "Läufer:innen werden geladen...",
|
||||||
"log_in": "Anmelden",
|
"log_in": "Anmelden",
|
||||||
"log_in_to_your_account": "Bitte melde dich an",
|
"log_in_to_your_account": "Bitte melde dich an",
|
||||||
"login_is_checked": "Login wird überprüft",
|
"login_is_checked": "Login wird überprüft",
|
||||||
|
"logout": "Abmelden",
|
||||||
|
"mail-validation-in-progress": "E-Mail Verifizierung läuft... ",
|
||||||
|
"manage-admin-users": "Nutzer verwalten",
|
||||||
|
"middle-name": "Mittelname",
|
||||||
|
"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",
|
||||||
|
"new-password": "Neues Passwort",
|
||||||
|
"no-contact-specified": "Kein Kontakt angegeben",
|
||||||
|
"no-license-text-could-be-found": "Kein Lizenz-Text gefunden 😢",
|
||||||
|
"no-organization-specified": "Keine Organisation angegeben",
|
||||||
|
"no-tracks-added-yet": "Es wurden noch keine Tracks erstellt.",
|
||||||
|
"organization": "Organisation",
|
||||||
|
"organization-added": "Organisation hinzugefügt",
|
||||||
|
"organization-deleted": "Organisation gelöscht",
|
||||||
|
"organization-detail-is-being-loaded": "Organisationsdetails werden geladen ...",
|
||||||
|
"organization-is-being-added": "Organisation wird hinzugefügt ...",
|
||||||
|
"organization-name-is-required": "Der Name muss angegeben werden",
|
||||||
|
"organizations": "Organisationen",
|
||||||
|
"organizations-are-being-loaded": "Organisationen werden geladen ...",
|
||||||
|
"orgs": "Orgs",
|
||||||
"oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!",
|
"oss_credit_description": "Wir verwenden eine Menge Open Source-Software bei diesen Projekten und möchten uns bei den folgenden Projekten und Mitwirkenden bedanken, die dazu beitragen, Open Source großartig zu machen!",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
|
"password-is-required": "Passwort muss angegeben werden",
|
||||||
|
"password-reset-failed": "Passwort zurücksetzen ist fehlgeschlagen!",
|
||||||
|
"password-reset-in-progress": "Passwort wird zurückgesetzt...",
|
||||||
|
"password-reset-mail-sent": "Passwort-Reset Mail wurde an \"{usersEmail}\" geschickt.",
|
||||||
|
"password-reset-successful": "Passwort erfolgreich zurückgesetzt!",
|
||||||
|
"permissions": "Berechtigungen",
|
||||||
|
"permissions-updated": "Berechtigungen aktualisiert!",
|
||||||
|
"phone": "Telefon",
|
||||||
|
"please-provide-a-password": "Bitte gebe ein Passwort an...",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
"please-provide-the-required-csv-xlsx-file": "Bitte eine CSV oder XLSX Datei hochladen.",
|
||||||
"register": "Registrieren",
|
"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.",
|
||||||
|
"please-provide-the-required-information-to-add-a-new-team": "Bitte gebe alle nötigen Informationen an, im das neue Team zu erstellen.",
|
||||||
|
"please-provide-the-required-information-to-add-a-new-track": "Bitte die benötigten Informationen angeben.",
|
||||||
|
"please-provide-the-required-information-to-add-a-new-user": "Bitte gebe alle nötigen Informationen an, im die neue Benutzer:in zu erstellen.",
|
||||||
|
"please-request-a-new-reset-mail": "Bitte eine neue Passwortreset-Mail anfordern...",
|
||||||
|
"privacy": "Datenschutz",
|
||||||
|
"privacy-loading": "Datenschutzerklärung lädt...",
|
||||||
|
"profile-picture": "Profilbild",
|
||||||
|
"read-license": "Lizenz-Text lesen",
|
||||||
|
"repo_link": "Link",
|
||||||
|
"request-a-new-reset-mail": "Neue Reset-Mail anfordern",
|
||||||
"reset-my-password": "Passwort zurücksetzen",
|
"reset-my-password": "Passwort zurücksetzen",
|
||||||
"runner-import": "Läufer Import",
|
"reset-password": "Passwort zurücksetzen",
|
||||||
"runnerimport_verify_runners_org": "Bitte die Läufer für den Import in die Organisation \"{org_name}\" bestätigen",
|
"runner-added": "Läufer:in hinzugefügt",
|
||||||
|
"runner-import": "Läufer:innen Import",
|
||||||
|
"runner-is-being-added": "Läufer:in wird hinzugefügt...",
|
||||||
|
"runner-updated": "Läufer:in aktualisiert!",
|
||||||
|
"runnerimport_verify_runners_org": "Bitte die Läufer:innen für den Import in die Organisation \"{org_name}\" bestätigen",
|
||||||
"runners": "Läufer",
|
"runners": "Läufer",
|
||||||
|
"runners-are-being-imported": "Läufer:innen werden importiert ...",
|
||||||
|
"runners-are-being-loaded": "Läufer:innen werden geladen ...",
|
||||||
|
"save": "Speichern",
|
||||||
|
"save-changes": "Änderungen speichern",
|
||||||
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
"send-a-mail-to-lfk-odit-services": "Sende eine Mail an lfk@odit.services",
|
||||||
"settings": "Einstellungen",
|
"settings": "Einstellungen",
|
||||||
"signout": "Abmelden",
|
"stats-are-being-loaded": "Die Statistiken werden geladen...",
|
||||||
|
"status": "Status",
|
||||||
|
"successful-password-reset": "Passwort erfolgreich zurückgesetzt!",
|
||||||
|
"team": "Team",
|
||||||
|
"team-name": "Teamname",
|
||||||
|
"team-name-is-required": "Teamname ist erforderlich",
|
||||||
|
"teams": "Teams",
|
||||||
|
"teams-are-being-loaded": "Teams werden geladen ...",
|
||||||
|
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "Die angegebene Telefonnummer ist nicht korrekt. <br /> Bitte gebe eine Telefonnummer im internationalen Format an...",
|
||||||
|
"there-are-no-contacts-added-yet": "Es wurden noch keine Kontakte hinzugefügt.",
|
||||||
|
"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.",
|
||||||
|
"there-are-no-users-added-yet": "Es wurden noch keine Benutzer hinzugefügt.",
|
||||||
|
"this-might-take-a-moment": "Das könnte einen kleinen Moment dauern",
|
||||||
"total-distance": "gelaufene Strecke",
|
"total-distance": "gelaufene Strecke",
|
||||||
"total-donations": "Spendensumme",
|
"total-donations": "Spendensumme",
|
||||||
"total-scans": "gesamte Scans",
|
"total-scans": "gesamte Scans",
|
||||||
|
"track-added": "Track hinzugefügt",
|
||||||
|
"track-data-is-being-loaded": "Trackdaten werden geladen",
|
||||||
|
"track-is-being-added": "Track wird hinzugefügt...",
|
||||||
|
"track-length-in-m": "Tracklänge (in Metern)",
|
||||||
|
"track-length-must-be-greater-than-0": "Die Länge muss größer als 0 (Meter) sein",
|
||||||
|
"track-name": "Trackname",
|
||||||
|
"track-name-must-not-be-empty": "Der Name muss angegeben werden",
|
||||||
|
"tracks": "Tracks",
|
||||||
|
"updated-contact": "Kontakt aktualisiert!",
|
||||||
|
"updated-organization": "Organisation wurde aktualisiert",
|
||||||
|
"updating-organization": "Organisation wird aktualisiert",
|
||||||
|
"updating-runner": "Läufer:in wird aktualisiert.",
|
||||||
|
"updating-user": "Benutzer:in wird aktualisiert...",
|
||||||
|
"user-added": "Benutzer hinzugefügt",
|
||||||
|
"user-is-being-added": "Benutzer wird hinzugefügt ...",
|
||||||
|
"user-updated": "Benutzer:in wurde aktualisiert",
|
||||||
|
"username": "Benutzername",
|
||||||
|
"users": "Benutzer",
|
||||||
|
"valid-city-is-required": "Du musst eine Stadt angeben",
|
||||||
|
"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",
|
||||||
"welcome_wavinghand": "Willkommen 👋",
|
"welcome_wavinghand": "Willkommen 👋",
|
||||||
"your_profile": "Dein Profil"
|
"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"
|
||||||
}
|
}
|
@ -3,27 +3,56 @@
|
|||||||
"404title": "Error 404",
|
"404title": "Error 404",
|
||||||
"about": "About",
|
"about": "About",
|
||||||
"action": "Action",
|
"action": "Action",
|
||||||
"add-your-first-track": "Add your first track",
|
"active": "Active",
|
||||||
|
"add-your-first-contact": "Add your first contact",
|
||||||
|
"add-your-first-organization": "Add your first organization",
|
||||||
|
"add-your-first-runner": "Add your first runner",
|
||||||
|
"add-your-first-team": "Add your first team",
|
||||||
|
"add-your-first-track": "Add your first track.",
|
||||||
|
"add-your-first-user": "Add your first user",
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
|
"address-is-required": "Address is required",
|
||||||
|
"all-associated-runners-will-be-deleted-too": "All associated runners will be deleted too!",
|
||||||
|
"all-associated-teams-and-runners-will-be-deleted-too": "All associated teams and runners will be deleted too!",
|
||||||
|
"apartment-suite-etc": "Apartment, suite, etc.",
|
||||||
"application_name": "Lauf für Kaya! - Admin",
|
"application_name": "Lauf für Kaya! - Admin",
|
||||||
|
"applying-changes": "Applying Changes",
|
||||||
|
"attention": "Attention!",
|
||||||
"author": "Author",
|
"author": "Author",
|
||||||
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import",
|
"bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.",
|
||||||
"browse": "Browse",
|
|
||||||
"by": "by",
|
"by": "by",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
|
"cancel-delete": "Cancel Delete",
|
||||||
|
"cancel-keep-organization": "Cancel, keep organization",
|
||||||
|
"cancel-keep-team": "Cancel, keep team",
|
||||||
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
"cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity",
|
||||||
"changelog": "Changelog",
|
"city": "City",
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
|
"configure-the-tracks-and-minimum-lap-times": "configure the tracks & minimum lap times",
|
||||||
|
"confirm": "Confirm",
|
||||||
"confirm-delete": "Confirm Delete",
|
"confirm-delete": "Confirm Delete",
|
||||||
|
"confirm-delete-organization-and-associated-teams-runners": "Confirm, delete organization and associated teams+runners.",
|
||||||
|
"confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.",
|
||||||
"confirm-deletion": "Confirm Deletion",
|
"confirm-deletion": "Confirm Deletion",
|
||||||
"contact": "Contact",
|
"contact": "Contact",
|
||||||
|
"contact-deleted": "Contact deleted",
|
||||||
"contact-information": "Contact Information",
|
"contact-information": "Contact Information",
|
||||||
|
"contact-is-being-updated": "Contact is being updated...",
|
||||||
|
"contact-is-not-a-member-in-any-group": "Contact is not a member in any group",
|
||||||
|
"contacts": "Contacts",
|
||||||
|
"contacts-are-being-loaded": "contacts are being loaded...",
|
||||||
"count_organizations": "# Organizations",
|
"count_organizations": "# Organizations",
|
||||||
"count_teams": "# Teams",
|
"count_teams": "# Teams",
|
||||||
"create": "Create",
|
"create": "Create",
|
||||||
|
"create-a-new-contact": "Create a new contact",
|
||||||
|
"create-a-new-organization": "Create a new Organization",
|
||||||
"create-a-new-runner": "Create a new Runner",
|
"create-a-new-runner": "Create a new Runner",
|
||||||
|
"create-a-new-team": "Create a new team",
|
||||||
"create-a-new-track": "Create a new Track",
|
"create-a-new-track": "Create a new Track",
|
||||||
|
"create-a-new-user": "Create a new User",
|
||||||
"create-organization": "Create Organization",
|
"create-organization": "Create Organization",
|
||||||
|
"create-team": "Create Team",
|
||||||
|
"create-track": "Create Track",
|
||||||
"create-user": "Create User",
|
"create-user": "Create User",
|
||||||
"credits": "Credits",
|
"credits": "Credits",
|
||||||
"csv_import__class": "Class",
|
"csv_import__class": "Class",
|
||||||
@ -49,68 +78,57 @@
|
|||||||
"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": "Delete",
|
"delete": "Delete",
|
||||||
"delete-group": "Delete Group",
|
"delete-contact": "Delete Contact",
|
||||||
"delete-organization": "Delete Organization",
|
"delete-organization": "Delete Organization",
|
||||||
"delete-runner": "Delete Runner",
|
"delete-runner": "Delete Runner",
|
||||||
"delete-team": "Delete Team",
|
"delete-team": "Delete Team",
|
||||||
"delete-user": "Delete User",
|
"delete-user": "Delete User",
|
||||||
"dependency_name": "Name",
|
"dependency_name": "Name",
|
||||||
"description": "Description",
|
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
"distance-in-km": "Distance in km",
|
"distance-in-km": "Distance in km",
|
||||||
|
"do-you-want-to-delete-the-organization-delete_org-name": "Do you want to delete the organization {orgname}?",
|
||||||
|
"do-you-want-to-delete-the-team-delete_team-name": "Do you want to delete the team {teamname}?",
|
||||||
"dont-have-your-email-connected": "Don't have your email connected?",
|
"dont-have-your-email-connected": "Don't have your email connected?",
|
||||||
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
"dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌",
|
||||||
"drag-and-drop-your-files-or": "Drag & Drop your files or",
|
|
||||||
"e-mail-adress": "E-Mail Adress",
|
"e-mail-adress": "E-Mail Adress",
|
||||||
|
"edit": "Edit",
|
||||||
"edit-permissions": "edit permissions",
|
"edit-permissions": "edit permissions",
|
||||||
"email_address_or_username": "Email / username",
|
"email_address_or_username": "Email / username",
|
||||||
"error_on_login": "Error on login",
|
"error_on_login": "Error on login",
|
||||||
|
"erteilte": "Directly granted",
|
||||||
|
"everything-is-more-fun-together": "everything is more fun together 🏃♂️🏃♀️🏃♂️",
|
||||||
"faq": "FAQ",
|
"faq": "FAQ",
|
||||||
"filepond__abort": "Abort",
|
"filter-by-organization-team": "Filter by Organization/ Team",
|
||||||
"filepond__cancel": "Cancel",
|
|
||||||
"filepond__error-during-load": "Error during load",
|
|
||||||
"filepond__error-during-remove": "Error during remove",
|
|
||||||
"filepond__error-during-revert": "Error during revert",
|
|
||||||
"filepond__error-during-upload": "Error during upload",
|
|
||||||
"filepond__field-contains-invalid-files": "Field contains invalid files",
|
|
||||||
"filepond__loading": "Loading",
|
|
||||||
"filepond__remove": "Remove",
|
|
||||||
"filepond__retry": "Retry",
|
|
||||||
"filepond__size-not-available": "Size not available",
|
|
||||||
"filepond__tap-to-cancel": "tap to cancel",
|
|
||||||
"filepond__tap-to-retry": "tap to retry",
|
|
||||||
"filepond__tap-to-undo": "tap to undo",
|
|
||||||
"filepond__undo": "Undo",
|
|
||||||
"filepond__upload": "Upload",
|
|
||||||
"filepond__upload-cancelled": "Upload cancelled",
|
|
||||||
"filepond__upload-complete": "Upload complete",
|
|
||||||
"filepond__uploading": "Uploading",
|
|
||||||
"filepond__waiting-for-size": "Waiting for size",
|
|
||||||
"first-name": "First name",
|
"first-name": "First name",
|
||||||
"first-name-is-required": "First Name is required",
|
"first-name-is-required": "First Name is required",
|
||||||
"forgot_password?": "Forgot your password?",
|
"forgot_password": "Forgot your password?",
|
||||||
|
"geerbte": "inherited",
|
||||||
"general-stats": "General Stats",
|
"general-stats": "General Stats",
|
||||||
"general_promise_error": "😢 Error",
|
"general_promise_error": "😢 Error",
|
||||||
|
"generic-ui-logic-error": "Something went wrong in the UI logic",
|
||||||
"go-to-login": "Go To Login",
|
"go-to-login": "Go To Login",
|
||||||
"goback": "Go Home",
|
"goback": "Go Home",
|
||||||
"group": "Group",
|
"group": "Group",
|
||||||
"group-updated": "Group updated!",
|
|
||||||
"groups": "Groups",
|
"groups": "Groups",
|
||||||
"groups-are-being-loaded": "Groups are being loaded...",
|
"home": "Home",
|
||||||
"hallo": "hello",
|
|
||||||
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
"icon-image-credits": "We also want to thank these projects for illustrations and icons:",
|
||||||
|
"import-finished": "Import finished",
|
||||||
"import-runners": "Import runners",
|
"import-runners": "Import runners",
|
||||||
"import__target-organization": "Target Organization",
|
"import__target-organization": "Target Organization",
|
||||||
"imprint": "Imprint 🧾",
|
"imprint": "Imprint",
|
||||||
"imprint-loading": "Imprint loading...",
|
"imprint-loading": "Imprint loading...",
|
||||||
|
"inactive": "Inactive",
|
||||||
"installed-version": "Installed version",
|
"installed-version": "Installed version",
|
||||||
|
"internal-error": "Internal Error",
|
||||||
"invalid-mail-reset": "the provided email is invalid",
|
"invalid-mail-reset": "the provided email is invalid",
|
||||||
|
"laeufer-hinzufuegen": "Add runner",
|
||||||
|
"laeufer-importieren": "Läufer importieren",
|
||||||
"last-name": "Last name",
|
"last-name": "Last name",
|
||||||
"last-name-is-required": "Last Name is required",
|
"last-name-is-required": "Last Name is required",
|
||||||
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
"lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.",
|
||||||
"license": "License",
|
"license": "License",
|
||||||
"licenses-are-being-loaded": "Licenses are being loaded...",
|
"licenses-are-being-loaded": "Licenses are being loaded...",
|
||||||
"loading-group-detail": "Loading group detail...",
|
"loading-contact-details": "Loading contact details...",
|
||||||
"loading-runners": "loading runners...",
|
"loading-runners": "loading runners...",
|
||||||
"log_in": "Log in",
|
"log_in": "Log in",
|
||||||
"log_in_to_your_account": "Log in to your account",
|
"log_in_to_your_account": "Log in to your account",
|
||||||
@ -120,49 +138,75 @@
|
|||||||
"manage-admin-users": "manage admin users",
|
"manage-admin-users": "manage admin users",
|
||||||
"middle-name": "Middle name",
|
"middle-name": "Middle name",
|
||||||
"minimum-lap-time-in-s": "minimum lap time in s",
|
"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": "Name",
|
||||||
"new-password": "New password",
|
"new-password": "New password",
|
||||||
|
"no-contact-specified": "no contact specified",
|
||||||
"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-organization-specified": "no organization specified",
|
||||||
"no-tracks-added-yet": "there are no tracks added yet.",
|
"no-tracks-added-yet": "there are no tracks added yet.",
|
||||||
"organization": "Organization",
|
"organization": "Organization",
|
||||||
|
"organization-added": "Organization added",
|
||||||
|
"organization-deleted": "Organization deleted",
|
||||||
|
"organization-detail-is-being-loaded": "organization detail is being loaded...",
|
||||||
|
"organization-is-being-added": "Organization is being added...",
|
||||||
|
"organization-name-is-required": "Organization name is required",
|
||||||
"organizations": "Organizations",
|
"organizations": "Organizations",
|
||||||
|
"organizations-are-being-loaded": "organizations are being loaded...",
|
||||||
"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",
|
||||||
"password-is-required": "Password is required",
|
"password-is-required": "Password is required",
|
||||||
"password-reset-failed": "Password reset failed!",
|
"password-reset-failed": "Password reset failed!",
|
||||||
"password-reset-in-progress": "Password Reset in Progress...",
|
"password-reset-in-progress": "Password Reset in Progress...",
|
||||||
|
"password-reset-mail-sent": "Password reset mail was sent to \"{usersEmail}\".",
|
||||||
"password-reset-successful": "Password Reset successful!",
|
"password-reset-successful": "Password Reset successful!",
|
||||||
"permissions": "Permissions",
|
"permissions": "Permissions",
|
||||||
|
"permissions-updated": "Permissions updated!",
|
||||||
"phone": "Phone",
|
"phone": "Phone",
|
||||||
"please-provide-a-password": "Please provide a password...",
|
"please-provide-a-password": "Please provide a password...",
|
||||||
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
"please-provide-the-required-csv-xlsx-file": "Please provide the required csv/ xlsx file",
|
||||||
|
"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.",
|
"please-provide-the-required-information-to-add-a-new-runner": "Please provide the required information to add a new runner.",
|
||||||
|
"please-provide-the-required-information-to-add-a-new-team": "Please provide the required information to add a new team.",
|
||||||
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
"please-provide-the-required-information-to-add-a-new-track": "Please provide the required information to add a new track.",
|
||||||
|
"please-provide-the-required-information-to-add-a-new-user": "Please provide the required information to add a new user.",
|
||||||
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
"please-request-a-new-reset-mail": "Please request a new reset mail...",
|
||||||
"privacy": "Privacy 🔒",
|
"privacy": "Privacy",
|
||||||
"privacy-loading": "Privacy loading...",
|
"privacy-loading": "Privacy loading...",
|
||||||
"profile-picture": "Profile Picture",
|
"profile-picture": "Profile Picture",
|
||||||
"read-license": "Read License",
|
"read-license": "Read License",
|
||||||
"register": "Register",
|
|
||||||
"repo_link": "Link",
|
"repo_link": "Link",
|
||||||
"request-a-new-reset-mail": "Request a new reset mail",
|
"request-a-new-reset-mail": "Request a new reset mail",
|
||||||
"reset-my-password": "Reset my password",
|
"reset-my-password": "Reset my password",
|
||||||
"reset-password": "Reset your password",
|
"reset-password": "Reset your password",
|
||||||
|
"runner-added": "Runner added",
|
||||||
"runner-import": "Runner Import",
|
"runner-import": "Runner Import",
|
||||||
|
"runner-is-being-added": "Runner is being added...",
|
||||||
"runner-updated": "Runner updated!",
|
"runner-updated": "Runner updated!",
|
||||||
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
"runnerimport_verify_runners_org": "Please confirm these runners for import into the organization \"{org_name}\"",
|
||||||
"runners": "Runners",
|
"runners": "Runners",
|
||||||
|
"runners-are-being-imported": "Runners are being imported...",
|
||||||
|
"runners-are-being-loaded": "runners are being loaded...",
|
||||||
|
"save": "Save",
|
||||||
"save-changes": "Save Changes",
|
"save-changes": "Save Changes",
|
||||||
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
"send-a-mail-to-lfk-odit-services": "send a mail to lfk@odit.services",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
"signout": "Sign out",
|
|
||||||
"stats-are-being-loaded": "stats are being loaded...",
|
"stats-are-being-loaded": "stats are being loaded...",
|
||||||
|
"status": "Status",
|
||||||
"successful-password-reset": "Successful password reset!",
|
"successful-password-reset": "Successful password reset!",
|
||||||
"team": "Team",
|
"team": "Team",
|
||||||
"team-name": "Team name",
|
"team-name": "Team name",
|
||||||
|
"team-name-is-required": "team name is required",
|
||||||
"teams": "Teams",
|
"teams": "Teams",
|
||||||
|
"teams-are-being-loaded": "teams are being loaded...",
|
||||||
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.<br />please enter a valid international number...",
|
"the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.<br />please enter a valid international number...",
|
||||||
|
"there-are-no-contacts-added-yet": "There are no contacts added 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.",
|
||||||
|
"there-are-no-users-added-yet": "There are no users added yet.",
|
||||||
"this-might-take-a-moment": "This might take a moment 👀",
|
"this-might-take-a-moment": "This might take a moment 👀",
|
||||||
"total-distance": "total distance",
|
"total-distance": "total distance",
|
||||||
"total-donations": "total donations",
|
"total-donations": "total donations",
|
||||||
@ -171,16 +215,26 @@
|
|||||||
"track-data-is-being-loaded": "Track data is being loaded",
|
"track-data-is-being-loaded": "Track data is being loaded",
|
||||||
"track-is-being-added": "Track is being added...",
|
"track-is-being-added": "Track is being added...",
|
||||||
"track-length-in-m": "Track Length in m",
|
"track-length-in-m": "Track Length in m",
|
||||||
|
"track-length-must-be-greater-than-0": "Track length must be greater than 0",
|
||||||
"track-name": "Track name",
|
"track-name": "Track name",
|
||||||
|
"track-name-must-not-be-empty": "Track name must not be empty",
|
||||||
"tracks": "Tracks",
|
"tracks": "Tracks",
|
||||||
"updating-group": "Updating group...",
|
"updated-contact": "Updated contact!",
|
||||||
|
"updated-organization": "updated organization",
|
||||||
|
"updating-organization": "updating organization",
|
||||||
"updating-runner": "Updating runner...",
|
"updating-runner": "Updating runner...",
|
||||||
"updating-user": "updating user...",
|
"updating-user": "updating user...",
|
||||||
|
"user-added": "User added",
|
||||||
|
"user-is-being-added": "User is being added...",
|
||||||
"user-updated": "User updated",
|
"user-updated": "User updated",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"users": "Users",
|
"users": "Users",
|
||||||
|
"valid-city-is-required": "Valid city is required",
|
||||||
"valid-email-is-required": "valid email is required",
|
"valid-email-is-required": "valid email is required",
|
||||||
|
"valid-international-phone-number-is-required": "valid international phone number is required...",
|
||||||
|
"valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required",
|
||||||
|
"verfuegbare": "availdable",
|
||||||
"welcome_wavinghand": "Welcome 👋",
|
"welcome_wavinghand": "Welcome 👋",
|
||||||
"you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉",
|
"you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉",
|
||||||
"your_profile": "Your Profile"
|
"zip-postal-code": "ZIP/ postal code"
|
||||||
}
|
}
|
@ -23,9 +23,7 @@ const store = () => {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
refreshAuth() {
|
refreshAuth() {
|
||||||
console.log('refreshing auth');
|
|
||||||
AuthService.authControllerRefresh({ token: state.auth.refresh_token }).then((auth) => {
|
AuthService.authControllerRefresh({ token: state.auth.refresh_token }).then((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]));
|
const jwtinfo = JSON.parse(atob(auth.access_token.split('.')[1]));
|
||||||
state.jwtinfo = jwtinfo;
|
state.jwtinfo = jwtinfo;
|
||||||
|