-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add silence notification form page
Fixes #2284
- Loading branch information
1 parent
65b232c
commit 201e6f1
Showing
14 changed files
with
556 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export type SilenceNotificationResponse = { | ||
id: string; | ||
component_id: string; | ||
config_id: string; | ||
check_id: string; | ||
canary_id: string; | ||
from: string; | ||
until: string; | ||
description: string; | ||
recursive: boolean; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { getCanaryNames } from "@flanksource-ui/api/services/topology"; | ||
import { useQuery } from "@tanstack/react-query"; | ||
import { useMemo } from "react"; | ||
import FormikSelectDropdown from "./FormikSelectDropdown"; | ||
|
||
type FormikCanaryDropdownProps = { | ||
name: string; | ||
label?: string; | ||
required?: boolean; | ||
hint?: string; | ||
|
||
className?: string; | ||
}; | ||
|
||
export default function FormikCanaryDropdown({ | ||
name, | ||
label, | ||
required = false, | ||
hint, | ||
className = "flex flex-col space-y-2 py-2" | ||
}: FormikCanaryDropdownProps) { | ||
const { isLoading, data: canary } = useQuery({ | ||
queryKey: ["canaries", "canary_names"], | ||
queryFn: () => getCanaryNames() | ||
}); | ||
|
||
const options = useMemo( | ||
() => | ||
canary?.map((canary) => ({ | ||
label: canary.name, | ||
value: canary.id | ||
})), | ||
[canary] | ||
); | ||
|
||
return ( | ||
<FormikSelectDropdown | ||
name={name} | ||
className={className} | ||
options={options} | ||
label={label} | ||
isLoading={isLoading} | ||
required={required} | ||
hint={hint} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { | ||
rangeOptionsCategories, | ||
TimeRangeOption | ||
} from "@flanksource-ui/ui/TimeRangePicker/rangeOptions"; | ||
import { TimeRangePicker } from "@flanksource-ui/ui/TimeRangePicker/TimeRangePicker"; | ||
import dayjs from "dayjs"; | ||
import { useFormikContext } from "formik"; | ||
import { useMemo } from "react"; | ||
|
||
type FormikDurationPickerProps = { | ||
fieldNames: { | ||
from: string; | ||
to: string; | ||
}; | ||
label: string; | ||
className?: string; | ||
placeholder?: string; | ||
}; | ||
|
||
export default function FormikDurationPicker({ | ||
fieldNames: { from, to }, | ||
label, | ||
placeholder = "Select duration", | ||
className = "flex flex-col py-2" | ||
}: FormikDurationPickerProps) { | ||
const { values, setFieldValue } = | ||
useFormikContext<Record<string, string | undefined>>(); | ||
|
||
const value = useMemo(() => { | ||
// if until is a valid date, then, set time range value to and from | ||
if (dayjs(values[to]).isValid()) { | ||
return { | ||
display: "Custom", | ||
from: values[from] ?? "", | ||
to: values[to] ?? "", | ||
type: "absolute" | ||
} satisfies TimeRangeOption; | ||
} | ||
|
||
const relativeValues = rangeOptionsCategories.find( | ||
(category) => | ||
category.name === "Relative time ranges" && category.type === "future" | ||
)?.options; | ||
|
||
return { | ||
type: "relative", | ||
display: values[to] | ||
? relativeValues?.find( | ||
(v) => v.type === "relative" && v.range === values[to] | ||
)?.display! | ||
: "", | ||
range: values[to] ?? "" | ||
} satisfies TimeRangeOption; | ||
}, [from, to, values]); | ||
|
||
return ( | ||
<div className={className}> | ||
{label && <label className={`form-label`}>{label}</label>} | ||
<div className="flex w-full flex-col"> | ||
<TimeRangePicker | ||
value={value} | ||
placeholder={placeholder} | ||
onChange={(value) => { | ||
console.log(value, "value"); | ||
if (value.type === "absolute") { | ||
setFieldValue(from, value.from); | ||
setFieldValue(to, value.to); | ||
} else if (value.type === "relative") { | ||
setFieldValue(to, value.range); | ||
setFieldValue(from, "now"); | ||
} | ||
}} | ||
showFutureTimeRanges | ||
className="w-full" | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
110 changes: 110 additions & 0 deletions
110
src/components/Notifications/SilenceNotificationForm/FormikNotificationField.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import FormikResourceSelectorDropdown from "@flanksource-ui/components/Forms/Formik/FormikResourceSelectorDropdown"; | ||
import { Switch } from "@flanksource-ui/ui/FormControls/Switch"; | ||
import { useFormikContext } from "formik"; | ||
import { useMemo, useState } from "react"; | ||
|
||
export default function FormikNotificationResourceField() { | ||
const { values } = useFormikContext<Record<string, any>>(); | ||
|
||
const component_id = values.component_id; | ||
const config_id = values.config_id; | ||
const check_id = values.check_id; | ||
const canary_id = values.canary_id; | ||
|
||
const [switchOption, setSwitchOption] = useState< | ||
"Component" | "Catalog" | "Check" | "Canary" | ||
>(() => { | ||
if (component_id) { | ||
return "Component"; | ||
} | ||
if (config_id) { | ||
return "Catalog"; | ||
} | ||
if (check_id) { | ||
return "Check"; | ||
} | ||
if (canary_id) { | ||
return "Canary"; | ||
} | ||
return "Catalog"; | ||
}); | ||
|
||
const fieldName = useMemo(() => { | ||
switch (switchOption) { | ||
case "Component": | ||
return { | ||
name: "component_id", | ||
label: "Component" | ||
}; | ||
case "Catalog": | ||
return { | ||
name: "config_id", | ||
label: "Catalog" | ||
}; | ||
case "Check": | ||
return { | ||
name: "check_id", | ||
label: "Check" | ||
}; | ||
case "Canary": | ||
return { | ||
name: "canary_id", | ||
label: "Canary" | ||
}; | ||
} | ||
}, [switchOption]); | ||
|
||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<label className={`form-label`}>Resource</label> | ||
<div> | ||
<div className="flex w-full flex-row"> | ||
<Switch | ||
options={["Catalog", "Component", "Check"]} | ||
className="w-auto" | ||
itemsClassName="" | ||
defaultValue="Go Template" | ||
value={switchOption} | ||
onChange={(v) => { | ||
setSwitchOption(v); | ||
// clear the other fields if the user selects a different option | ||
if (v === "Component") { | ||
values.config_id = null; | ||
values.check_id = null; | ||
values.canary_id = null; | ||
} | ||
|
||
if (v === "Catalog") { | ||
values.component_id = null; | ||
values.check_id = null; | ||
values.canary_id = null; | ||
} | ||
|
||
if (v === "Check") { | ||
values.component_id = null; | ||
values.config_id = null; | ||
values.canary_id = null; | ||
} | ||
|
||
if (v === "Canary") { | ||
values.component_id = null; | ||
values.config_id = null; | ||
values.check_id = null; | ||
} | ||
}} | ||
/> | ||
</div> | ||
|
||
<FormikResourceSelectorDropdown | ||
required | ||
name={fieldName.name} | ||
checkResourceSelector={switchOption === "Check" ? [{}] : undefined} | ||
componentResourceSelector={ | ||
switchOption === "Component" ? [{}] : undefined | ||
} | ||
configResourceSelector={switchOption === "Catalog" ? [{}] : undefined} | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
Oops, something went wrong.