gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant-backoffice] branch master updated (045cd4b -> 1d24593)


From: gnunet
Subject: [taler-merchant-backoffice] branch master updated (045cd4b -> 1d24593)
Date: Thu, 11 Feb 2021 18:55:34 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a change to branch master
in repository merchant-backoffice.

    from 045cd4b  test hooks example
     new aa3858a  refactor table, taking out the modal
     new 1737dfe  splt card table into components
     new 1d24593  removing secret-token

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/components/auth/LoginPage.tsx       |   2 +-
 src/components/hooks/backend.ts         |   2 +-
 src/routes/instances/CardTable.tsx      |  72 ++++++++++++
 src/routes/instances/CreateModal.tsx    |   9 +-
 src/routes/instances/DeleteAllModal.tsx |  29 -----
 src/routes/instances/DeleteModal.tsx    |   6 +-
 src/routes/instances/EmptyTable.tsx     |  10 ++
 src/routes/instances/Table.tsx          | 187 ++++++++------------------------
 src/routes/instances/UpdateModal.tsx    |   2 +-
 src/routes/instances/View.tsx           |  44 ++++++--
 10 files changed, 177 insertions(+), 186 deletions(-)
 create mode 100644 src/routes/instances/CardTable.tsx
 delete mode 100644 src/routes/instances/DeleteAllModal.tsx
 create mode 100644 src/routes/instances/EmptyTable.tsx

