Skip to content

Commit

Permalink
Merge pull request #1576 from deepfence/ui-1487-notify
Browse files Browse the repository at this point in the history
added notify features
  • Loading branch information
milan-deepfence authored Sep 18, 2023
2 parents 73063eb + 916b99c commit 9122e3c
Show file tree
Hide file tree
Showing 7 changed files with 555 additions and 1 deletion.
1 change: 1 addition & 0 deletions deepfence_frontend/apps/dashboard/api-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -12358,6 +12358,7 @@
"required": ["scan_id", "result_ids", "scan_type"],
"type": "object",
"properties": {
"notify_individual": { "type": "boolean" },
"result_ids": {
"type": "array",
"items": { "type": "string" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ import { exists, mapValues } from '../runtime';
* @interface ModelScanResultsActionRequest
*/
export interface ModelScanResultsActionRequest {
/**
*
* @type {boolean}
* @memberof ModelScanResultsActionRequest
*/
notify_individual?: boolean;
/**
*
* @type {Array<string>}
Expand Down Expand Up @@ -75,6 +81,7 @@ export function ModelScanResultsActionRequestFromJSONTyped(json: any, ignoreDisc
}
return {

'notify_individual': !exists(json, 'notify_individual') ? undefined : json['notify_individual'],
'result_ids': json['result_ids'],
'scan_id': json['scan_id'],
'scan_type': json['scan_type'],
Expand All @@ -90,6 +97,7 @@ export function ModelScanResultsActionRequestToJSON(value?: ModelScanResultsActi
}
return {

'notify_individual': value.notify_individual,
'result_ids': value.result_ids,
'scan_id': value.scan_id,
'scan_type': value.scan_type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
BreadcrumbLink,
Button,
Card,
Checkbox,
CircleSpinner,
Combobox,
ComboboxOption,
Expand Down Expand Up @@ -110,6 +111,7 @@ const action = async ({
}

if (actionType === ActionEnumType.DELETE || actionType === ActionEnumType.NOTIFY) {
const notifyIndividual = formData.get('notifyIndividual')?.toString();
const apiFunction =
actionType === ActionEnumType.DELETE
? getScanResultsApiClient().deleteScanResult
Expand All @@ -122,6 +124,7 @@ const action = async ({
result_ids: [...ids],
scan_id: _scanId,
scan_type: ScanTypeEnum.MalwareScan,
notify_individual: notifyIndividual === 'on',
},
});
if (!result.ok) {
Expand Down Expand Up @@ -461,6 +464,85 @@ const DeleteScanConfirmationModal = ({
);
};

const NotifyModal = ({
open,
ids,
closeModal,
}: {
open: boolean;
ids: string[];
closeModal: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
const fetcher = useFetcher<ActionData>();

return (
<Modal
size="s"
open={open}
onOpenChange={() => closeModal(false)}
title={
!fetcher.data?.success ? (
<div className="flex gap-3 items-center dark:text-text-text-and-icon">
<span className="h-6 w-6 shrink-0">
<BellLineIcon />
</span>
Notify malwares
</div>
) : undefined
}
>
{!fetcher.data?.success ? (
<fetcher.Form method="post">
<input
type="text"
name="actionType"
hidden
readOnly
value={ActionEnumType.NOTIFY}
/>
{ids.map((id) => (
<input key={id} type="text" name="nodeIds[]" hidden readOnly value={id} />
))}

<div className="grid">
<span>The selected malwares will be notified.</span>
<br />
<span>Do you want to notify each malware separately?</span>
<div className="mt-2">
<Checkbox label="Yes notify them separately" name="notifyIndividual" />
</div>
{fetcher.data?.message && (
<p className="mt-2 text-p7 dark:text-status-error">
{fetcher.data?.message}
</p>
)}
</div>
<div className={'flex gap-x-3 justify-end pt-3 mx-2'}>
<Button
size="md"
onClick={() => closeModal(false)}
type="button"
variant="outline"
>
Cancel
</Button>
<Button
size="md"
loading={fetcher.state === 'submitting'}
disabled={fetcher.state === 'submitting'}
type="submit"
>
Notify
</Button>
</div>
</fetcher.Form>
) : (
<SuccessModalContent text="Deleted successfully!" />
)}
</Modal>
);
};

const ScanHistory = () => {
return (
<div className="flex items-center h-12">
Expand Down Expand Up @@ -642,6 +724,14 @@ const ActionDropdown = ({
Un-mask malware across hosts and images
</DropdownItem>
<DropdownSeparator />
<DropdownItem
onClick={() => {
onTableAction(ids, ActionEnumType.NOTIFY);
}}
>
Notify
</DropdownItem>
<DropdownSeparator />
<DropdownItem
onClick={() => {
setIdsToDelete(ids);
Expand Down Expand Up @@ -670,8 +760,12 @@ const BulkActions = ({
setShowDeleteDialog: React.Dispatch<React.SetStateAction<boolean>>;
onTableAction: (ids: string[], actionType: string, maskHostAndImages?: string) => void;
}) => {
const [openNotifyModal, setOpenNotifyModal] = useState<boolean>(false);
return (
<>
{openNotifyModal && (
<NotifyModal open={true} closeModal={setOpenNotifyModal} ids={ids} />
)}
<Dropdown
triggerAsChild
align={'start'}
Expand Down Expand Up @@ -730,6 +824,21 @@ const BulkActions = ({
Unmask
</Button>
</Dropdown>
<Button
variant="flat"
size="sm"
startIcon={<BellLineIcon />}
disabled={!ids.length}
onClick={() => {
if (ids.length === 1) {
onTableAction(ids, ActionEnumType.NOTIFY);
} else {
setOpenNotifyModal(true);
}
}}
>
Notify
</Button>
<Button
color="error"
variant="flat"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
BreadcrumbLink,
Button,
Card,
Checkbox,
CircleSpinner,
Combobox,
ComboboxOption,
Expand All @@ -40,6 +41,7 @@ import {
} from '@/api/generated';
import { DFLink } from '@/components/DFLink';
import { FilterBadge } from '@/components/filters/FilterBadge';
import { BellLineIcon } from '@/components/icons/common/BellLine';
import { CaretDown } from '@/components/icons/common/CaretDown';
import { ClockLineIcon } from '@/components/icons/common/ClockLine';
import { DownloadLineIcon } from '@/components/icons/common/DownloadLine';
Expand Down Expand Up @@ -119,6 +121,7 @@ const action = async ({
}

if (actionType === ActionEnumType.DELETE || actionType === ActionEnumType.NOTIFY) {
const notifyIndividual = formData.get('notifyIndividual')?.toString();
const apiFunction =
actionType === ActionEnumType.DELETE
? getScanResultsApiClient().deleteScanResult
Expand All @@ -132,6 +135,7 @@ const action = async ({
result_ids: [...ids],
scan_id: _scanId,
scan_type: ScanTypeEnum.CloudComplianceScan,
notify_individual: notifyIndividual === 'on',
},
});

Expand Down Expand Up @@ -451,6 +455,85 @@ const DeleteScanConfirmationModal = ({
);
};

const NotifyModal = ({
open,
ids,
closeModal,
}: {
open: boolean;
ids: string[];
closeModal: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
const fetcher = useFetcher<ActionData>();

return (
<Modal
size="s"
open={open}
onOpenChange={() => closeModal(false)}
title={
!fetcher.data?.success ? (
<div className="flex gap-3 items-center dark:text-text-text-and-icon">
<span className="h-6 w-6 shrink-0">
<BellLineIcon />
</span>
Notify compliances
</div>
) : undefined
}
>
{!fetcher.data?.success ? (
<fetcher.Form method="post">
<input
type="text"
name="actionType"
hidden
readOnly
value={ActionEnumType.NOTIFY}
/>
{ids.map((id) => (
<input key={id} type="text" name="nodeIds[]" hidden readOnly value={id} />
))}

<div className="grid">
<span>The selected compliances will be notified.</span>
<br />
<span>Do you want to notify each compliance separately?</span>
<div className="mt-2">
<Checkbox label="Yes notify them separately" name="notifyIndividual" />
</div>
{fetcher.data?.message && (
<p className="mt-2 text-p7 dark:text-status-error">
{fetcher.data?.message}
</p>
)}
</div>
<div className={'flex gap-x-3 justify-end pt-3 mx-2'}>
<Button
size="md"
onClick={() => closeModal(false)}
type="button"
variant="outline"
>
Cancel
</Button>
<Button
size="md"
loading={fetcher.state === 'submitting'}
disabled={fetcher.state === 'submitting'}
type="submit"
>
Notify
</Button>
</div>
</fetcher.Form>
) : (
<SuccessModalContent text="Deleted successfully!" />
)}
</Modal>
);
};

const ScanHistory = () => {
return (
<div className="flex items-center h-12">
Expand Down Expand Up @@ -616,6 +699,13 @@ const ActionDropdown = ({
<DropdownItem onClick={() => onTableAction(ids, ActionEnumType.UNMASK)}>
Un-mask
</DropdownItem>
<DropdownItem
onClick={() => {
onTableAction(ids, ActionEnumType.NOTIFY);
}}
>
Notify
</DropdownItem>
<DropdownItem
onClick={() => {
setIdsToDelete(ids);
Expand Down Expand Up @@ -643,8 +733,12 @@ const BulkActions = ({
setShowDeleteDialog: React.Dispatch<React.SetStateAction<boolean>>;
onTableAction: (ids: string[], actionType: string) => void;
}) => {
const [openNotifyModal, setOpenNotifyModal] = useState<boolean>(false);
return (
<>
{openNotifyModal && (
<NotifyModal open={true} closeModal={setOpenNotifyModal} ids={ids} />
)}
<Dropdown
triggerAsChild
align={'start'}
Expand Down Expand Up @@ -691,6 +785,21 @@ const BulkActions = ({
Unmask
</Button>
</Dropdown>
<Button
variant="flat"
size="sm"
startIcon={<BellLineIcon />}
disabled={!ids.length}
onClick={() => {
if (ids.length === 1) {
onTableAction(ids, ActionEnumType.NOTIFY);
} else {
setOpenNotifyModal(true);
}
}}
>
Notify
</Button>
<Button
color="error"
variant="flat"
Expand Down
Loading

0 comments on commit 9122e3c

Please sign in to comment.