Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/api/services/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export type SearchResourcesRequest = {
checks?: PlaybookResourceSelector[];
components?: PlaybookResourceSelector[];
configs?: PlaybookResourceSelector[];
connections?: PlaybookResourceSelector[];
playbooks?: PlaybookResourceSelector[];
};

type SearchedResource = {
Expand All @@ -22,6 +24,8 @@ type SelectedResources = {
configs: SearchedResource[];
checks: SearchedResource[];
components: SearchedResource[];
connections: SearchedResource[];
playbooks: SearchedResource[];
};

export async function searchResources(input: SearchResourcesRequest) {
Expand Down
5 changes: 4 additions & 1 deletion src/api/services/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ export const getPerson = (id: string) =>
);

export const getPersons = () =>
// email=NULl filters out system user
resolvePostGrestRequestWithPagination<User[]>(
IncidentCommander.get<User[]>(`/people?select=*&order=name.asc`)
IncidentCommander.get<User[]>(
`/people?select=*&deleted_at=is.null&email=not.is.null&order=name.asc`
)
);

export const getPersonWithEmail = (email: string) =>
Expand Down
31 changes: 23 additions & 8 deletions src/api/types/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,37 @@ export type PermissionTable = {
deny?: boolean;
object?: string;
subject?: string;
subject_type?: "playbook" | "team" | "person" | "notification" | "component";
subject_type?:
| "group"
| "playbook"
| "team"
| "person"
| "notification"
| "component";
created_by: string;
updated_by: string;
created_at: string;
updated_at: string;
until?: string;
source?: string;
tags?: Record<string, string>;
agents?: string[];

// Resources
object_selector?: Record<string, any>[];
component_id?: string;
config_id?: string;
canary_id?: string;
playbook_id?: string;
created_by: string;
connection_id?: string;

// Deprecated fields
// These are subject fields that we do not use anymore.
// Instead we use the "subject" and "subject_type" field.
// Instead of setting person_id, we set subject = <person_id> and subject_type = "person"
person_id?: string;
notification_id?: string;
team_id?: string;
updated_by: string;
created_at: string;
updated_at: string;
until?: string;
source?: string;
playbook_id?: string;
};

export type PermissionAPIResponse = PermissionTable & {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Forms/Formik/FormikConnectionField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function FormikConnectionField({
return (
<FormikSelectDropdown
name={name}
className="h-full rounded-md border-gray-300 py-2 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
className="flex flex-col space-y-2 py-2"
options={connections}
label={label}
isLoading={isLoading}
Expand Down
80 changes: 79 additions & 1 deletion src/components/Forms/Formik/FormikResourceSelectorDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type FormikConfigsDropdownProps = {
configResourceSelector?: PlaybookResourceSelector[];
componentResourceSelector?: PlaybookResourceSelector[];
checkResourceSelector?: PlaybookResourceSelector[];
connectionResourceSelector?: PlaybookResourceSelector[];
playbookResourceSelector?: PlaybookResourceSelector[];
className?: string;
};

Expand All @@ -33,6 +35,8 @@ export default function FormikResourceSelectorDropdown({
configResourceSelector,
componentResourceSelector,
checkResourceSelector,
connectionResourceSelector,
playbookResourceSelector,
className = "flex flex-col space-y-2 py-2"
}: FormikConfigsDropdownProps) {
const [inputText, setInputText] = useState<string>("");
Expand Down Expand Up @@ -81,12 +85,32 @@ export default function FormikResourceSelectorDropdown({
agent: r.agent || "all"
}))
]
: undefined,
connections: connectionResourceSelector
? [
...connectionResourceSelector.map((r) => ({
...r,
search: searchText,
name: r.name || "*"
}))
]
: undefined,
playbooks: playbookResourceSelector
? [
...playbookResourceSelector.map((r) => ({
...r,
search: searchText,
name: r.name || "*"
}))
]
: undefined
}),
[
configResourceSelector,
componentResourceSelector,
checkResourceSelector,
connectionResourceSelector,
playbookResourceSelector,
searchText
]
);
Expand All @@ -101,7 +125,9 @@ export default function FormikResourceSelectorDropdown({
enabled:
configResourceSelector !== undefined ||
componentResourceSelector !== undefined ||
checkResourceSelector !== undefined, // || (field.value === undefined && field.value === "" && field.value === null),
checkResourceSelector !== undefined ||
connectionResourceSelector !== undefined ||
playbookResourceSelector !== undefined, // || (field.value === undefined && field.value === "" && field.value === null),
select: (data) => {
if (data?.checks) {
return data.checks.map(
Expand Down Expand Up @@ -159,6 +185,58 @@ export default function FormikResourceSelectorDropdown({
} as FormikSelectDropdownOption;
});
}
if (data?.connections) {
return data.connections.map((connection) => {
const tags = Object.values(connection.tags ?? {}).map(
(value) => value
);

return {
icon: (
<Icon
className="h-4 w-5"
name={connection.icon}
secondary={connection.name}
/>
),
value: connection.id,
search: connection.name,
label: (
<div className="flex flex-wrap gap-1">
<span className="mr-2"> {connection.name}</span>
<Tag title="tags">
{connection.type.split("::").at(-1)?.toLocaleLowerCase()}
</Tag>
{tags.map((tag) => (
<Tag title={tag} key={tag}>
{tag}
</Tag>
))}
</div>
)
} as FormikSelectDropdownOption;
});
}
if (data?.playbooks) {
return data.playbooks.map((playbook) => {
return {
icon: (
<Icon
className="h-4 w-5"
name={playbook.icon}
secondary={playbook.name}
/>
),
value: playbook.id,
search: playbook.name,
label: (
<div className="flex flex-wrap gap-1">
<span className="mr-2"> {playbook.name}</span>
</div>
)
} as FormikSelectDropdownOption;
});
}
},
keepPreviousData: true,
staleTime: 0,
Expand Down
37 changes: 37 additions & 0 deletions src/components/Forms/Formik/FormikRoleDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import FormikSelectDropdown from "./FormikSelectDropdown";

type FormikRoleDropdownProps = {
name: string;
label?: string;
required?: boolean;
hint?: string;
className?: string;
};

export default function FormikRoleDropdown({
name,
label,
required = false,
hint,
className = "flex flex-col space-y-2 py-2"
}: FormikRoleDropdownProps) {
const options = [
{ label: "Admin", value: "admin" },
{ label: "Editor", value: "editor" },
{ label: "Guest", value: "guest" },
{ label: "Viewer", value: "viewer" },
{ label: "Responder", value: "responder" },
{ label: "Commander", value: "commander" }
];

return (
<FormikSelectDropdown
name={name}
className={className}
options={options}
label={label}
required={required}
hint={hint}
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import FormikCanaryDropdown from "@flanksource-ui/components/Forms/Formik/FormikCanaryDropdown";
import FormikConnectionField from "@flanksource-ui/components/Forms/Formik/FormikConnectionField";
import FormikPlaybooksDropdown from "@flanksource-ui/components/Forms/Formik/FormikPlaybooksDropdown";
import FormikResourceSelectorDropdown from "@flanksource-ui/components/Forms/Formik/FormikResourceSelectorDropdown";
import FormikSelectDropdown from "@flanksource-ui/components/Forms/Formik/FormikSelectDropdown";
import { Switch } from "@flanksource-ui/ui/FormControls/Switch";
Expand Down Expand Up @@ -78,15 +76,23 @@ export default function FormikPermissionSelectResourceFields() {
)}

{switchOption === "Playbook" && (
<FormikPlaybooksDropdown required name="playbook_id" />
<FormikResourceSelectorDropdown
required
name="playbook_id"
playbookResourceSelector={[{}]}
/>
)}

{switchOption === "Canary" && (
<FormikCanaryDropdown required name="canary_id" />
)}

{switchOption === "Connection" && (
<FormikConnectionField required name="connection_id" />
<FormikResourceSelectorDropdown
required
name="connection_id"
connectionResourceSelector={[{}]}
/>
)}

{switchOption === "Global" && (
Expand Down
Loading
Loading