diff --git a/src/components/auth/LoginPage.tsx 
b/src/components/auth/LoginPage.tsx
index 956e573..616b0cd 100644
--- a/src/components/auth/LoginPage.tsx
+++ b/src/components/auth/LoginPage.tsx
@@ -23,7 +23,7 @@ export default function LoginPage({ onLogIn }: Props): VNode {
           <div class="field-body">
             <div class="field">
               <p class="control is-expanded has-icons-left">
-                <input class="input" type="text" placeholder="abcdef" 
name="id" value={token} onInput={e => update(e?.currentTarget.value)} />
+                <input class="input" type="text" placeholder="abcdef" 
name="id" value={token} onInput={(e): void => update(e?.currentTarget.value)} />
               </p>
             </div>
           </div>
diff --git a/src/components/hooks/backend.ts b/src/components/hooks/backend.ts
index 2f3fb27..bd2bcba 100644
--- a/src/components/hooks/backend.ts
+++ b/src/components/hooks/backend.ts
@@ -20,7 +20,7 @@ type Methods = 'get' | 'post' | 'patch' | 'delete' | 'put';
 
 async function request(url: string, method?: Methods, data?: object): 
Promise<any> {
   const token = localStorage.getItem(TOKEN_KEY)
-  const headers = token ? { Authorization: `Bearer secret-token:${token}` } : 
undefined
+  const headers = token ? { Authorization: `Bearer ${token}` } : undefined
 
   try {
     const res = await axios({
diff --git a/src/routes/instances/CardTable.tsx 
b/src/routes/instances/CardTable.tsx
new file mode 100644
index 0000000..551a543
--- /dev/null
+++ b/src/routes/instances/CardTable.tsx
@@ -0,0 +1,72 @@
+import { h, VNode } from "preact";
+import { useEffect, useState } from "preact/hooks";
+import { MerchantBackend, WidthId as WithId } from "../../declaration";
+import EmptyTable from "./EmptyTable";
+import Table from "./Table";
+
+interface Props {
+  instances: MerchantBackend.Instances.Instance[];
+  onSelect: (id: string | null, action: 'UPDATE' | 'DELETE') => void;
+  onCreate: () => void;
+  selected: MerchantBackend.Instances.QueryInstancesResponse & WithId | 
undefined;
+}
+
+interface Actions {
+  element: MerchantBackend.Instances.Instance;
+  type: 'DELETE' | 'UPDATE';
+}
+
+function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
+  return value !== null && value !== undefined;
+}
+
+function buildActions(intances: MerchantBackend.Instances.Instance[], 
selected: string[], action: 'DELETE'): Actions[] {
+  return selected.map(id => intances.find(i => i.id === id))
+    .filter(notEmpty)
+    .map(id => ({ element: id, type: action }))
+}
+
+export default function CardTable({ instances, onCreate, onSelect, selected }: 
Props): VNode {
+  const [actionQueue, actionQueueHandler] = useState<Actions[]>([]);
+  const [rowSelection, rowSelectionHandler] = useState<string[]>([])
+
+  useEffect(() => {
+    if (actionQueue.length > 0 && !selected && actionQueue[0].type == 
'DELETE') {
+      onSelect(actionQueue[0].element.id, 'DELETE')
+      actionQueueHandler(actionQueue.slice(1))
+    }
+  }, [actionQueue, selected, onSelect])
+
+  useEffect(() => {
+    if (actionQueue.length > 0 && !selected && actionQueue[0].type == 
'UPDATE') {
+      onSelect(actionQueue[0].element.id, 'UPDATE')
+      actionQueueHandler(actionQueue.slice(1))
+    }
+  }, [actionQueue, selected, onSelect])
+
+
+  return <div class="card has-table">
+    <header class="card-header">
+      <p class="card-header-title"><span class="icon"><i class="mdi 
mdi-account-multiple" /></span>Instances</p>
+      
+      <button class={rowSelection.length > 0 ? "card-header-icon" : 
"card-header-icon is-hidden"} 
+        type="button" onClick={(): void => 
actionQueueHandler(buildActions(instances, rowSelection, 'DELETE'))} >
+
+        <span class="icon"><i class="mdi mdi-trash-can" /></span>
+      </button>
+      <button class="card-header-icon" type="button" onClick={onCreate}>
+        <span class="icon"><i class="mdi mdi-plus" /></span>
+      </button>
+    </header>
+    <div class="card-content">
+      <div class="b-table has-pagination">
+        <div class="table-wrapper has-mobile-cards">
+          {instances.length > 0 ?
+            <Table instances={instances} onSelect={onSelect} 
rowSelection={rowSelection} rowSelectionHandler={rowSelectionHandler} /> :
+            <EmptyTable />
+          }
+        </div>
+      </div>
+    </div>
+  </div>
+}
\ No newline at end of file
diff --git a/src/routes/instances/CreateModal.tsx 
b/src/routes/instances/CreateModal.tsx
index e1b53da..7eff286 100644
--- a/src/routes/instances/CreateModal.tsx
+++ b/src/routes/instances/CreateModal.tsx
@@ -36,7 +36,6 @@ const schema = yup.object().shape({
 });
 
 interface Props {
-  active: boolean;
   onCancel: () => void;
   onConfirm: (i: MerchantBackend.Instances.InstanceConfigurationMessage) => 
void;
 }
@@ -45,8 +44,8 @@ interface KeyValue {
   [key: string]: string;
 }
 
-export default function CreateModal({ active, onCancel, onConfirm }: Props): 
VNode {
-  const [value, valueHandler] = useState((active || {}) as any)
+export default function CreateModal({ onCancel, onConfirm }: Props): VNode {
+  const [value, valueHandler] = useState({} as any)
   const [errors, setErrors] = useState<KeyValue>({})
 
   const submit = (): void => {
@@ -60,7 +59,7 @@ export default function CreateModal({ active, onCancel, 
onConfirm }: Props): VNo
     }
   }
 
-  return <ConfirmModal description="create instance" active={active} 
onConfirm={submit} onCancel={onCancel}>
+  return <ConfirmModal description="create instance" active onConfirm={submit} 
onCancel={onCancel}>
     {Object.keys(schema.fields).map(f => {
 
       const info = schema.fields[f].describe()
@@ -73,7 +72,7 @@ export default function CreateModal({ active, onCancel, 
onConfirm }: Props): VNo
         <div class="field-body">
           <div class="field">
             <p class="control is-expanded has-icons-left">
-              <input class="input" type="text" 
placeholder={info?.meta?.placeholder} readonly={info?.meta?.readonly} name={f} 
value={value[f]} onChange={e => valueHandler((prev: any) => ({ ...prev, [f]: 
e.currentTarget.value }))} />
+              <input class="input" type="text" 
placeholder={info?.meta?.placeholder} readonly={info?.meta?.readonly} name={f} 
value={value[f]} onChange={(e): void => valueHandler((prev: any) => ({ ...prev, 
[f]: e.currentTarget.value }))} />
               {info?.meta?.help}
             </p>
             {errors[f] ? <p class="help is-danger">{errors[f]}</p> : null}
diff --git a/src/routes/instances/DeleteAllModal.tsx 
b/src/routes/instances/DeleteAllModal.tsx
deleted file mode 100644
index 6f81e2c..0000000
--- a/src/routes/instances/DeleteAllModal.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { h, VNode } from "preact";
-import { MerchantBackend } from "../../declaration";
-
-interface Props {
-  element: MerchantBackend.Instances.Instance | null;
-  onCancel: () => void;
-  onConfirm: (i: MerchantBackend.Instances.Instance) => void;
-}
-
-export default function DeleteAllModal({ element, onCancel, onConfirm }: 
Props): VNode {
-  return <div class={element ? "modal is-active is-clipped" : "modal"}>
-    <div class="modal-background jb-modal-close" onClick={e => onCancel()} />
-    <div class="modal-card">
-      <header class="modal-card-head">
-        <p class="modal-card-title">Confirm action</p>
-        <button class="delete jb-modal-close" aria-label="close" onClick={e => 
onCancel()} />
-      </header>
-      <section class="modal-card-body">
-        <p>This will permanently delete instance "{element?.name}" with id 
<b>{element?.id}</b></p>
-        <p>Please confirm this action</p>
-      </section>
-      <footer class="modal-card-foot">
-        <button class="button jb-modal-close" onClick={e => onCancel()} 
>Cancel</button>
-        <button class="button is-danger jb-modal-close" onClick={element ? e 
=> onConfirm(element) : undefined} >Delete</button>
-      </footer>
-    </div>
-    <button class="modal-close is-large jb-modal-close" aria-label="close" 
onClick={e => onCancel()} />
-  </div>
-}
\ No newline at end of file
diff --git a/src/routes/instances/DeleteModal.tsx 
b/src/routes/instances/DeleteModal.tsx
index 98dbfe8..276dab4 100644
--- a/src/routes/instances/DeleteModal.tsx
+++ b/src/routes/instances/DeleteModal.tsx
@@ -1,11 +1,11 @@
 import { h, VNode } from "preact";
-import { MerchantBackend } from "../../declaration";
+import { MerchantBackend, WidthId } from "../../declaration";
 import ConfirmModal from "./ConfirmModal";
 
 interface Props {
-  element: MerchantBackend.Instances.Instance;
+  element: MerchantBackend.Instances.QueryInstancesResponse & WidthId;
   onCancel: () => void;
-  onConfirm: (i: MerchantBackend.Instances.Instance) => void;
+  onConfirm: (i: MerchantBackend.Instances.QueryInstancesResponse & WidthId) 
=> void;
 }
 
 export default function DeleteModal({ element, onCancel, onConfirm }: Props): 
VNode {
diff --git a/src/routes/instances/EmptyTable.tsx 
b/src/routes/instances/EmptyTable.tsx
new file mode 100644
index 0000000..5aff8ef
--- /dev/null
+++ b/src/routes/instances/EmptyTable.tsx
@@ -0,0 +1,10 @@
+import { h, VNode } from "preact";
+
+export default function EmptyTable(): VNode {
+  return <div class="content has-text-grey has-text-centered">
+    <p>
+      <span class="icon is-large"><i class="mdi mdi-emoticon-sad mdi-48px" 
/></span>
+    </p>
+    <p>No instance configured yet, setup one pressing the + button </p>
+  </div>
+}
diff --git a/src/routes/instances/Table.tsx b/src/routes/instances/Table.tsx
index e6d1474..761b068 100644
--- a/src/routes/instances/Table.tsx
+++ b/src/routes/instances/Table.tsx
@@ -1,153 +1,62 @@
-import { h, VNode } from "preact";
-import { useEffect, useState, StateUpdater } from "preact/hooks";
-import { MerchantBackend, WidthId as WithId } from "../../declaration";
-import DeleteModal from './DeleteModal'
-import UpdateModal from './UpdateModal'
-import CreateModal from './CreateModal'
+import { h, VNode } from "preact"
+import { StateUpdater } from "preact/hooks"
+import { MerchantBackend } from "../../declaration"
 
 interface Props {
+  rowSelection: string[];
   instances: MerchantBackend.Instances.Instance[];
-  onCreate: (d: MerchantBackend.Instances.InstanceConfigurationMessage) => 
void;
-  onUpdate: (id: string, d: 
MerchantBackend.Instances.InstanceReconfigurationMessage) => void;
-  onDelete: (id: string) => void;
-  onSelect: (id: string | null) => void;
-  selected: MerchantBackend.Instances.QueryInstancesResponse & WithId | 
undefined;
+  onSelect: (id: string | null, action: 'UPDATE' | 'DELETE') => void;
+  rowSelectionHandler: StateUpdater<string[]>;
 }
 
 function toggleSelected<T>(id: T): (prev: T[]) => T[] {
   return (prev: T[]): T[] => prev.indexOf(id) == -1 ? [...prev, id] : 
prev.filter(e => e != id)
 }
 
-interface Actions {
-  element: MerchantBackend.Instances.Instance;
-  type: 'DELETE' | 'UPDATE';
-}
-
-function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
-  return value !== null && value !== undefined;
-}
-
-function buildActions(intances: MerchantBackend.Instances.Instance[], 
selected: string[], action: 'DELETE'): Actions[] {
-  return selected.map(id => intances.find(i => i.id === id))
-    .filter(notEmpty)
-    .map(id => ({ element: id, type: action }))
-}
-
-const EmptyTable = () => <div class="content has-text-grey has-text-centered">
-  <p>
-    <span class="icon is-large"><i class="mdi mdi-emoticon-sad mdi-48px" 
/></span>
-  </p>
-  <p>No instance configured yet, setup one pressing the + button </p>
-</div>
-
-interface TableProps {
-  rowSelection: string[];
-  instances: MerchantBackend.Instances.Instance[];
-  onSelect: (id: string | null) => void;
-  rowSelectionHandler: StateUpdater<string[]>;
-  toBeDeletedHandler:  StateUpdater<MerchantBackend.Instances.Instance | null>;
-}
-
-const Table = ({ rowSelection, rowSelectionHandler, instances, onSelect, 
toBeDeletedHandler }: TableProps): VNode => (
-  <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
-    <thead>
-      <tr>
-        <th class="is-checkbox-cell">
-          <label class="b-checkbox checkbox">
-            <input type="checkbox" checked={rowSelection.length === 
instances.length} onClick={e => rowSelectionHandler(rowSelection.length === 
instances.length ? [] : instances.map(i => i.id))} />
-            <span class="check" />
-          </label>
-        </th>
-        <th>id</th>
-        <th>name</th>
-        <th>public key</th>
-        <th>payments</th>
-        <th />
-      </tr>
-    </thead>
-    <tbody>
-      {instances.map(i => {
-        return <tr>
-          <td class="is-checkbox-cell">
+export default function Table({ rowSelection, rowSelectionHandler, instances, 
onSelect }: Props): VNode {
+  return (
+    <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+      <thead>
+        <tr>
+          <th class="is-checkbox-cell">
             <label class="b-checkbox checkbox">
-              <input type="checkbox" checked={rowSelection.indexOf(i.id) != 
-1} onClick={e => rowSelectionHandler(toggleSelected(i.id))} />
+              <input type="checkbox" checked={rowSelection.length === 
instances.length} onClick={(): void => rowSelectionHandler(rowSelection.length 
=== instances.length ? [] : instances.map(i => i.id))} />
               <span class="check" />
             </label>
-          </td>
-          <td >{i.id}</td>
-          <td >{i.name}</td>
-          <td >{i.merchant_pub}</td>
-          <td >{i.payment_targets}</td>
-          <td class="is-actions-cell">
-            <div class="buttons is-right">
-              <button class="button is-small is-primary" type="button" 
onClick={e => onSelect(i.id)}>
-                <span class="icon"><i class="mdi mdi-eye" /></span>
-              </button>
-              <button class="button is-small is-danger jb-modal" type="button" 
onClick={e => toBeDeletedHandler(i)}>
-                <span class="icon"><i class="mdi mdi-trash-can" /></span>
-              </button>
-            </div>
-          </td>
+          </th>
+          <th>id</th>
+          <th>name</th>
+          <th>public key</th>
+          <th>payments</th>
+          <th />
         </tr>
-      })}
-
-    </tbody>
-  </table>)
-
-
-export default function CardTable({ instances, onCreate, onDelete, onSelect, 
onUpdate, selected }: Props): VNode {
-  const [toBeCreated, toBeCreatedHandler] = useState<boolean>(false)
-  const [actionQueue, actionQueueHandler] = useState<Actions[]>([]);
-  const [toBeDeleted, toBeDeletedHandler] = 
useState<MerchantBackend.Instances.Instance | null>(null)
-
-  const [rowSelection, rowSelectionHandler] = useState<string[]>([])
-
-  useEffect(() => {
-    if (actionQueue.length > 0 && !toBeDeleted && actionQueue[0].type == 
'DELETE') {
-      toBeDeletedHandler(actionQueue[0].element)
-      actionQueueHandler(actionQueue.slice(1))
-    }
-  }, [actionQueue, toBeDeleted])
-
-  useEffect(() => {
-    if (actionQueue.length > 0 && !selected && actionQueue[0].type == 
'UPDATE') {
-      onSelect(actionQueue[0].element.id)
-      actionQueueHandler(actionQueue.slice(1))
-    }
-  }, [actionQueue, selected])
-
-
-  return <div class="card has-table">
-    <header class="card-header">
-      <p class="card-header-title"><span class="icon"><i class="mdi 
mdi-account-multiple" /></span>Instances</p>
-      <button class={rowSelection.length > 0 ? "card-header-icon" : 
"card-header-icon is-hidden"} type="button" onClick={e => 
actionQueueHandler(buildActions(instances, rowSelection, 'DELETE'))} >
-        <span class="icon"><i class="mdi mdi-trash-can" /></span>
-      </button>
-      <button class="card-header-icon" type="button" onClick={e => 
toBeCreatedHandler(true)}>
-        <span class="icon"><i class="mdi mdi-plus" /></span>
-      </button>
-    </header>
-    <div class="card-content">
-      <div class="b-table has-pagination">
-        <div class="table-wrapper has-mobile-cards">
-          {instances.length > 0 ?
-            <Table instances={instances} onSelect={onSelect} 
rowSelection={rowSelection} rowSelectionHandler={rowSelectionHandler} 
toBeDeletedHandler={toBeDeletedHandler} /> :
-            <EmptyTable />
-          }
-        </div>
-        {toBeDeleted ? <DeleteModal element={toBeDeleted} onCancel={() => 
toBeDeletedHandler(null)} onConfirm={(i) => {
-          onDelete(i.id)
-          toBeDeletedHandler(null);
-        }} /> : null}
-        {selected ? <UpdateModal element={selected} onCancel={() => 
onSelect(null)} onConfirm={(i) => {
-          onUpdate(selected.id, i)
-          onSelect(null);
-        }} /> : null}
-        {toBeCreated ? <CreateModal active={toBeCreated} onCancel={() => 
toBeCreatedHandler(false)} onConfirm={(i) => {
-          onCreate(i)
-          toBeCreatedHandler(false);
-        }} /> : null}
-      </div>
-    </div>
-  </div >
+      </thead>
+      <tbody>
+        {instances.map(i => {
+          return <tr>
+            <td class="is-checkbox-cell">
+              <label class="b-checkbox checkbox">
+                <input type="checkbox" checked={rowSelection.indexOf(i.id) != 
-1} onClick={(): void => rowSelectionHandler(toggleSelected(i.id))} />
+                <span class="check" />
+              </label>
+            </td>
+            <td >{i.id}</td>
+            <td >{i.name}</td>
+            <td >{i.merchant_pub}</td>
+            <td >{i.payment_targets}</td>
+            <td class="is-actions-cell">
+              <div class="buttons is-right">
+                <button class="button is-small is-primary" type="button" 
onClick={(): void => onSelect(i.id, 'UPDATE')}>
+                  <span class="icon"><i class="mdi mdi-eye" /></span>
+                </button>
+                <button class="button is-small is-danger jb-modal" 
type="button" onClick={(): void => onSelect(i.id, 'DELETE')}>
+                  <span class="icon"><i class="mdi mdi-trash-can" /></span>
+                </button>
+              </div>
+            </td>
+          </tr>
+        })}
+
+      </tbody>
+    </table>)
 }
\ No newline at end of file
diff --git a/src/routes/instances/UpdateModal.tsx 
b/src/routes/instances/UpdateModal.tsx
index d788a91..d729729 100644
--- a/src/routes/instances/UpdateModal.tsx
+++ b/src/routes/instances/UpdateModal.tsx
@@ -66,7 +66,7 @@ export default function UpdateModal({ element, onCancel, 
onConfirm }: Props): VN
               <input class="input" type="text" 
                   placeholder={info?.meta?.placeholder} 
readonly={info?.meta?.readonly} 
                   name={f} value={value[f]} 
-                  onChange={e => valueHandler((prev: any) => ({ ...prev, [f]: 
e.currentTarget.value }))} />
+                  onChange={(e): void => valueHandler((prev: any) => ({ 
...prev, [f]: e.currentTarget.value }))} />
               {info?.meta?.help}
             </p>
             {errors[f] ? <p class="help is-danger">{errors[f]}</p> : null}
diff --git a/src/routes/instances/View.tsx b/src/routes/instances/View.tsx
index 95af162..4305564 100644
--- a/src/routes/instances/View.tsx
+++ b/src/routes/instances/View.tsx
@@ -1,6 +1,10 @@
 import { h, VNode } from "preact";
+import { useState } from "preact/hooks";
 import { MerchantBackend, WidthId } from "../../declaration";
-import Table from './Table';
+import Table from './CardTable';
+import DeleteModal from './DeleteModal'
+import UpdateModal from './UpdateModal'
+import CreateModal from './CreateModal'
 
 interface Props {
   instances: MerchantBackend.Instances.Instance[];
@@ -13,6 +17,14 @@ interface Props {
 }
 
 export default function View({ instances, isLoading, onCreate, onDelete, 
onSelect, onUpdate, selected }: Props): VNode {
+  const [create, setCreate] = useState<boolean>(false)
+  const [action, setAction] = useState<'UPDATE' | 'DELETE' | null>(null)
+
+  const onSelectAction = (id: string | null, action?: 'UPDATE' | 'DELETE'): 
void => {
+    onSelect(id)
+    setAction(action || null)
+  }
+
   return <div id="app">
     <section class="section is-title-bar">
 
@@ -27,7 +39,8 @@ export default function View({ instances, isLoading, 
onCreate, onDelete, onSelec
         </div>
       </div>
     </section>
-    <section class={ isLoading ? "hero is-hero-bar" : "hero is-hero-bar 
is-loading" }>
+
+    <section class={isLoading ? "hero is-hero-bar" : "hero is-hero-bar 
is-loading"}>
       <div class="hero-body">
         <div class="level">
           <div class="level-left">
@@ -42,12 +55,29 @@ export default function View({ instances, isLoading, 
onCreate, onDelete, onSelec
       </div>
     </section>
     <section class="section is-main-section">
-      <Table instances={instances} onCreate={onCreate}
-        onUpdate={onUpdate}
-        onDelete={onDelete} onSelect={onSelect}
-        selected={selected}
-      />
+      <Table instances={instances} onSelect={onSelectAction} 
selected={selected} onCreate={(): void => setCreate(true)} />
     </section>
 
+    {selected && action === 'DELETE' ?
+      <DeleteModal element={selected} onCancel={(): void => 
onSelectAction(null)} onConfirm={(i): void => {
+        onDelete(i.id)
+        onSelectAction(null);
+      }}
+      />
+      : null}
+
+    {selected && action === 'UPDATE' ?
+      <UpdateModal element={selected} onCancel={(): void => 
onSelectAction(null)} onConfirm={(i): void => {
+        onUpdate(selected.id, i);
+        onSelectAction(null);
+      }}
+      />
+      : null}
+
+    {create ? <CreateModal onCancel={(): void => setCreate(false)} 
onConfirm={(i): void => {
+      onCreate(i)
+      setCreate(false);
+    }} /> : null}
+
   </div >
 }
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]