Skip to content

Commit bb6c9c8

Browse files
committed
Certificates section react work
1 parent 5b7013b commit bb6c9c8

24 files changed

+596
-121
lines changed

frontend/src/api/backend/createCertificate.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type { Certificate } from "./models";
44
export async function createCertificate(item: Certificate): Promise<Certificate> {
55
return await api.post({
66
url: "/nginx/certificates",
7-
// todo: only use whitelist of fields for this data
87
data: item,
98
});
109
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import * as api from "./base";
22

33
export async function testHttpCertificate(domains: string[]): Promise<Record<string, string>> {
4-
return await api.get({
4+
return await api.post({
55
url: "/nginx/certificates/test-http",
6-
params: {
7-
domains: domains.join(","),
6+
data: {
7+
domains,
88
},
99
});
1010
}

frontend/src/components/Form/AccessField.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export function AccessField({ name = "accessListId", label = "access-list", id =
5858
options?.unshift({
5959
value: 0,
6060
label: intl.formatMessage({ id: "access-list.public" }),
61-
subLabel: "No basic auth required",
61+
subLabel: intl.formatMessage({ id: "access-list.public.subtitle" }),
6262
icon: <IconLockOpen2 size={14} className="text-red" />,
6363
});
6464

frontend/src/components/Form/DNSProviderFields.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1+
import { IconAlertTriangle } from "@tabler/icons-react";
12
import { Field, useFormikContext } from "formik";
23
import { useState } from "react";
34
import Select, { type ActionMeta } from "react-select";
45
import type { DNSProvider } from "src/api/backend";
56
import { useDnsProviders } from "src/hooks";
7+
import { T } from "src/locale";
68
import styles from "./DNSProviderFields.module.css";
79

810
interface DNSProviderOption {
911
readonly value: string;
1012
readonly label: string;
1113
readonly credentials: string;
1214
}
13-
export function DNSProviderFields() {
15+
16+
interface Props {
17+
showBoundaryBox?: boolean;
18+
}
19+
export function DNSProviderFields({ showBoundaryBox = false }: Props) {
1420
const { values, setFieldValue } = useFormikContext();
1521
const { data: dnsProviders, isLoading } = useDnsProviders();
1622
const [dnsProviderId, setDnsProviderId] = useState<string | null>(null);
@@ -31,17 +37,17 @@ export function DNSProviderFields() {
3137
})) || [];
3238

3339
return (
34-
<div className={styles.dnsChallengeWarning}>
35-
<p className="text-info">
36-
This section requires some knowledge about Certbot and DNS plugins. Please consult the respective
37-
plugins documentation.
40+
<div className={showBoundaryBox ? styles.dnsChallengeWarning : undefined}>
41+
<p className="text-warning">
42+
<IconAlertTriangle size={16} className="me-1" />
43+
<T id="certificates.dns.warning" />
3844
</p>
3945

4046
<Field name="meta.dnsProvider">
4147
{({ field }: any) => (
4248
<div className="row">
4349
<label htmlFor="dnsProvider" className="form-label">
44-
DNS Provider
50+
<T id="certificates.dns.provider" />
4551
</label>
4652
<Select
4753
className="react-select-container"
@@ -66,7 +72,7 @@ export function DNSProviderFields() {
6672
{({ field }: any) => (
6773
<div className="mt-3">
6874
<label htmlFor="dnsProviderCredentials" className="form-label">
69-
Credentials File Content
75+
<T id="certificates.dns.credentials" />
7076
</label>
7177
<textarea
7278
id="dnsProviderCredentials"
@@ -78,13 +84,12 @@ export function DNSProviderFields() {
7884
/>
7985
<div>
8086
<small className="text-muted">
81-
This plugin requires a configuration file containing an API token or other
82-
credentials to your provider
87+
<T id="certificates.dns.credentials-note" />
8388
</small>
8489
</div>
8590
<div>
8691
<small className="text-danger">
87-
This data will be stored as plaintext in the database and in a file!
92+
<T id="certificates.dns.credentials-warning" />
8893
</small>
8994
</div>
9095
</div>
@@ -94,20 +99,18 @@ export function DNSProviderFields() {
9499
{({ field }: any) => (
95100
<div className="mt-3">
96101
<label htmlFor="propagationSeconds" className="form-label">
97-
Propagation Seconds
102+
<T id="certificates.dns.propagation-seconds" />
98103
</label>
99104
<input
100105
id="propagationSeconds"
101106
type="number"
102-
x
103107
className="form-control"
104108
min={0}
105109
max={600}
106110
{...field}
107111
/>
108112
<small className="text-muted">
109-
Leave empty to use the plugins default value. Number of seconds to wait for DNS
110-
propagation.
113+
<T id="certificates.dns.propagation-seconds-note" />
111114
</small>
112115
</div>
113116
)}

frontend/src/components/Form/DomainNamesField.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ interface Props {
1818
dnsProviderWildcardSupported?: boolean;
1919
name?: string;
2020
label?: string;
21+
onChange?: (domains: string[]) => void;
2122
}
2223
export function DomainNamesField({
2324
name = "domainNames",
2425
label = "domain-names",
2526
id = "domainNames",
2627
maxDomains,
27-
isWildcardPermitted = true,
28-
dnsProviderWildcardSupported = true,
28+
isWildcardPermitted = false,
29+
dnsProviderWildcardSupported = false,
30+
onChange,
2931
}: Props) {
3032
const { setFieldValue } = useFormikContext();
3133

@@ -34,6 +36,7 @@ export function DomainNamesField({
3436
return i.value;
3537
});
3638
setFieldValue(name, doms);
39+
onChange?.(doms);
3740
};
3841

3942
const helperTexts: ReactNode[] = [];

frontend/src/components/Form/LocationsFields.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ interface Props {
1111
initialValues: ProxyLocation[];
1212
name?: string;
1313
}
14-
export function LocationsFields({ initialValues, name = "items" }: Props) {
14+
export function LocationsFields({ initialValues, name = "locations" }: Props) {
1515
const [values, setValues] = useState<ProxyLocation[]>(initialValues || []);
1616
const { setFieldValue } = useFormikContext();
1717
const [advVisible, setAdvVisible] = useState<number[]>([]);

frontend/src/components/Form/NginxConfigField.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export function NginxConfigField({
3030
fontFamily: "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
3131
borderRadius: "0.3rem",
3232
minHeight: "200px",
33+
backgroundColor: "var(--tblr-bg-surface-dark)",
3334
}}
3435
{...field}
3536
/>

frontend/src/components/Form/SSLCertificateField.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Field, useFormikContext } from "formik";
33
import Select, { type ActionMeta, components, type OptionProps } from "react-select";
44
import type { Certificate } from "src/api/backend";
55
import { useCertificates } from "src/hooks";
6-
import { DateTimeFormat, T } from "src/locale";
6+
import { DateTimeFormat, intl, T } from "src/locale";
77

88
interface CertOption {
99
readonly value: number | "new";
@@ -75,18 +75,16 @@ export function SSLCertificateField({
7575
data?.map((cert: Certificate) => ({
7676
value: cert.id,
7777
label: cert.niceName,
78-
subLabel: `${cert.provider === "letsencrypt" ? "Let's Encrypt" : cert.provider} &mdash; Expires: ${
79-
cert.expiresOn ? DateTimeFormat(cert.expiresOn) : "N/A"
80-
}`,
78+
subLabel: `${cert.provider === "letsencrypt" ? intl.formatMessage({ id: "lets-encrypt" }) : cert.provider} &mdash; ${intl.formatMessage({ id: "expires.on" }, { date: cert.expiresOn ? DateTimeFormat(cert.expiresOn) : "N/A" })}`,
8179
icon: <IconShield size={14} className="text-pink" />,
8280
})) || [];
8381

8482
// Prepend the Add New option
8583
if (allowNew) {
8684
options?.unshift({
8785
value: "new",
88-
label: "Request a new Certificate",
89-
subLabel: "with Let's Encrypt",
86+
label: intl.formatMessage({ id: "certificates.request.title" }),
87+
subLabel: intl.formatMessage({ id: "certificates.request.subtitle" }),
9088
icon: <IconShield size={14} className="text-lime" />,
9189
});
9290
}
@@ -95,8 +93,10 @@ export function SSLCertificateField({
9593
if (!required) {
9694
options?.unshift({
9795
value: 0,
98-
label: "None",
99-
subLabel: forHttp ? "This host will not use HTTPS" : "No certificate assigned",
96+
label: intl.formatMessage({ id: "certificate.none.title" }),
97+
subLabel: forHttp
98+
? intl.formatMessage({ id: "certificate.none.subtitle.for-http" })
99+
: intl.formatMessage({ id: "certificate.none.subtitle" }),
100100
icon: <IconShield size={14} className="text-red" />,
101101
});
102102
}

frontend/src/components/Form/SSLOptionsFields.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ export function SSLOptionsFields({ forHttp = true, forceDNSForNew, requireDomain
136136
</label>
137137
)}
138138
</Field>
139-
{requireDomainNames ? <DomainNamesField /> : null}
140-
{dnsChallenge ? <DNSProviderFields /> : null}
139+
{requireDomainNames ? <DomainNamesField isWildcardPermitted dnsProviderWildcardSupported /> : null}
140+
{dnsChallenge ? <DNSProviderFields showBoundaryBox /> : null}
141141
</>
142142
) : null}
143143
</div>

frontend/src/components/Table/Formatter/EventFormatter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function EventFormatter({ row }: Props) {
6464
<div className="flex-fill">
6565
<div className="font-weight-medium">
6666
{getIcon(row)}
67-
<T id={`event.${row.action}-${row.objectType}`} />
67+
<T id={`object.event.${row.action}`} tData={{ object: row.objectType }} />
6868
&mdash; <span className="badge">{getEventValue(row)}</span>
6969
</div>
7070
<div className="text-secondary mt-1">{DateTimeFormat(row.createdOn)}</div>

0 commit comments

Comments
 (0)