aboutsummaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx13
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx52
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx27
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx77
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx37
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx4
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx17
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx6
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx2
-rw-r--r--packages/merchant-backoffice-ui/src/paths/login/index.tsx17
12 files changed, 158 insertions, 98 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
index cbfe1d573..db73217ed 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/Table.tsx
@@ -66,7 +66,7 @@ export function CardTable({
<span class="icon">
<i class="mdi mdi-shopping" />
</span>
- <i18n.Translate>Products</i18n.Translate>
+ <i18n.Translate>Inventory</i18n.Translate>
</p>
<div class="card-header-icon" aria-label="more options">
<span
@@ -142,7 +142,7 @@ function Table({
<i18n.Translate>Taxes</i18n.Translate>
</th>
<th>
- <i18n.Translate>Profit</i18n.Translate>
+ <i18n.Translate>Sales</i18n.Translate>
</th>
<th>
<i18n.Translate>Stock</i18n.Translate>
@@ -190,18 +190,21 @@ function Table({
src={i.image ? i.image : emptyImage}
style={{
border: "solid black 1px",
- width: 100,
- height: 100,
+ maxHeight: "2em",
+ width: "auto",
+ height: "auto",
}}
/>
</td>
<td
+ class="has-tooltip-right"
+ data-tooltip={i.description}
onClick={() =>
rowSelection !== i.id && rowSelectionHandler(i.id)
}
style={{ cursor: "pointer" }}
>
- {i.description}
+ {i.description.length > 30 ? i.description.substring(0, 30) + "..." : i.description}
</td>
<td
onClick={() =>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
index 85c50e5ed..274a7c2ea 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
@@ -53,7 +53,7 @@ export default function ProductList({
onNotFound,
}: Props): VNode {
const result = useInstanceProducts();
- const { deleteProduct, updateProduct } = useProductAPI();
+ const { deleteProduct, updateProduct, getProduct } = useProductAPI();
const [deleting, setDeleting] =
useState<MerchantBackend.Products.ProductDetail & WithId | null>(null);
const [notif, setNotif] = useState<Notification | undefined>(undefined);
@@ -74,11 +74,61 @@ export default function ProductList({
return onNotFound();
return onLoadError(result);
}
+ const [errorId, setErrorId] = useState<string | undefined>(
+ undefined,
+ );
+
+ const [productId, setProductId] = useState<string>()
+ async function testIfProductExistAndSelect(orderId: string | undefined): Promise<void> {
+ if (!orderId) {
+ setErrorId(i18n.str`Enter a product id`);
+ return;
+ }
+ try {
+ await getProduct(orderId);
+ onSelect(orderId);
+ setErrorId(undefined);
+ } catch {
+ setErrorId(i18n.str`product not found`);
+ }
+ }
return (
<section class="section is-main-section">
<NotificationCard notification={notif} />
+ <div class="level">
+ <div class="level-left">
+ <div class="level-item">
+ <div class="field has-addons">
+ <div class="control">
+ <input
+ class={errorId ? "input is-danger" : "input"}
+ type="text"
+ value={productId ?? ""}
+ onChange={(e) => setProductId(e.currentTarget.value)}
+ placeholder={i18n.str`product id`}
+ />
+ {errorId && <p class="help is-danger">{errorId}</p>}
+ </div>
+ <span
+ class="has-tooltip-bottom"
+ data-tooltip={i18n.str`jump to product with the given product ID`}
+ >
+ <button
+ class="button"
+ onClick={(e) => testIfProductExistAndSelect(productId)}
+ >
+ <span class="icon">
+ <i class="mdi mdi-arrow-right" />
+ </span>
+ </button>
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+
<CardTable
instances={result.data}
onCreate={onCreate}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
index 2201e75a5..0d2bb2c30 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
@@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { HttpError, RequestError, useApiContext, useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, h, VNode } from "preact";
import { StateUpdater, useEffect, useState } from "preact/hooks";
import { AsyncButton } from "../../../../components/exception/AsyncButton.js";
@@ -35,6 +35,7 @@ import {
PAYTO_WIRE_METHOD_LOOKUP,
URL_REGEX,
} from "../../../../utils/constants.js";
+import { useBackendBaseRequest } from "../../../../hooks/backend.js";
type Entity = MerchantBackend.Rewards.ReserveCreateRequest;
@@ -65,6 +66,7 @@ function ViewStep({
setReserve,
}: ViewProps): VNode {
const { i18n } = useTranslationContext();
+ const {request} = useApiContext()
const [wireMethods, setWireMethods] = useState<Array<string>>([]);
const [exchangeQueryError, setExchangeQueryError] = useState<
string | undefined
@@ -123,19 +125,26 @@ function ViewStep({
<AsyncButton
class="has-tooltip-left"
onClick={() => {
- return fetch(`${reserve.exchange_url}wire`)
- .then((r) => r.json())
+ if (!reserve.exchange_url) {
+ return Promise.resolve();
+ }
+
+ return request<any>(reserve.exchange_url, "keys") //</div>fetch(`${reserve.exchange_url}wire`)
.then((r) => {
- const wireMethods = r.accounts.map((a: any) => {
- const match = PAYTO_WIRE_METHOD_LOOKUP.exec(a.payto_uri);
- return (match && match[1]) || "";
- });
+ if (r.loading) return;
+ if (r.ok) {
+ const wireMethods = r.data.accounts.map((a: any) => {
+ const match = PAYTO_WIRE_METHOD_LOOKUP.exec(a.payto_uri);
+ return (match && match[1]) || "";
+ });
+ }
setWireMethods(wireMethods);
setCurrentStep(Steps.WIRE_METHOD);
return;
})
- .catch((r: any) => {
- setExchangeQueryError(r.message);
+ .catch((r: RequestError<{}>) => {
+ console.log(r.cause)
+ setExchangeQueryError(r.cause.message);
});
}}
data-tooltip={
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx
index 4b0db200a..89dba63b2 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/token/DetailPage.tsx
@@ -30,13 +30,13 @@ import { AccessToken } from "../../../declaration.js";
interface Props {
instanceId: string;
- currentToken: string | undefined;
- onClearToken: () => void;
- onNewToken: (s: AccessToken) => void;
+ hasToken: boolean | undefined;
+ onClearToken: (c: AccessToken | undefined) => void;
+ onNewToken: (c: AccessToken | undefined, s: AccessToken) => void;
onBack?: () => void;
}
-export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewToken, onClearToken }: Props): VNode {
+export function DetailPage({ instanceId, hasToken, onBack, onNewToken, onClearToken }: Props): VNode {
type State = { old_token: string; new_token: string; repeat_token: string };
const [form, setValue] = useState<Partial<State>>({
old_token: "",
@@ -45,11 +45,9 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo
});
const { i18n } = useTranslationContext();
- const hasOldtoken = !!oldToken
- const hasInputTheCorrectOldToken = hasOldtoken && oldToken !== form.old_token;
const errors = {
- old_token: hasInputTheCorrectOldToken
- ? i18n.str`is not the same as the current access token`
+ old_token: hasToken && !form.old_token
+ ? i18n.str`you need your access token to perform the operation`
: undefined,
new_token: !form.new_token
? i18n.str`cannot be empty`
@@ -72,8 +70,9 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo
async function submitForm() {
if (hasErrors) return;
+ const ot = hasToken ? `secret-token:${form.old_token}` as AccessToken : undefined;
const nt = `secret-token:${form.new_token}` as AccessToken;
- onNewToken(nt)
+ onNewToken(ot, nt)
}
return (
@@ -98,32 +97,38 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo
<div class="column" />
<div class="column is-four-fifths">
<FormProvider errors={errors} object={form} valueHandler={setValue}>
- {hasOldtoken && (
- <Input<State>
- name="old_token"
- label={i18n.str`Current access token`}
- tooltip={i18n.str`access token currently in use`}
- inputType="password"
- />
- )}
- {!hasInputTheCorrectOldToken && <Fragment>
- {hasOldtoken && <Fragment>
- <p>
- <i18n.Translate>
- Clearing the access token will mean public access to the instance.
- </i18n.Translate>
- </p>
- <div class="buttons is-right mt-5">
- <button
- disabled={!!hasInputTheCorrectOldToken}
- class="button"
- onClick={onClearToken}
- >
- <i18n.Translate>Clear token</i18n.Translate>
- </button>
- </div>
- </Fragment>
- }
+ <Fragment>
+ {hasToken && (
+ <Fragment>
+ <Input<State>
+ name="old_token"
+ label={i18n.str`Current access token`}
+ tooltip={i18n.str`access token currently in use`}
+ inputType="password"
+ />
+ <p>
+ <i18n.Translate>
+ Clearing the access token will mean public access to the instance.
+ </i18n.Translate>
+ </p>
+ <div class="buttons is-right mt-5">
+ <button
+ class="button"
+ onClick={() => {
+ if (hasToken) {
+ const ot = `secret-token:${form.old_token}` as AccessToken;
+ onClearToken(ot)
+ } else {
+ onClearToken(undefined)
+ }
+ }}
+ >
+ <i18n.Translate>Clear token</i18n.Translate>
+ </button>
+ </div>
+ </Fragment>
+ )}
+
<Input<State>
name="new_token"
@@ -137,7 +142,7 @@ export function DetailPage({ instanceId, currentToken: oldToken, onBack, onNewTo
tooltip={i18n.str`confirm the same access token`}
inputType="password"
/>
- </Fragment>}
+ </Fragment>
</FormProvider>
<div class="buttons is-right mt-5">
{onBack && (
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
index 0a49448f8..bc2bd9fa3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
@@ -33,8 +33,6 @@ interface Props {
onNotFound: () => VNode;
}
-const PREFIX = "secret-token:"
-
export default function Token({
onLoadError,
onChange,
@@ -44,21 +42,36 @@ export default function Token({
const { i18n } = useTranslationContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
- const { clearToken, setNewToken } = useInstanceAPI();
- const { token: rootToken } = useBackendContext();
- const { token: instanceToken, id, admin } = useInstanceContext();
+ const { clearAccessToken, setNewAccessToken } = useInstanceAPI();
+ const { id } = useInstanceContext();
+ const result = useInstanceDetails()
+
+ if (result.loading) return <Loading />;
+ if (!result.ok) {
+ if (
+ result.type === ErrorType.CLIENT &&
+ result.status === HttpStatusCode.Unauthorized
+ )
+ return onUnauthorized();
+ if (
+ result.type === ErrorType.CLIENT &&
+ result.status === HttpStatusCode.NotFound
+ )
+ return onNotFound();
+ return onLoadError(result);
+ }
+
+ const hasToken = result.data.auth.method === "token"
- const currentToken = !admin ? rootToken : instanceToken
- const hasPrefix = currentToken !== undefined && currentToken.token.startsWith(PREFIX)
return (
<Fragment>
<NotificationCard notification={notif} />
<DetailPage
instanceId={id}
- currentToken={hasPrefix ? currentToken.token.substring(PREFIX.length) : currentToken?.token}
- onClearToken={async (): Promise<void> => {
+ hasToken={hasToken}
+ onClearToken={async (currentToken): Promise<void> => {
try {
- await clearToken();
+ await clearAccessToken(currentToken);
onChange();
} catch (error) {
if (error instanceof Error) {
@@ -70,9 +83,9 @@ export default function Token({
}
}
}}
- onNewToken={async (newToken): Promise<void> => {
+ onNewToken={async (currentToken, newToken): Promise<void> => {
try {
- await setNewToken(newToken);
+ await setNewAccessToken(currentToken, newToken);
onChange();
} catch (error) {
if (error instanceof Error) {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
index a1c608f15..01a3d0252 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/UpdatePage.tsx
@@ -39,9 +39,6 @@ type Entity = MerchantBackend.Instances.InstanceReconfigurationMessage & {
//MerchantBackend.Instances.InstanceAuthConfigurationMessage
interface Props {
onUpdate: (d: Entity) => void;
- onChangeAuth: (
- d: MerchantBackend.Instances.InstanceAuthConfigurationMessage,
- ) => Promise<void>;
selected: MerchantBackend.Instances.QueryInstancesResponse;
isLoading: boolean;
onBack: () => void;
@@ -78,7 +75,6 @@ function getTokenValuePart(t?: string): string | undefined {
export function UpdatePage({
onUpdate,
- onChangeAuth,
selected,
onBack,
}: Props): VNode {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
index 6c5e7a514..e44cf5c0f 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
@@ -46,17 +46,17 @@ export interface Props {
}
export default function Update(props: Props): VNode {
- const { updateInstance, clearToken, setNewToken } = useInstanceAPI();
+ const { updateInstance } = useInstanceAPI();
const result = useInstanceDetails();
- return CommonUpdate(props, result, updateInstance, clearToken, setNewToken);
+ return CommonUpdate(props, result, updateInstance, );
}
export function AdminUpdate(props: Props & { instanceId: string }): VNode {
- const { updateInstance, clearToken, setNewToken } = useManagementAPI(
+ const { updateInstance } = useManagementAPI(
props.instanceId,
);
const result = useManagedInstanceDetails(props.instanceId);
- return CommonUpdate(props, result, updateInstance, clearToken, setNewToken);
+ return CommonUpdate(props, result, updateInstance, );
}
function CommonUpdate(
@@ -73,8 +73,6 @@ function CommonUpdate(
MerchantBackend.ErrorDetail
>,
updateInstance: any,
- clearToken: () => Promise<void>,
- setNewToken: (t: AccessToken) => Promise<void>,
): VNode {
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { i18n } = useTranslationContext();
@@ -114,13 +112,6 @@ function CommonUpdate(
}),
);
}}
- onChangeAuth={(
- d: MerchantBackend.Instances.InstanceAuthConfigurationMessage,
- ): Promise<void> => {
- const apiCall =
- d.method === "external" ? clearToken() : setNewToken(d.token! as AccessToken);
- return apiCall.then(onConfirm).catch(onUpdateError);
- }}
/>
</Fragment>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx
index bdc86d226..cebc1ade6 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatePage.tsx
@@ -70,8 +70,8 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
: state.otp_key.length !== 32
? i18n.str`size of the key should be 32`
: undefined,
- otp_description: !state.otp_description ? i18n.str`required`
- : !/[a-zA-Z0-9]*/.test(state.otp_description)
+ otp_device_description: !state.otp_device_description ? i18n.str`required`
+ : !/[a-zA-Z0-9]*/.test(state.otp_device_description)
? i18n.str`no valid. only characters and numbers`
: undefined,
@@ -103,7 +103,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
tooltip={i18n.str`Internal id on the system`}
/>
<Input<Entity>
- name="otp_description"
+ name="otp_device_description"
label={i18n.str`Descripiton`}
tooltip={i18n.str`Useful to identify the device physically`}
/>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx
index 22ae55677..db3842711 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/create/CreatedSuccessfully.tsx
@@ -77,7 +77,7 @@ export function CreatedSuccessfully({
<input
class="input"
readonly
- value={entity.otp_description}
+ value={entity.otp_device_description}
/>
</p>
</div>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx
index 585c12e11..79be9802f 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/UpdatePage.tsx
@@ -87,7 +87,7 @@ export function UpdatePage({ device, onUpdate, onBack }: Props): VNode {
errors={errors}
>
<Input<Entity>
- name="otp_description"
+ name="otp_device_description"
label={i18n.str`Description`}
tooltip={i18n.str`dddd`}
/>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx
index 9a27ccfee..52f6c6c29 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/validators/update/index.tsx
@@ -80,7 +80,7 @@ export default function UpdateValidator({
device={{
id: vid,
otp_algorithm: result.data.otp_algorithm,
- otp_description: result.data.device_description,
+ otp_device_description: result.data.device_description,
otp_key: undefined,
otp_ctr: result.data.otp_ctr
}}
diff --git a/packages/merchant-backoffice-ui/src/paths/login/index.tsx b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
index 9948307e4..a9e3c3a1b 100644
--- a/packages/merchant-backoffice-ui/src/paths/login/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/login/index.tsx
@@ -52,7 +52,7 @@ function cleanUp(s: string): string {
}
export function LoginPage({ onConfirm }: Props): VNode {
- const { url: backendURL, changeBackend } = useBackendContext();
+ const { url: backendURL, changeBackend, resetBackend } = useBackendContext();
const { admin, id } = useInstanceContext();
const { requestNewLoginToken } = useCredentialsChecker();
const [token, setToken] = useState("");
@@ -73,10 +73,9 @@ export function LoginPage({ onConfirm }: Props): VNode {
}, [backendURL, id, token])
async function changeServer() {
- changeBackend("")
+ resetBackend()
}
- console.log(admin, id)
if (admin && id !== "default") {
//admin trying to access another instance
return (<div class="columns is-centered" style={{ margin: "auto" }}>
@@ -211,10 +210,7 @@ export function LoginPage({ onConfirm }: Props): VNode {
borderTop: 0,
}}
>
- <AsyncButton
-
- onClick={changeServer}
- >
+ <AsyncButton onClick={changeServer}>
<i18n.Translate>Change server</i18n.Translate>
</AsyncButton>
@@ -304,11 +300,8 @@ export function ConnectionPage({ onConfirm }: { onConfirm: (s: string) => void }
borderTop: 0,
}}
>
- <AsyncButton
- disabled={backendURL === url}
- onClick={doConnect}
- >
- <i18n.Translate>Try again</i18n.Translate>
+ <AsyncButton onClick={doConnect}>
+ <i18n.Translate>Connect</i18n.Translate>
</AsyncButton>
</footer>
</div>