diff --git a/src/assets/SCSS/custom.scss b/src/assets/SCSS/custom.scss index 9b75cd2..806f9c2 100644 --- a/src/assets/SCSS/custom.scss +++ b/src/assets/SCSS/custom.scss @@ -1,25 +1,25 @@ //Font Definitions @font-face { - font-family: 'Telegrotesk Next Regular'; - src: url(./fonts/telegrotesknext-regular.woff) format('woff'); + font-family: "Telegrotesk Next Regular"; + src: url(./fonts/telegrotesknext-regular.woff) format("woff"); } @font-face { - font-family: 'Telegrotesk Next Bold'; - src: url(./fonts/telegrotesknext-bold.woff) format('woff'); + font-family: "Telegrotesk Next Bold"; + src: url(./fonts/telegrotesknext-bold.woff) format("woff"); } @font-face { - font-family: 'Telegrotesk Next Thin'; - src: url(./fonts/telegrotesknext-thin.woff) format('woff'); + font-family: "Telegrotesk Next Thin"; + src: url(./fonts/telegrotesknext-thin.woff) format("woff"); } @font-face { - font-family: 'TeleNeo'; - src: url(./fonts/TeleNeoWeb-Regular.eot) format('eot'), url(./fonts/TeleNeoWeb-Regular.woff) format('woff'), - url(./fonts/TeleNeoWeb-Regular.woff2) format('woff2'); + font-family: "TeleNeo"; + src: url(./fonts/TeleNeoWeb-Regular.eot) format("eot"), url(./fonts/TeleNeoWeb-Regular.woff) format("woff"), + url(./fonts/TeleNeoWeb-Regular.woff2) format("woff2"); } @font-face { - font-family: 'TeleNeo'; - src: url(./fonts/TeleNeoWeb-Bold.eot) format('eot'), url(./fonts/TeleNeoWeb-Bold.woff) format('woff'), - url(./fonts/TeleNeoWeb-Bold.woff2) format('woff2'); + font-family: "TeleNeo"; + src: url(./fonts/TeleNeoWeb-Bold.eot) format("eot"), url(./fonts/TeleNeoWeb-Bold.woff) format("woff"), + url(./fonts/TeleNeoWeb-Bold.woff2) format("woff2"); font-weight: bold; } @@ -29,17 +29,18 @@ $body-bg: white; $font-family-base: TeleNeo; $primary: #7e7e7e; +$table-border-color: #7e7e7e44; $light: #eeeeee; // Import Bootstrap and its default variables -@import '~bootstrap/scss/bootstrap.scss'; +@import "~bootstrap/scss/bootstrap.scss"; $header-height: 120px; $menu-width: 120px; $menu-padding: 1rem; $data-card-border-radius: 10px; $input-border-radius: 4px; -$user-image-width:39px; +$user-image-width: 39px; select, option { @@ -47,12 +48,12 @@ option { } body { overflow-y: scroll; - } +} hr { margin-left: 0; margin-right: 0; - } +} #qt-header { margin: 0; @@ -70,12 +71,12 @@ hr { padding: 1rem 1rem 2rem 1rem; } -.qt-IFrame{ +.qt-IFrame { height: 100%; width: inherit; } -.qt-frame-card{ +.qt-frame-card { display: flex; flex-direction: column; } @@ -101,7 +102,7 @@ hr { justify-content: center; // all greater than md - + @include media-breakpoint-up(md) { position: absolute; right: 0; @@ -109,7 +110,6 @@ hr { padding: 1rem; justify-content: flex-end; } - } #process-row { @@ -124,7 +124,7 @@ hr { } } -#data-card{ +#data-card { height: 100%; background-color: $light; border-radius: $data-card-border-radius; @@ -136,7 +136,7 @@ hr { flex-direction: column; height: 100%; } -.data-modal{ +.data-modal { background-color: $light; border-radius: $data-card-border-radius; box-shadow: 4px 2px 8px rgba(0, 0, 0, 0.15); @@ -169,7 +169,7 @@ hr { } #id-query-text { - font-family: 'TeleNeo'; + font-family: "TeleNeo"; font-weight: bold; font-size: 20px; align-self: center; @@ -189,18 +189,21 @@ hr { width: 80%; height: 80%; } -.qt-input{ +.qt-input { align-self: center; border-radius: $input-border-radius; border: 1px solid $primary; } +.qt-input-area { + height: 150px !important; +} .footer-font { font-size: 14px !important; color: #757575; } .header-font { - font-family: 'TeleNeo'; + font-family: "TeleNeo"; font-weight: bold; font-size: 26px; color: black; @@ -221,7 +224,7 @@ hr { } .landing-btn { - font-family: 'TeleNeo'; + font-family: "TeleNeo"; font-weight: bold; color: white; max-width: 500px; @@ -244,11 +247,10 @@ hr { font-size: 20px; } -.txt-no-wrap{ +.txt-no-wrap { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; - } .first-col-item { @include media-breakpoint-up(sm) { @@ -290,7 +292,7 @@ hr { .dropdown-toggle::after { width: $user-image-width; height: $user-image-width; - background-image: url('../images/user.png') !important; + background-image: url("../images/user.png") !important; border: 0; align-self: center; } @@ -300,7 +302,6 @@ hr { height: $user-image-width; line-height: $user-image-width; font-size: 20px; - } .navbar-toggler { border: 0 !important; @@ -328,48 +329,91 @@ hr { border: 0 !important; } -.ckb-input{ +.ckb-input { position: inherit; width: 20px; - height:20px; + height: 20px; border-radius: $data-card-border-radius; } -.rdb-input{ +.rdb-input { position: inherit; width: 20px; - height:20px; + height: 20px; } -.rdb-label{ +.rdb-label { height: 20px; align-self: center; padding-left: 0.5rem; -} -.qt-notification{ +} +.qt-notification { margin-bottom: 20%; border-radius: 6px; - border-color: #46A800; + border-color: #46a800; color: black; display: flex; } -.qt-notification-text{ +.qt-notification-text { font-size: 22px; } .success-icon { - background-image: url('../images/icon_success.svg') !important; + background-image: url("../images/icon_success.svg") !important; height: 40px; width: 40px; - } +} + +.edit-icon { + background-image: url("../images/icon_edit.svg") !important; + height: 24px; + width: 24px; +} - .modal-90w{ - max-width: 90% !important; - } - .btn-spinner { +.delete-icon { + background-image: url("../images/icon_delete.svg") !important; + height: 24px; + width: 24px; +} + +.modal-90w { + max-width: 90% !important; +} +.btn-spinner { position: absolute; left: 30px; top: 6px; } .btn-icon { padding: 0px; + border:0px; + background: transparent; +} +.table{ + margin-bottom: 0.25rem; +} +th{ + background: white; + padding:0.1rem 0.25rem !important; + font-weight: normal; + font-size: 0.9rem; +} +td{ + background: #f3f3f3; + vertical-align: middle !important; + padding:0.5rem 0.25rem !important; + line-height: 16px; + font-size: 0.8rem; +} +.td-btn{ + min-width: 70px; + width:10%; +} +.intend{ + margin-left: 2rem; +} + +.btn-add{ + padding-left: 0px; + display: flex; + vertical-align: middle; } \ No newline at end of file diff --git a/src/assets/i18n/de/translation.json b/src/assets/i18n/de/translation.json index 4403729..1a38c78 100644 --- a/src/assets/i18n/de/translation.json +++ b/src/assets/i18n/de/translation.json @@ -27,12 +27,12 @@ "city": "Ort", "street": "Straße", "house-number": "Hausnr.", - "phone-number":"Telefonnummer", - "email-address":"E-Mail Adresse", - "test-id":"Test-ID", - "test-name":"Test-Name", - "processing-consent-title":"Testergebnis in CWA anzeigen (Nicht-namentlicher Testnachweis)", - "patientdata-exclude-title":"Testergebnis in CWA anzeigen (Namentlicher Testnachweis)", + "phone-number": "Telefonnummer", + "email-address": "E-Mail Adresse", + "test-id": "Test-ID", + "test-name": "Test-Name", + "processing-consent-title": "Testergebnis in CWA anzeigen (Nicht-namentlicher Testnachweis)", + "patientdata-exclude-title": "Testergebnis in CWA anzeigen (Namentlicher Testnachweis)", "processing-consent": "Das Einverständnis des Getesteten zum Übermitteln des Testergebnisses und des pseudonymen Codes an das Serversystem des RKI zum Zweck des Ergebnisabrufs in der Corona-Warn-App wurde erteilt. Es wurde darauf hingewiesen, dass das Testergebnis in der App hierbei nicht als namentlicher Testnachweis verwendet werden kann. Dem Getesteten wurden Hinweise zum Datenschutz ausgehändigt.", "patientdata-exclude": "Das Einverständnis des Getesteten zum Übermitteln des Testergebnisses und des pseudonymen Codes an das Serversystem des RKI zum Zweck des Ergebnisabrufs in der Corona-Warn-App wurde erteilt. Der Getestete willigte außerdem in die Übermittlung von Name und Geburtsdatum an die App zur Anzeige des Testergebnisses in der App als namentlicher Testnachweis ein. Dem Getesteten wurden Hinweise zum Datenschutz ausgehändigt.", "bill-status": "KV Abrechnung", @@ -46,15 +46,15 @@ "result-positive": "Positiv", "result-negative": "Negativ", "result-failed": "Failed", - "process-number":"Proben-ID", - "logout":"Logout", - "wrong-process-number":"Falsche Vorgangsnummer", - "unknown-process-number":"Unbekannte Vorgangsnummer: {{processNo}}", - "server-error":"Datenübermittlungsfehler: {{status}}", + "process-number": "Proben-ID", + "logout": "Logout", + "wrong-process-number": "Falsche Vorgangsnummer", + "unknown-process-number": "Unbekannte Vorgangsnummer: {{processNo}}", + "server-error": "Datenübermittlungsfehler: {{status}}", "server-not-reachable": "Server unerreichbar", "connection-error": "Verbindungsfehler: {{message}}", "qr-scan": "QR-Code scan", - "qr-scan-https-only" : "QR-Scan braucht eine HTTPS Verbindung", + "qr-scan-https-only": "QR-Scan braucht eine HTTPS Verbindung", "qr-code-no-patient-data": "QR-code enthält keine Patientendaten", "error-message": "Fehlermeldung", "serverError": "Es ist ein Fehler aufgetreten: ", @@ -68,18 +68,26 @@ "timerange": "Testzeitraum", "from": "am", "to": "bis", - "filter-none":"alle", + "filter-none": "alle", "filter-record-result": "Testergebnis", - "search":"Suchen", - "dp-title":"Datenschutzhinweis", - "imprint-title":"Impressum", + "search": "Suchen", + "dp-title": "Datenschutzhinweis", + "imprint-title": "Impressum", "standardised-first-name": "Standardisierter Vorname", "standardised-name": "Standardisierter Name", "testManufacturers": "Testhersteller und -name", "testId-input-header": "Eingabe Proben-ID", "error-processId-data-load": "Die eingegebene Proben-ID ist uns nicht bekannt!", - "ok":"OK", - "change-password":"Passwort ändern", - "dccConsent":"Patient wünscht ein offizielles COVID-Testzertifikat der EU (DCC).", - "user-management":"Benutzerverwaltung" -} + "ok": "OK", + "change-password": "Passwort ändern", + "dccConsent": "Patient wünscht ein offizielles COVID-Testzertifikat der EU (DCC).", + "user-management": "Benutzerverwaltung", + "user": "Benutzer", + "user-name": "Benutzername", + "group": "Gruppe", + "groups": "Gruppen", + "roles": "Rollen", + "add-user": "Neuen Benutzer hinzufügen", + "add-group": "Neue Gruppe hinzufügen", + "back": "Zurück" +} \ No newline at end of file diff --git a/src/assets/i18n/en/translation.json b/src/assets/i18n/en/translation.json index b7a000f..118305a 100644 --- a/src/assets/i18n/en/translation.json +++ b/src/assets/i18n/en/translation.json @@ -26,10 +26,10 @@ "city": "City", "street": "Street", "house-number": "House Number", - "phone-number":"Phone Number", - "email-address":"E-Mail Address", - "test-id":"Test-ID", - "test-name":"Test-Name", + "phone-number": "Phone Number", + "email-address": "E-Mail Address", + "test-id": "Test-ID", + "test-name": "Test-Name", "processing-consent": "Consent to processing in CWA", "bill-status": "bill status", "data-privacy-approve": "Approve Dataprivacy", @@ -37,21 +37,21 @@ "patient-data-correction": "Correct patient data", "process-finish": "Process finish", "qr-code": "QR Code", - "patient-data":"Patient data", + "patient-data": "Patient data", "cancel": "Cancel", "data-submit": "Submit Data", "result-positiv": "Positive", "result-negative": "Negative", "result-failed": "Failed", - "process-number":"Process number", - "logout":"Logout", - "wrong-process-number":"Wrong process number", - "unknown-process-number":"Unknown process number: {{processNo}}", - "server-error":"server error: {{status}}", + "process-number": "Process number", + "logout": "Logout", + "wrong-process-number": "Wrong process number", + "unknown-process-number": "Unknown process number: {{processNo}}", + "server-error": "server error: {{status}}", "server-not-reachable": "server not reachable", "connection-error": "connection error: {{message}}", "qr-scan": "QR-Code scan", - "qr-scan-https-only" : "QR-Scan will work only with https", + "qr-scan-https-only": "QR-Scan will work only with https", "qr-code-no-patient-data": "QR-code does not contain patient data", "error-message": "Error Message", "serverError": "An error occured: ", @@ -65,17 +65,25 @@ "timerange": "Timerange", "from": "from", "to": "to", - "filter-none":"all", + "filter-none": "all", "filter-record-result": "testresult", - "search":"search", - "dp-title":"Dataprivacy", - "imprint-title":"Imprint", + "search": "search", + "dp-title": "Dataprivacy", + "imprint-title": "Imprint", "standardised-first-name": "Standardised Given name", "standardised-name": "Standardised Family name", "testManufacturers": "Test manufacturers and names", "testId-input-header": "Process number input", "error-processId-data-load": "The entered sample ID is not known!", - "ok":"OK", - "change-password":"Change Password", - "user-management":"User Management" + "ok": "OK", + "change-password": "Change Password", + "user-management": "User Management", + "user": "User", + "user-name": "Username", + "group": "Group", + "groups": "Groups", + "roles": "Roles", + "add-user": "Add new user", + "add-group": "Add new group", + "back": "Back" } \ No newline at end of file diff --git a/src/components/failed-report.component.tsx b/src/components/failed-report.component.tsx index 3f63147..ddf4271 100644 --- a/src/components/failed-report.component.tsx +++ b/src/components/failed-report.component.tsx @@ -27,7 +27,7 @@ import { useTranslation } from 'react-i18next'; import DatePicker from 'react-datepicker'; import CwaSpinner from './spinner/spinner.component'; -import PagedList from './paged-list.component'; +import PagedList from './modules/paged-list.component'; import { useGetPDF, useGetPositiveForTimeRange } from '../api'; import { TestResult } from '../misc/enum'; diff --git a/src/components/group-modal.component.tsx b/src/components/group-modal.component.tsx deleted file mode 100644 index 5901411..0000000 --- a/src/components/group-modal.component.tsx +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Corona-Warn-App / cwa-quick-test-frontend - * - * (C) 2021, T-Systems International GmbH - * - * Deutsche Telekom AG and all other contributors / - * copyright owners license this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this - * file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { Button, Modal, Form, Col, Row } from 'react-bootstrap' - -import '../i18n'; -import { useTranslation } from 'react-i18next'; -import { FormGroupTextarea, FormGroupInput } from './modules/form-group.component'; -import { IGroupDetails, IGroupNode, IGroup } from '../misc/user'; -import { useGetGroupDetails } from '../api'; -import CwaSpinner from './spinner/spinner.component'; - -const emptyGroup: IGroupDetails = { - id: '', - pocId: '', - name: '', - pocDetails: '', -} - -const GroupModal = (props: any) => { - - const [btnOkDisabled, setBtnOkDisabled] = React.useState(true); - const { t } = useTranslation(); - - const [data, setData] = React.useState(''); - const [validated, setValidated] = React.useState(false); - - const groupReloaded = (group: IGroupDetails) => { - if (group) { - setData(unpackData(group.pocDetails)) - group.parentGroup = props.parentGroupId; - } - setBtnOkDisabled(false); - } - - const [group, updateGroup, setGroup] = useGetGroupDetails(groupReloaded, props.handleError); - - const handleCancel = () => { - props.onCancel(); - } - - const unpackData = (data:string) => { - if (data) { - data = data.replaceAll(',','\n') - } else { - data = '' - } - return data; - } - - const packData = (data:string) => { - if (data) { - data = data.replaceAll('\n',',') - } - return data; - } - - const handleOk = () => { - setBtnOkDisabled(true); - if (props.handleOk) { - group.pocDetails = packData(data); - props.handleOk(group); - } - } - - const handleEnter = () => { - setBtnOkDisabled(false); - if (props.groupId) { - updateGroup(props.groupId); - } else { - setGroup({...emptyGroup}); - setData('') - } - } - - const updateGroupProp = (name:string, value:any) => { - const ngroup = { ...group, [name]: value}; - setGroup(ngroup); - } - - const handleSubmit = (event: React.FormEvent) => { - const form = event.currentTarget; - event.preventDefault(); - event.stopPropagation(); - - setValidated(true); - - if (form.checkValidity()) { - handleOk(); - } - } - - const isNew = !(group && group.id); - - const selfIdOrChildren: string[] = []; - const collectChildren = (idlist: string[], parentNode: IGroup) => { - if (parentNode) { - idlist.push(parentNode.id); - parentNode.children.forEach(child => collectChildren(idlist, child as IGroup)); - } - } - if (!isNew) { - const node = props.groups.find((groupNode: IGroupNode) => groupNode.group.id === group.id); - if (node) { - collectChildren(selfIdOrChildren, node.group); - } - } - const fList = props.groups.filter((groupNode: IGroupNode) => selfIdOrChildren.indexOf(groupNode.group.id)<0) - const groupOptions = fList.map((groupNode: IGroupNode) => - - ); - groupOptions.push(); - - return ( - -
- - {isNew ? 'Neue Gruppe anlegen' : 'Gruppe bearbeiten'} - - - {!isNew ? - - Übergeordnete Gruppe - - updateGroupProp('parentGroup',ent.target.value)} - > - {groupOptions} - - - : null} - < FormGroupInput controlId='formFirstName' title="Name" - value={group ? group.name : ''} - required - onChange={(evt: any) => updateGroupProp('name',evt.target.value)} - maxLength={50} - /> - < FormGroupInput controlId='formFirstName' title="POC Id" - value={group && group.pocId ? group.pocId : ''} - onChange={(evt: any) => updateGroupProp('pocId',evt.target.value)} - maxLength={50} - /> - < FormGroupTextarea controlId='formLastName' title="Data" - value={data} - onChange={(evt: any) => setData(evt.target.value)} - type='textarea' - maxLength={300} - /> - - - {btnOkDisabled ? : null} - - - -
-
- ) -} - -export default GroupModal; \ No newline at end of file diff --git a/src/components/landing-page.component.tsx b/src/components/landing-page.component.tsx index cb866db..ef470c8 100644 --- a/src/components/landing-page.component.tsx +++ b/src/components/landing-page.component.tsx @@ -34,7 +34,7 @@ const LandingPage = (props: any) => { const navigation = useNavigation(); const { t } = useTranslation(); - const { keycloak, initialized } = useKeycloak(); + const { keycloak } = useKeycloak(); const [isInit, setIsInit] = React.useState(false) diff --git a/src/components/confirm-modal.component.tsx b/src/components/modals/confirm-modal.component.tsx similarity index 99% rename from src/components/confirm-modal.component.tsx rename to src/components/modals/confirm-modal.component.tsx index 2496575..4a8780c 100644 --- a/src/components/confirm-modal.component.tsx +++ b/src/components/modals/confirm-modal.component.tsx @@ -22,7 +22,7 @@ import React from 'react'; import { Button, Col, Container, Modal, Row } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; const ConfirmModal = (props: any) => { diff --git a/src/components/dataprivacy.component.tsx b/src/components/modals/dataprivacy.component.tsx similarity index 99% rename from src/components/dataprivacy.component.tsx rename to src/components/modals/dataprivacy.component.tsx index 101f4dc..6c55e3b 100644 --- a/src/components/dataprivacy.component.tsx +++ b/src/components/modals/dataprivacy.component.tsx @@ -22,7 +22,7 @@ import React from 'react'; import { Modal, Row, Col, Card, Button, Container, Table } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/error-page.component.tsx b/src/components/modals/error-page.component.tsx similarity index 99% rename from src/components/error-page.component.tsx rename to src/components/modals/error-page.component.tsx index 284bba6..5882533 100644 --- a/src/components/error-page.component.tsx +++ b/src/components/modals/error-page.component.tsx @@ -22,7 +22,7 @@ import React from 'react'; import { Button, Card, Col, Modal, Row } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; const ErrorPage = (props: any) => { diff --git a/src/components/modals/group-modal.component.tsx b/src/components/modals/group-modal.component.tsx new file mode 100644 index 0000000..3036045 --- /dev/null +++ b/src/components/modals/group-modal.component.tsx @@ -0,0 +1,270 @@ +/* + * Corona-Warn-App / cwa-quick-test-frontend + * + * (C) 2021, T-Systems International GmbH + * + * Deutsche Telekom AG and all other contributors / + * copyright owners license this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { Button, Modal, Form, Col, Row, Spinner, Fade, Container } from 'react-bootstrap' + +import '../../i18n'; +import { useTranslation } from 'react-i18next'; +import { FormGroupTextarea, FormGroupInput, FormGroupSelect } from '../modules/form-group.component'; +import { IGroupDetails, IGroupNode, IGroup } from '../../misc/user'; +import { useGetGroupDetails } from '../../api'; +import { v4 as newUuid } from 'uuid'; +import CwaSpinner from '../spinner/spinner.component'; + +const emptyGroup: IGroupDetails = { + id: '', + pocId: '', + name: '', + pocDetails: '', +} + +const GroupModal = (props: any) => { + + const [btnOkDisabled, setBtnOkDisabled] = React.useState(true); + const { t } = useTranslation(); + + const [data, setData] = React.useState(''); + const [validated, setValidated] = React.useState(false); + const [isReady, setIsReady] = React.useState(false); + + const groupReloaded = (group: IGroupDetails) => { + if (group) { + setData(unpackData(group.pocDetails)) + group.parentGroup = props.parentGroupId; + } + setBtnOkDisabled(false); + } + + const [group, updateGroup, setGroup] = useGetGroupDetails(groupReloaded, props.handleError); + + React.useEffect(() => { + setBtnOkDisabled(false); + if (props.groupId) { + updateGroup(props.groupId); + } else { + setGroup({ ...emptyGroup }); + setData('') + } + }, []) + + React.useEffect(() => { + if (group) { + console.log('möp'); + + setIsReady(true); + } + }, [group]) + + + const handleCancel = () => { + props.onCancel(); + } + + const unpackData = (data: string) => { + if (data) { + data = data.replaceAll(',', '\n') + } else { + data = '' + } + return data; + } + + const packData = (data: string) => { + if (data) { + data = data.replaceAll('\n', ',') + } + return data; + } + + const handleOk = () => { + setBtnOkDisabled(true); + if (props.handleOk) { + group.pocDetails = packData(data); + + if (!group.pocId) { + group.pocId = newUuid(); + } + + props.handleOk(group); + } + } + + const handleEnter = () => { + setBtnOkDisabled(false); + if (props.groupId) { + updateGroup(props.groupId); + } else { + setGroup({ ...emptyGroup }); + setData('') + } + } + + const handleExited = () => { + setIsReady(false); + } + + const updateGroupProp = (name: string, value: any) => { + const ngroup = { ...group, [name]: value }; + setGroup(ngroup); + } + + const handleSubmit = (event: React.FormEvent) => { + const form = event.currentTarget; + event.preventDefault(); + event.stopPropagation(); + + setValidated(true); + + if (form.checkValidity()) { + handleOk(); + } + } + + const isNew = !(group && group.id); + + const selfIdOrChildren: string[] = []; + const collectChildren = (idlist: string[], parentNode: IGroup) => { + if (parentNode) { + idlist.push(parentNode.id); + parentNode.children.forEach(child => collectChildren(idlist, child as IGroup)); + } + } + if (!isNew) { + const node = props.groups.find((groupNode: IGroupNode) => groupNode.group.id === group.id); + if (node) { + collectChildren(selfIdOrChildren, node.group); + } + } + const fList = props.groups.filter((groupNode: IGroupNode) => selfIdOrChildren.indexOf(groupNode.group.id) < 0) + const groupOptions = fList.map((groupNode: IGroupNode) => + + ); + groupOptions.push(); + + return ( + + {!isReady + ? + : +
+ + {isNew ? 'Neue Gruppe anlegen' : 'Gruppe bearbeiten'} + + + + {isNew + ? <> + : <> + updateGroupProp('parentGroup', ent.target.value)} + options={groupOptions} + /> + +
+ + } + + < FormGroupInput controlId='formFirstName' title="Name" + value={group ? group.name : ''} + required + onChange={(evt: any) => updateGroupProp('name', evt.target.value)} + maxLength={50} + /> + + < FormGroupTextarea controlId='formLastName' title="Data" + value={data} + onChange={(evt: any) => setData(evt.target.value)} + type='textarea' + maxLength={300} + /> + + {!(group && group.pocId) + ? <> + : <> +
+ < FormGroupInput controlId='formPocId' title="POC Id" + value={group && group.pocId ? group.pocId : ''} + readOnly + /> + + } + +
+ + + + + + + + + + + + + +
+
+ } +
+ ) +} + +export default GroupModal; \ No newline at end of file diff --git a/src/components/imprint.component.tsx b/src/components/modals/imprint.component.tsx similarity index 99% rename from src/components/imprint.component.tsx rename to src/components/modals/imprint.component.tsx index a2ed819..07f5eb2 100644 --- a/src/components/imprint.component.tsx +++ b/src/components/modals/imprint.component.tsx @@ -22,7 +22,7 @@ import React from 'react'; import { Modal, Row, Col, Card, Button, Container } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; diff --git a/src/components/notification-page.component.tsx b/src/components/modals/notification-page.component.tsx similarity index 95% rename from src/components/notification-page.component.tsx rename to src/components/modals/notification-page.component.tsx index 6a62c4f..438ca86 100644 --- a/src/components/notification-page.component.tsx +++ b/src/components/modals/notification-page.component.tsx @@ -22,10 +22,10 @@ import React from 'react'; import { Alert, Modal, Image } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; -import successIcon from '../assets/images/icon_success.svg'; +import successIcon from '../../assets/images/icon_success.svg'; const NotificationPage = (props: any) => { diff --git a/src/components/process-input.component.tsx b/src/components/modals/process-input.component.tsx similarity index 96% rename from src/components/process-input.component.tsx rename to src/components/modals/process-input.component.tsx index 96d834a..9ac3535 100644 --- a/src/components/process-input.component.tsx +++ b/src/components/modals/process-input.component.tsx @@ -22,11 +22,11 @@ import React from 'react'; import { Button, Card, Col, Container, Modal, Row, Spinner } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; -import { FormGroupInput } from './modules/form-group.component'; -import utils from '../misc/utils'; -import { IShortHashedGuid, useGetPendingProcessIds } from '../api'; +import { FormGroupInput } from '../modules/form-group.component'; +import utils from '../../misc/utils'; +import { IShortHashedGuid, useGetPendingProcessIds } from '../../api'; const ProcessIdInput = (props: any) => { diff --git a/src/components/user-modal.component.tsx b/src/components/modals/user-modal.component.tsx similarity index 97% rename from src/components/user-modal.component.tsx rename to src/components/modals/user-modal.component.tsx index 0b0dec7..7d4c8f5 100644 --- a/src/components/user-modal.component.tsx +++ b/src/components/modals/user-modal.component.tsx @@ -22,10 +22,10 @@ import React from 'react'; import { Button, Col, Modal, Row, Form } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; -import { FormGroupConsentCkb, FormGroupInput } from './modules/form-group.component'; -import { IUser, IGroupNode } from '../misc/user'; +import { FormGroupConsentCkb, FormGroupInput } from '../modules/form-group.component'; +import { IUser, IGroupNode } from '../../misc/user'; const UserModal = (props: any) => { diff --git a/src/components/footer.component.tsx b/src/components/modules/footer.component.tsx similarity index 95% rename from src/components/footer.component.tsx rename to src/components/modules/footer.component.tsx index 321872a..dc64035 100644 --- a/src/components/footer.component.tsx +++ b/src/components/modules/footer.component.tsx @@ -21,10 +21,10 @@ import { Button, Image, Row } from 'react-bootstrap' -import '../i18n'; +import '../../i18n'; import { useTranslation } from 'react-i18next'; -import DataProtectLogo from '../assets/images/data_protect.png' +import DataProtectLogo from '../../assets/images/data_protect.png' import React from 'react'; diff --git a/src/components/modules/form-group.component.tsx b/src/components/modules/form-group.component.tsx index a4fca0a..c5b4210 100644 --- a/src/components/modules/form-group.component.tsx +++ b/src/components/modules/form-group.component.tsx @@ -47,7 +47,7 @@ export const FormGroupTextarea = (props: any) => { { ) } +export const FormGroupSelect = (props: any) => { + return (!(props && props.options) + ? <> + : + ) +} + export const FormGroupValueSetSelect = (props: any) => { const valueSet = props.valueSet; @@ -189,23 +211,16 @@ export const FormGroupValueSetSelect = (props: any) => { return result; } - return (!(props && options) ? <> : - + return (!(props && options) + ? <> + :