feat: Refactor deployment types and add new deployment rules management

- Updated DeploymentExecution and related types to use targetId instead of virtualMachineId.
- Introduced new types for DeploymentRule, DeploymentRuleStep, and related entities.
- Added DeploymentRulesPage for managing deployment rules with CRUD operations.
- Created TargetDetailsPage and TargetsPage for managing targets with linking and unlinking functionality.
- Enhanced UI components with Fluent UI for better user experience.
- Implemented data fetching and state management using React Query.
This commit is contained in:
Torsten Brendgen
2026-07-07 23:30:08 +02:00
parent 08bcd60746
commit 3083e81452
27 changed files with 1492 additions and 399 deletions

View File

@@ -1,4 +1,4 @@
import { useQuery } from "@tanstack/react-query";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
Badge,
Button,
@@ -17,7 +17,7 @@ import {
tokens,
Tooltip,
} from "@fluentui/react-components";
import { ArrowLeftRegular, OpenRegular } from "@fluentui/react-icons";
import { ArrowLeftRegular, DeleteRegular, OpenRegular } from "@fluentui/react-icons";
import { Link, useParams } from "react-router-dom";
import { portalApi } from "../api/portalApi";
import { DataState } from "../components/DataState";
@@ -59,6 +59,7 @@ const useStyles = makeStyles({
export function EnvironmentDetailsPage() {
const styles = useStyles();
const queryClient = useQueryClient();
const { id } = useParams();
const { data, error, isLoading } = useQuery({
enabled: Boolean(id),
@@ -66,6 +67,15 @@ export function EnvironmentDetailsPage() {
queryFn: ({ signal }) => portalApi.getEnvironmentDomains(id!, signal),
});
const links = data?.environmentDomains?.filter((link) => link.domain) ?? [];
const unlinkDomainFromEnvironment = useMutation({
mutationFn: ({ domainId, environmentId }: { domainId: string; environmentId: string }) =>
portalApi.unlinkDomainFromEnvironment(domainId, environmentId),
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: ["environment", id, "domains"] });
await queryClient.invalidateQueries({ queryKey: ["domains"] });
await queryClient.invalidateQueries({ queryKey: ["environments"] });
},
});
return (
<>
@@ -92,24 +102,30 @@ export function EnvironmentDetailsPage() {
</Text>
</div>
<div className={styles.field}>
<Text size={200}>Environment Type</Text>
<Text size={200}>Environment Stage</Text>
<Text className={styles.value} weight="semibold">
{data.environmentType}
</Text>
</div>
<div className={styles.field}>
<Text size={200}>Hosting Type</Text>
<Text className={styles.value} weight="semibold">
{data.hostingType}
</Text>
</div>
<div className={styles.field}>
<Text size={200}>Cloud Enabled</Text>
<Text className={styles.value} weight="semibold">
{data.environmentType === "OnPrem" ? "Nein" : "Ja"}
{data.hostingType === "OnPrem" ? "Nein" : "Ja"}
</Text>
</div>
<div className={styles.field}>
<Text size={200}>Provider Type</Text>
<Text className={styles.value} weight="semibold">
{data.environmentType === "OnPrem" ? data.providerType : ""}
{data.hostingType === "OnPrem" ? data.providerType : ""}
</Text>
</div>
{data.environmentType !== "OnPrem" && (
{data.hostingType !== "OnPrem" && (
<div className={styles.field}>
<Text size={200}>Tenant Id</Text>
<Text className={styles.value} weight="semibold">
@@ -117,7 +133,7 @@ export function EnvironmentDetailsPage() {
</Text>
</div>
)}
{data.environmentType === "AzureTenant" && (
{data.hostingType === "AzureTenant" && (
<div className={styles.field}>
<Text size={200}>Subscription Id</Text>
<Text className={styles.value} weight="semibold">
@@ -140,7 +156,7 @@ export function EnvironmentDetailsPage() {
<TableHeaderCell>FQDN</TableHeaderCell>
<TableHeaderCell>NetBIOS</TableHeaderCell>
<TableHeaderCell>Status</TableHeaderCell>
<TableHeaderCell>Details</TableHeaderCell>
<TableHeaderCell>Actions</TableHeaderCell>
</TableRow>
</TableHeader>
<TableBody>
@@ -161,6 +177,21 @@ export function EnvironmentDetailsPage() {
<Button appearance="subtle" aria-label="Details" icon={<OpenRegular />} />
</Link>
</Tooltip>
<Tooltip content="Unlink" relationship="label">
<Button
appearance="subtle"
aria-label="Unlink"
disabled={unlinkDomainFromEnvironment.isPending}
icon={<DeleteRegular />}
onClick={() => {
if (!id) return;
unlinkDomainFromEnvironment.mutate({
domainId: link.domain!.id,
environmentId: id,
});
}}
/>
</Tooltip>
</div>
</TableCell>
</TableRow>
@@ -173,3 +204,4 @@ export function EnvironmentDetailsPage() {
</>
);
}