WIP: Enable OpenAPI spec generation and integrate with frontend #21
2 changed files with 39 additions and 36 deletions
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, useId, useTemplateRef } from "vue";
|
||||
import { computed, ref, useId, useTemplateRef } from "vue";
|
||||
import CountryListItem from "./CountryListItem.vue";
|
||||
import { type Country, getAvailableCountries } from "../utils/countries.ts";
|
||||
import { type Country, getAvailableCountries, userCountry } from "../utils/countries.ts";
|
||||
|
||||
const formModel = ref(false);
|
||||
const formRef = useTemplateRef("form");
|
||||
|
@ -16,7 +16,7 @@ const commonName = ref("");
|
|||
const emailAddress = ref("");
|
||||
const organization = ref("");
|
||||
const organizationalUnit = ref("");
|
||||
const country = ref("");
|
||||
const country = ref(userCountry?.alpha2);
|
||||
const countryName = ref("");
|
||||
const state = ref("");
|
||||
const locality = ref("");
|
||||
|
@ -32,20 +32,20 @@ const noExpiry = ref(false);
|
|||
// Validation rules
|
||||
const domainRules = [
|
||||
(value: string) => !!value || "A value must be provided to add the domain.",
|
||||
(value: string) => /^[a-z0-9][a-z0-9.\-_]+$|^xn--[a-z0-9.\-_]+$/i.test(value) || "Invalid domain characters provided. (To use some special characters, convert the domain to xn-domain format.)",
|
||||
]
|
||||
(value: string) => /^[a-z0-9][a-z0-9.\-_]+$|^xn--[a-z0-9.\-_]+$/i.test(value) || "Invalid domain characters provided. (To use some special characters, convert the domain to xn-domain format.)"
|
||||
];
|
||||
|
||||
const emailRules = [
|
||||
(value: string) => !value || /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value) || "Invalid email format.",
|
||||
(value: string) => !value || /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value) || "Invalid email format."
|
||||
];
|
||||
|
||||
const keyLengthRules = [
|
||||
(value: number) => value >= 3000 || "Key length must be at least 3000 bits.",
|
||||
(value: number) => value <= 6000 || "Key length must not exceed 6000 bits.",
|
||||
(value: number) => value <= 6000 || "Key length must not exceed 6000 bits."
|
||||
];
|
||||
|
||||
const validityDaysRules = [
|
||||
(value: number) => !value || value > 0 || "Validity period (in days) must be a positive integer.",
|
||||
(value: number) => !value || value > 0 || "Validity period (in days) must be a positive integer."
|
||||
];
|
||||
|
||||
|
||||
|
@ -64,6 +64,7 @@ function addDomain() {
|
|||
}
|
||||
|
||||
const isSubmitting = ref(false);
|
||||
|
||||
async function submitNewCertificate() {
|
||||
if (!formRef.value?.validate()) {
|
||||
return;
|
||||
|
@ -72,7 +73,7 @@ async function submitNewCertificate() {
|
|||
isSubmitting.value = true;
|
||||
try {
|
||||
// Extract country code if country is an object
|
||||
const countryCode = typeof country.value === 'object' && country.value !== null
|
||||
const countryCode = typeof country.value === "object" && country.value !== null
|
||||
? (country.value as Country).alpha2
|
||||
: country.value;
|
||||
|
||||
|
@ -88,10 +89,10 @@ async function submitNewCertificate() {
|
|||
organizationalUnit: organizationalUnit.value,
|
||||
country: countryCode,
|
||||
state: state.value,
|
||||
locality: locality.value,
|
||||
locality: locality.value
|
||||
},
|
||||
extension: {
|
||||
alternativeDnsNames: domains.value,
|
||||
alternativeDnsNames: domains.value
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
|
@ -144,8 +145,11 @@ async function submitNewCertificate() {
|
|||
hint="Search and select your country"
|
||||
class="mb-2"
|
||||
>
|
||||
<template #item="slotProps">
|
||||
<CountryListItem :item="slotProps.item" :props="slotProps.props" />
|
||||
<template #item="{ props, item }">
|
||||
<CountryListItem
|
||||
:item="item"
|
||||
:item-props="props"
|
||||
/>
|
||||
</template>
|
||||
</v-autocomplete>
|
||||
|
||||
|
|
|
@ -1,45 +1,44 @@
|
|||
<script setup lang="ts">
|
||||
// Define props with proper TypeScript typing
|
||||
import { computed } from "vue";
|
||||
import type { CountryListItemType } from "@/utils/countries.ts";
|
||||
|
||||
interface Country {
|
||||
country: string;
|
||||
alpha2: string;
|
||||
alpha3: string;
|
||||
numeric: string;
|
||||
type ListItem<T> = {
|
||||
raw: T;
|
||||
}
|
||||
|
||||
interface Divider {
|
||||
divider: boolean;
|
||||
header: string;
|
||||
}
|
||||
|
||||
// Define a type that can be either a Country or a Divider
|
||||
type CountryListItemType = Country | Divider;
|
||||
|
||||
// Define props with proper TypeScript typing
|
||||
const props = defineProps<{
|
||||
item: { raw: CountryListItemType };
|
||||
props?: Record<string, unknown>;
|
||||
item: ListItem<CountryListItemType>;
|
||||
itemProps?: Record<string, unknown>;
|
||||
}>();
|
||||
|
||||
// Helper functions to check the type of the item
|
||||
const isDivider = computed(() => {
|
||||
return 'divider' in props.item.raw && props.item.raw.divider;
|
||||
return "divider" in props.item.raw && props.item.raw.divider;
|
||||
});
|
||||
|
||||
const headerText = computed(() => {
|
||||
return 'header' in props.item.raw ? props.item.raw.header : "";
|
||||
return "header" in props.item.raw ? props.item.raw.header : "";
|
||||
});
|
||||
|
||||
const countryItem = computed(() => {
|
||||
return !isDivider.value && !headerText.value && 'country' in props.item.raw ? props.item.raw: undefined;
|
||||
})
|
||||
return !isDivider.value && !headerText.value && "country" in props.item.raw ? props.item.raw : undefined;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-divider v-if="isDivider" class="my-2" />
|
||||
<v-list-subheader v-if="headerText">{{ headerText }}</v-list-subheader>
|
||||
<v-list-item v-if="countryItem" v-bind="props" :title="countryItem.country" :value="countryItem.alpha2" />
|
||||
<v-divider
|
||||
v-if="isDivider"
|
||||
class="my-2"
|
||||
/>
|
||||
<v-list-subheader v-if="headerText">
|
||||
{{ headerText }}
|
||||
</v-list-subheader>
|
||||
<v-list-item
|
||||
v-if="countryItem"
|
||||
v-bind="itemProps"
|
||||
:title="countryItem.country"
|
||||
/>
|
||||
</template>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue