mirror of
https://github.com/fosrl/pangolin.git
synced 2026-06-06 07:38:46 +00:00
Control updates from the ui
This commit is contained in:
@@ -38,11 +38,16 @@ import { useUserContext } from "@app/hooks/useUserContext";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { build } from "@server/build";
|
||||
import type { OrgContextType } from "@app/contexts/orgContext";
|
||||
import { SwitchInput } from "@app/components/SwitchInput";
|
||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||
import { tierMatrix, TierFeature } from "@server/lib/billing/tierMatrix";
|
||||
import { PaidFeaturesAlert } from "@app/components/PaidFeaturesAlert";
|
||||
|
||||
// Schema for general organization settings
|
||||
const GeneralFormSchema = z.object({
|
||||
name: z.string(),
|
||||
subnet: z.string().optional()
|
||||
subnet: z.string().optional(),
|
||||
settingsEnableGlobalNewtAutoUpdate: z.boolean().optional()
|
||||
});
|
||||
|
||||
export default function GeneralPage() {
|
||||
@@ -163,17 +168,24 @@ function GeneralSectionForm({ org }: SectionFormProps) {
|
||||
resolver: zodResolver(
|
||||
GeneralFormSchema.pick({
|
||||
name: true,
|
||||
subnet: true
|
||||
subnet: true,
|
||||
settingsEnableGlobalNewtAutoUpdate: true
|
||||
})
|
||||
),
|
||||
defaultValues: {
|
||||
name: org.name,
|
||||
subnet: org.subnet || "" // Add default value for subnet
|
||||
subnet: org.subnet || "",
|
||||
settingsEnableGlobalNewtAutoUpdate:
|
||||
org.settingsEnableGlobalNewtAutoUpdate ?? false
|
||||
},
|
||||
mode: "onChange"
|
||||
});
|
||||
const t = useTranslations();
|
||||
const router = useRouter();
|
||||
const { isPaidUser } = usePaidStatus();
|
||||
const hasAutoUpdateFeature = isPaidUser(
|
||||
tierMatrix[TierFeature.NewtAutoUpdate]
|
||||
);
|
||||
|
||||
const [, formAction, loadingSave] = useActionState(performSave, null);
|
||||
const api = createApiClient(useEnvContext());
|
||||
@@ -186,7 +198,9 @@ function GeneralSectionForm({ org }: SectionFormProps) {
|
||||
|
||||
try {
|
||||
const reqData = {
|
||||
name: data.name
|
||||
name: data.name,
|
||||
settingsEnableGlobalNewtAutoUpdate:
|
||||
data.settingsEnableGlobalNewtAutoUpdate
|
||||
} as any;
|
||||
|
||||
// Update organization
|
||||
@@ -194,7 +208,9 @@ function GeneralSectionForm({ org }: SectionFormProps) {
|
||||
|
||||
// Update the org context to reflect the change in the info card
|
||||
updateOrg({
|
||||
name: data.name
|
||||
name: data.name,
|
||||
settingsEnableGlobalNewtAutoUpdate:
|
||||
data.settingsEnableGlobalNewtAutoUpdate
|
||||
});
|
||||
|
||||
toast({
|
||||
@@ -243,6 +259,34 @@ function GeneralSectionForm({ org }: SectionFormProps) {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="settingsEnableGlobalNewtAutoUpdate"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<SwitchInput
|
||||
id="settings-enable-global-newt-auto-update"
|
||||
label={t("newtAutoUpdate")}
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
disabled={
|
||||
!hasAutoUpdateFeature
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{hasAutoUpdateFeature
|
||||
? t("newtAutoUpdateDescription")
|
||||
: t(
|
||||
"newtAutoUpdateDisabledDescription"
|
||||
)}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
</SettingsSectionForm>
|
||||
|
||||
@@ -36,35 +36,53 @@ import { useState } from "react";
|
||||
import { SwitchInput } from "@app/components/SwitchInput";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
import { usePaidStatus } from "@app/hooks/usePaidStatus";
|
||||
import { tierMatrix, TierFeature } from "@server/lib/billing/tierMatrix";
|
||||
import { Button as ButtonUI } from "@/components/ui/button";
|
||||
|
||||
const GeneralFormSchema = z.object({
|
||||
name: z.string().nonempty("Name is required"),
|
||||
niceId: z.string().min(1).max(255).optional(),
|
||||
dockerSocketEnabled: z.boolean().optional()
|
||||
dockerSocketEnabled: z.boolean().optional(),
|
||||
autoUpdateEnabled: z.boolean().optional(),
|
||||
autoUpdateOverrideOrg: z.boolean().optional()
|
||||
});
|
||||
|
||||
type GeneralFormValues = z.infer<typeof GeneralFormSchema>;
|
||||
|
||||
export default function GeneralPage() {
|
||||
const { site, updateSite } = useSiteContext();
|
||||
const { org } = useOrgContext();
|
||||
|
||||
const { env } = useEnvContext();
|
||||
const api = createApiClient(useEnvContext());
|
||||
const router = useRouter();
|
||||
const t = useTranslations();
|
||||
const { toast } = useToast();
|
||||
const { isPaidUser } = usePaidStatus();
|
||||
const hasAutoUpdateFeature = isPaidUser(
|
||||
tierMatrix[TierFeature.NewtAutoUpdate]
|
||||
);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [activeCidrTagIndex, setActiveCidrTagIndex] = useState<number | null>(
|
||||
null
|
||||
);
|
||||
|
||||
const orgAutoUpdate =
|
||||
org.org.settingsEnableGlobalNewtAutoUpdate ?? false;
|
||||
|
||||
const form = useForm({
|
||||
resolver: zodResolver(GeneralFormSchema),
|
||||
defaultValues: {
|
||||
name: site?.name,
|
||||
niceId: site?.niceId || "",
|
||||
dockerSocketEnabled: site?.dockerSocketEnabled ?? false
|
||||
dockerSocketEnabled: site?.dockerSocketEnabled ?? false,
|
||||
autoUpdateEnabled: site?.autoUpdateOverrideOrg
|
||||
? (site?.autoUpdateEnabled ?? false)
|
||||
: orgAutoUpdate,
|
||||
autoUpdateOverrideOrg: site?.autoUpdateOverrideOrg ?? false
|
||||
},
|
||||
mode: "onChange"
|
||||
});
|
||||
@@ -76,13 +94,17 @@ export default function GeneralPage() {
|
||||
await api.post(`/site/${site?.siteId}`, {
|
||||
name: data.name,
|
||||
niceId: data.niceId,
|
||||
dockerSocketEnabled: data.dockerSocketEnabled
|
||||
dockerSocketEnabled: data.dockerSocketEnabled,
|
||||
autoUpdateEnabled: data.autoUpdateEnabled,
|
||||
autoUpdateOverrideOrg: data.autoUpdateOverrideOrg
|
||||
});
|
||||
|
||||
updateSite({
|
||||
name: data.name,
|
||||
niceId: data.niceId,
|
||||
dockerSocketEnabled: data.dockerSocketEnabled
|
||||
dockerSocketEnabled: data.dockerSocketEnabled,
|
||||
autoUpdateEnabled: data.autoUpdateEnabled,
|
||||
autoUpdateOverrideOrg: data.autoUpdateOverrideOrg
|
||||
});
|
||||
|
||||
if (data.niceId && data.niceId !== site?.niceId) {
|
||||
@@ -217,6 +239,91 @@ export default function GeneralPage() {
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{site && site.type === "newt" && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="autoUpdateEnabled"
|
||||
render={({ field }) => {
|
||||
const isOverriding =
|
||||
form.watch(
|
||||
"autoUpdateOverrideOrg"
|
||||
);
|
||||
return (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<SwitchInput
|
||||
id="auto-update-enabled"
|
||||
label={t(
|
||||
"siteAutoUpdateLabel"
|
||||
)}
|
||||
checked={
|
||||
field.value
|
||||
}
|
||||
onCheckedChange={(checked) => {
|
||||
field.onChange(
|
||||
checked
|
||||
);
|
||||
form.setValue(
|
||||
"autoUpdateOverrideOrg",
|
||||
true
|
||||
);
|
||||
}}
|
||||
disabled={
|
||||
!hasAutoUpdateFeature
|
||||
}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
{isOverriding ? (
|
||||
<span className="flex items-center gap-2">
|
||||
<span>
|
||||
{t(
|
||||
"siteAutoUpdateOverriding"
|
||||
)}
|
||||
</span>
|
||||
<ButtonUI
|
||||
type="button"
|
||||
variant="link"
|
||||
size="sm"
|
||||
className="h-auto p-0 text-xs"
|
||||
onClick={() => {
|
||||
form.setValue(
|
||||
"autoUpdateOverrideOrg",
|
||||
false
|
||||
);
|
||||
form.setValue(
|
||||
"autoUpdateEnabled",
|
||||
orgAutoUpdate
|
||||
);
|
||||
}}
|
||||
>
|
||||
{t(
|
||||
"siteAutoUpdateResetToOrg"
|
||||
)}
|
||||
</ButtonUI>
|
||||
</span>
|
||||
) : (
|
||||
t(
|
||||
"siteAutoUpdateOrgDefault",
|
||||
{
|
||||
state: orgAutoUpdate
|
||||
? t(
|
||||
"siteAutoUpdateEnabled"
|
||||
)
|
||||
: t(
|
||||
"siteAutoUpdateDisabled"
|
||||
)
|
||||
}
|
||||
)
|
||||
)}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
</Form>
|
||||
</SettingsSectionForm>
|
||||
|
||||
Reference in New Issue
Block a user