diff --git a/packages/frinx-dashboard/src/api/unistore/converters.ts b/packages/frinx-dashboard/src/api/unistore/converters.ts index f352b7fe7..49483fb1b 100644 --- a/packages/frinx-dashboard/src/api/unistore/converters.ts +++ b/packages/frinx-dashboard/src/api/unistore/converters.ts @@ -19,6 +19,7 @@ import { DefaultCVlanEnum, EvcAttachment, EvcAttachmentOutput, + EvcAttachmentInput, IPConnection, LanTag, MaximumRoutes, @@ -37,6 +38,7 @@ import { SiteVpnFlavor, ValidProviderIdentifiersOutput, VpnBearerOutput, + VpnBearerInput, VpnBearer, VpnService, VpnServicesOutput, @@ -542,3 +544,84 @@ export function apiBearerToClientBearer(apiBearer: VpnBearerOutput): VpnBearer[] }; }); } +function clientBearerStatusToApiBearerStatus(status: BearerStatus): BearerStatusOutput { + const adminStatus = status.adminStatus + ? { + status: status.adminStatus.status || undefined, + 'last-updated': status.adminStatus.lastUpdated || undefined, + } + : undefined; + const operStatus = status.operStatus + ? { + status: status.operStatus.status || undefined, + 'last-updated': status.operStatus.lastUpdated || undefined, + } + : undefined; + return { + 'admin-status': adminStatus, + 'oper-status': operStatus, + }; +} + +function clientCarrierToApiCarrier(carrier: Carrier): CarrierOutput { + return { + 'carrier-name': carrier.carrierName || undefined, + 'carrier-reference': carrier.carrierReference || undefined, + 'service-status': carrier.serviceStatus || undefined, + 'service-type': carrier.serviceType || undefined, + }; +} + +function clientConnectionToApiConnection(connection: Connection): ConnectionOutput { + return { + 'encapsulation-type': connection.encapsulationType || undefined, + 'remote-ne-id': connection.remoteNeId || undefined, + 'remote-port-id': connection.remotePortId || undefined, + 'svlan-assignment-type': connection.svlanAssignmentType || undefined, + mtu: connection.mtu, + tpid: connection.tpId || undefined, + }; +} + +function clientEvcAttachmentsToApiEvcAttachments(attachments: EvcAttachment[]): EvcAttachmentInput | undefined { + if (!attachments.length) { + return undefined; + } + + const result = attachments.map((a: EvcAttachment): EvcAttachmentOutput => { + return { + 'evc-type': a.evcType, + 'customer-name': a.customerName || undefined, + 'circuit-reference': a.circuitReference, + 'carrier-reference': a.carrierReference || undefined, + 'svlan-id': a.svlanId || undefined, + status: a.status ? clientBearerStatusToApiBearerStatus(a.status) : undefined, + 'input-bandwidth': a.inputBandwidth, + 'qos-input-profile': a.qosInputProfile || undefined, + 'upstream-bearer': a.upstreamBearer || undefined, + }; + }); + + return { + 'evc-attachment': result, + }; +} + +export function clientBearerToApiBearer(bearer: VpnBearer): VpnBearerInput { + const output: VpnBearerInput = { + 'vpn-bearer': [ + { + 'sp-bearer-reference': bearer.spBearerReference, + description: bearer.description || undefined, + 'ne-id': bearer.neId, + 'port-id': bearer.portId, + status: bearer.status ? clientBearerStatusToApiBearerStatus(bearer.status) : undefined, + carrier: bearer.carrier ? clientCarrierToApiCarrier(bearer.carrier) : undefined, + connection: bearer.connection ? clientConnectionToApiConnection(bearer.connection) : undefined, + 'default-upstream-bearer': bearer.defaultUpstreamBearer || undefined, + 'evc-attachments': clientEvcAttachmentsToApiEvcAttachments(bearer.evcAttachments), + }, + ], + }; + return output; +} diff --git a/packages/frinx-dashboard/src/api/unistore/network-types.ts b/packages/frinx-dashboard/src/api/unistore/network-types.ts index 2d4dcd7bb..a5ca07f59 100644 --- a/packages/frinx-dashboard/src/api/unistore/network-types.ts +++ b/packages/frinx-dashboard/src/api/unistore/network-types.ts @@ -611,29 +611,38 @@ export function decodeConnectionOutput(value: unknown): ConnectionOutput { return extractResult(ConnectionOutputValidator.decode(value)); } -const VpnBearerOutputValidator = t.type({ - 'vpn-bearers': optional( +const VpnBearerItemsOutputValidator = t.type({ + 'vpn-bearer': t.array( t.type({ - 'vpn-bearer': t.array( + 'sp-bearer-reference': t.string, + description: optional(t.string), + 'ne-id': t.string, + 'port-id': t.string, + status: optional(BearerStatusValidator), + carrier: optional(CarrierOutputValidator), + connection: optional(ConnectionOutputValidator), + 'default-upstream-bearer': optional(t.string), + 'evc-attachments': optional( t.type({ - 'sp-bearer-reference': t.string, - description: optional(t.string), - 'ne-id': t.string, - 'port-id': t.string, - status: optional(BearerStatusValidator), - carrier: optional(CarrierOutputValidator), - connection: optional(ConnectionOutputValidator), - 'default-upstream-bearer': optional(t.string), - 'evc-attachments': optional( - t.type({ - 'evc-attachment': t.array(EvcAttachmentOutputValidator), - }), - ), + 'evc-attachment': t.array(EvcAttachmentOutputValidator), }), ), }), ), }); +export type VpnBearerItemsOutput = t.TypeOf; +export type VpnBearerInput = VpnBearerItemsOutput; +export function decodeVpnBearerItemsOutput(value: unknown): VpnBearerItemsOutput { + return extractResult(VpnBearerItemsOutputValidator.decode(value)); +} + +export type EvcAttachmentInput = { + 'evc-attachment': EvcAttachmentOutput[]; +}; + +const VpnBearerOutputValidator = t.type({ + 'vpn-bearers': optional(VpnBearerItemsOutputValidator), +}); export type VpnBearerOutput = t.TypeOf; diff --git a/packages/frinx-dashboard/src/api/unistore/unistore.ts b/packages/frinx-dashboard/src/api/unistore/unistore.ts index 4ce6845dc..71f96e882 100644 --- a/packages/frinx-dashboard/src/api/unistore/unistore.ts +++ b/packages/frinx-dashboard/src/api/unistore/unistore.ts @@ -10,8 +10,9 @@ import { VpnSite, decodeVpnBearerOutput, VpnBearerOutput, + VpnBearer, } from './network-types'; -import { clientVpnServiceToApiVpnService, clientVpnSiteToApiVpnSite } from './converters'; +import { clientBearerToApiBearer, clientVpnServiceToApiVpnService, clientVpnSiteToApiVpnSite } from './converters'; // data/network-topology:network-topology/topology=uniconfig/node=bearer/frinx-uniconfig-topology:configuration/gamma-bearer-svc:bearer-svc/vpn-bearers const UNICONFIG_SERVICE_URL = @@ -80,3 +81,26 @@ export async function getVpnBearers(): Promise { return data; } + +export async function createVpnBearer(bearer: VpnBearer): Promise { + const body = clientBearerToApiBearer(bearer); + await sendPostRequest( + '/data/network-topology:network-topology/topology=uniconfig/node=bearer/frinx-uniconfig-topology:configuration/gamma-bearer-svc:bearer-svc/vpn-bearers', + body, + ); +} + +export async function editVpnBearer(vpnBearer: VpnBearer): Promise { + const body = clientBearerToApiBearer(vpnBearer); + const json = await sendPutRequest( + `/data/network-topology:network-topology/topology=uniconfig/node=bearer/frinx-uniconfig-topology:configuration/gamma-bearer-svc:bearer-svc/vpn-bearers/vpn-bearer=${vpnBearer.spBearerReference}`, + body, + ); + return json; +} + +export async function deleteVpnBearer(id: string): Promise { + await sendDeleteRequest( + `/data/network-topology:network-topology/topology=uniconfig/node=bearer/frinx-uniconfig-topology:configuration/gamma-bearer-svc:bearer-svc/vpn-bearers/vpn-bearer=${id}`, + ); +} diff --git a/packages/frinx-dashboard/src/gamma-app.tsx b/packages/frinx-dashboard/src/gamma-app.tsx index 1c3821276..f58e99533 100644 --- a/packages/frinx-dashboard/src/gamma-app.tsx +++ b/packages/frinx-dashboard/src/gamma-app.tsx @@ -35,6 +35,8 @@ const GammaApp: VoidFunctionComponent = () => { CreateDevice, EditDevice, VpnBearerList, + CreateBearer, + EditBearer, getUnistoreApiProvider, } = gammaImport; @@ -53,6 +55,8 @@ const GammaApp: VoidFunctionComponent = () => { CreateDevice, EditDevice, VpnBearerList, + CreateBearer, + EditBearer, UnistoreApiProvider: getUnistoreApiProvider(callbacks), }); }); @@ -77,6 +81,8 @@ const GammaApp: VoidFunctionComponent = () => { SiteList, SiteNetworkAccessList, VpnBearerList, + CreateBearer, + EditBearer, UnistoreApiProvider, } = components; @@ -237,15 +243,35 @@ const GammaApp: VoidFunctionComponent = () => { }} /> - + + {/* bearers */} + { - // eslint-disable-next-line no-console - console.log('edit click'); + onEditVpnBearerClick={(bearerId: string) => { + history.push(`/gamma/vpn-bearers/edit/${bearerId}`); }} onCreateVpnBearerClick={() => { - // eslint-disable-next-line no-console - console.log('create click'); + history.push(`/gamma/vpn-bearers/add`); + }} + /> + + + { + history.push(`/gamma/vpn-bearers`); + }} + onCancel={() => { + history.push(`/gamma/vpn-bearers`); + }} + /> + + + { + history.push('/gamma/vpn-bearers'); + }} + onCancel={() => { + history.push('/gamma/vpn-bearers'); }} /> diff --git a/packages/frinx-gamma/docs/gamma-bearer-svc.txt b/packages/frinx-gamma/docs/gamma-bearer-svc.txt new file mode 100644 index 000000000..c0212b471 --- /dev/null +++ b/packages/frinx-gamma/docs/gamma-bearer-svc.txt @@ -0,0 +1,57 @@ +module: gamma-bearer-svc + +--rw bearer-svc + +--rw valid-provider-identifiers + | +--rw qos-profile-identifier* [id] + | +--rw id string + +--rw carriers + | +--rw carrier* [carrier-name] + | +--rw carrier-name string + | +--rw description? string + +--rw vpn-nodes + | +--rw vpn-node* [ne-id] + | +--rw ne-id string + | +--rw router-id inet:ip-address + | +--rw role? identityref + +--rw vpn-bearers + +--rw vpn-bearer* [sp-bearer-reference] + +--rw sp-bearer-reference svc-id + +--rw description? string + +--rw ne-id -> /bearer-svc/vpn-nodes/vpn-node/ne-id + +--rw port-id string + +--rw status + | +--rw admin-status + | | +--rw status? identityref + | | +--rw last-updated? yang:date-and-time + | +--ro oper-status + | +--ro status? identityref + | +--ro last-updated? yang:date-and-time + +--rw carrier + | +--rw carrier-name? -> /bearer-svc/carriers/carrier/carrier-name + | +--rw carrier-reference? string + | +--rw service-type? identityref + | +--rw service-status? identityref + +--rw connection + | +--rw encapsulation-type? identityref + | +--rw svlan-assignment-type? identityref + | +--rw tpid? identityref + | +--rw mtu uint16 + | +--rw remote-ne-id? -> /bearer-svc/vpn-nodes/vpn-node/ne-id + | +--rw remote-port-id? string + +--rw default-upstream-bearer? -> /bearer-svc/vpn-bearers/vpn-bearer/sp-bearer-reference + +--rw evc-attachments + +--rw evc-attachment* [evc-type circuit-reference] + +--rw evc-type identityref + +--rw customer-name? string + +--rw circuit-reference svc-id + +--rw carrier-reference? svc-id + +--rw svlan-id? uint16 + +--rw status + | +--rw admin-status + | | +--rw status? identityref + | | +--rw last-updated? yang:date-and-time + | +--ro oper-status + | +--ro status? identityref + | +--ro last-updated? yang:date-and-time + +--rw input-bandwidth uint64 + +--rw qos-input-profile? -> /bearer-svc/valid-provider-identifiers/qos-profile-identifier/id + +--rw upstream-bearer? -> /bearer-svc/vpn-bearers/vpn-bearer/sp-bearer-reference \ No newline at end of file diff --git a/packages/frinx-gamma/src/callback-utils.ts b/packages/frinx-gamma/src/callback-utils.ts index ea04af649..0a65f4e14 100644 --- a/packages/frinx-gamma/src/callback-utils.ts +++ b/packages/frinx-gamma/src/callback-utils.ts @@ -1,6 +1,7 @@ import { ValidProviderIdentifiersOutput, VpnBearerOutput, VpnServicesOutput, VpnSitesOutput } from './network-types'; import { VpnService } from './components/forms/service-types'; import { VpnSite } from './components/forms/site-types'; +import { VpnBearer } from './components/forms/bearer-types'; export type WorkflowPayload = { input: unknown; @@ -25,6 +26,9 @@ export type Callbacks = { executeWorkflow: (payload: WorkflowPayload) => Promise; getWorkflowInstanceDetail: (workflowId: string, options?: RequestInit) => Promise; getVpnBearers: () => Promise; + createVpnBearer: (bearer: VpnBearer) => Promise; + editVpnBearer: (bearer: VpnBearer) => Promise; + deleteVpnBearer: (id: string) => Promise; }; class CallbackUtils { private callbacks: Callbacks | null = null; diff --git a/packages/frinx-gamma/src/components/forms/converters.ts b/packages/frinx-gamma/src/components/forms/converters.ts index 64fbab45f..2c2da0231 100644 --- a/packages/frinx-gamma/src/components/forms/converters.ts +++ b/packages/frinx-gamma/src/components/forms/converters.ts @@ -37,6 +37,8 @@ import { ConnectionOutput, EvcAttachmentOutput, VpnBearerOutput, + VpnBearerInput, + EvcAttachmentInput, } from '../../network-types'; import unwrap from '../../helpers/unwrap'; import { VpnBearer, BearerStatus, Carrier, Connection, EvcAttachment } from './bearer-types'; @@ -557,3 +559,85 @@ export function apiBearerToClientBearer(apiBearer: VpnBearerOutput): VpnBearer[] }; }); } + +function clientBearerStatusToApiBearerStatus(status: BearerStatus): BearerStatusOutput { + const adminStatus = status.adminStatus + ? { + status: status.adminStatus.status || undefined, + 'last-updated': status.adminStatus.lastUpdated || undefined, + } + : undefined; + const operStatus = status.operStatus + ? { + status: status.operStatus.status || undefined, + 'last-updated': status.operStatus.lastUpdated || undefined, + } + : undefined; + return { + 'admin-status': adminStatus, + 'oper-status': operStatus, + }; +} + +function clientCarrierToApiCarrier(carrier: Carrier): CarrierOutput { + return { + 'carrier-name': carrier.carrierName || undefined, + 'carrier-reference': carrier.carrierReference || undefined, + 'service-status': carrier.serviceStatus || undefined, + 'service-type': carrier.serviceType || undefined, + }; +} + +function clientConnectionToApiConnection(connection: Connection): ConnectionOutput { + return { + 'encapsulation-type': connection.encapsulationType || undefined, + 'remote-ne-id': connection.remoteNeId || undefined, + 'remote-port-id': connection.remotePortId || undefined, + 'svlan-assignment-type': connection.svlanAssignmentType || undefined, + mtu: connection.mtu, + tpid: connection.tpId || undefined, + }; +} + +function clientEvcAttachmentsToApiEvcAttachments(attachments: EvcAttachment[]): EvcAttachmentInput | undefined { + if (!attachments.length) { + return undefined; + } + + const result = attachments.map((a: EvcAttachment): EvcAttachmentOutput => { + return { + 'evc-type': a.evcType, + 'customer-name': a.customerName || undefined, + 'circuit-reference': a.circuitReference, + 'carrier-reference': a.carrierReference || undefined, + 'svlan-id': a.svlanId || undefined, + status: a.status ? clientBearerStatusToApiBearerStatus(a.status) : undefined, + 'input-bandwidth': a.inputBandwidth, + 'qos-input-profile': a.qosInputProfile || undefined, + 'upstream-bearer': a.upstreamBearer || undefined, + }; + }); + + return { + 'evc-attachment': result, + }; +} + +export function clientBearerToApiBearer(bearer: VpnBearer): VpnBearerInput { + const output: VpnBearerInput = { + 'vpn-bearer': [ + { + 'sp-bearer-reference': bearer.spBearerReference, + description: bearer.description || undefined, + 'ne-id': bearer.neId, + 'port-id': bearer.portId, + status: bearer.status ? clientBearerStatusToApiBearerStatus(bearer.status) : undefined, + carrier: bearer.carrier ? clientCarrierToApiCarrier(bearer.carrier) : undefined, + connection: bearer.connection ? clientConnectionToApiConnection(bearer.connection) : undefined, + 'default-upstream-bearer': bearer.defaultUpstreamBearer || undefined, + 'evc-attachments': clientEvcAttachmentsToApiEvcAttachments(bearer.evcAttachments), + }, + ], + }; + return output; +} diff --git a/packages/frinx-gamma/src/components/forms/vpn-bearer-form.tsx b/packages/frinx-gamma/src/components/forms/vpn-bearer-form.tsx new file mode 100644 index 000000000..8c716d728 --- /dev/null +++ b/packages/frinx-gamma/src/components/forms/vpn-bearer-form.tsx @@ -0,0 +1,98 @@ +import React, { FC, FormEvent, useEffect, useState } from 'react'; +import { Divider, Button, Input, Stack, FormControl, FormLabel } from '@chakra-ui/react'; +import { VpnSite } from './site-types'; +import { VpnBearer } from './bearer-types'; + +type Props = { + mode: 'add' | 'edit'; + bearer: VpnBearer; + onSubmit: (s: VpnBearer) => void; + onCancel: () => void; + onSiteChange?: (s: VpnSite) => void; +}; + +const VpnBearerForm: FC = ({ bearer, onSubmit, onCancel }) => { + const [bearerState, setBearerState] = useState(bearer); + + useEffect(() => { + setBearerState({ + ...bearer, + }); + }, [bearer]); + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + onSubmit(bearerState); + }; + + return ( +
+ + Ne ID + { + setBearerState({ + ...bearerState, + neId: event.target.value, + }); + }} + /> + + + Port ID + { + setBearerState({ + ...bearerState, + portId: event.target.value, + }); + }} + /> + + + SP Bearer Reference + { + setBearerState({ + ...bearerState, + spBearerReference: event.target.value, + }); + }} + /> + + + Description + { + setBearerState({ + ...bearerState, + description: event.target.value || null, + }); + }} + /> + + + + + + + + + ); +}; + +export default VpnBearerForm; diff --git a/packages/frinx-gamma/src/helpers/id-helpers.ts b/packages/frinx-gamma/src/helpers/id-helpers.ts index 54ee88ae5..5ff608855 100644 --- a/packages/frinx-gamma/src/helpers/id-helpers.ts +++ b/packages/frinx-gamma/src/helpers/id-helpers.ts @@ -24,3 +24,7 @@ export function generateNetworkAccessId(): string { export function generateDeviceId(): string { return `NETWORK_ACCESS_${getRandomString(8)}`; } + +export function generateBearerId(): string { + return `BEARER_${getRandomString(8)}`; +} diff --git a/packages/frinx-gamma/src/index.ts b/packages/frinx-gamma/src/index.ts index f9edbd3b9..38ff7989e 100644 --- a/packages/frinx-gamma/src/index.ts +++ b/packages/frinx-gamma/src/index.ts @@ -12,4 +12,6 @@ export { default as DeviceList } from './pages/device-list/device-list'; export { default as CreateDevice } from './pages/create-device/create-device'; export { default as EditDevice } from './pages/edit-device/edit-device'; export { default as VpnBearerList } from './pages/vpn-bearer-list/vpn-bearer-list'; +export { default as CreateBearer } from './pages/create-bearer/create-bearer'; +export { default as EditBearer } from './pages/edit-bearer/edit-bearer'; export { getUnistoreApiProvider } from './unistore-api-provider'; diff --git a/packages/frinx-gamma/src/network-types.ts b/packages/frinx-gamma/src/network-types.ts index e5ede8317..dd4730bae 100644 --- a/packages/frinx-gamma/src/network-types.ts +++ b/packages/frinx-gamma/src/network-types.ts @@ -605,29 +605,38 @@ export function decodeConnectionOutput(value: unknown): ConnectionOutput { return extractResult(ConnectionOutputValidator.decode(value)); } -const VpnBearerOutputValidator = t.type({ - 'vpn-bearers': optional( +const VpnBearerItemsOutputValidator = t.type({ + 'vpn-bearer': t.array( t.type({ - 'vpn-bearer': t.array( + 'sp-bearer-reference': t.string, + description: optional(t.string), + 'ne-id': t.string, + 'port-id': t.string, + status: optional(BearerStatusValidator), + carrier: optional(CarrierOutputValidator), + connection: optional(ConnectionOutputValidator), + 'default-upstream-bearer': optional(t.string), + 'evc-attachments': optional( t.type({ - 'sp-bearer-reference': t.string, - description: optional(t.string), - 'ne-id': t.string, - 'port-id': t.string, - status: optional(BearerStatusValidator), - carrier: optional(CarrierOutputValidator), - connection: optional(ConnectionOutputValidator), - 'default-upstream-bearer': optional(t.string), - 'evc-attachments': optional( - t.type({ - 'evc-attachment': t.array(EvcAttachmentOutputValidator), - }), - ), + 'evc-attachment': t.array(EvcAttachmentOutputValidator), }), ), }), ), }); +export type VpnBearerItemsOutput = t.TypeOf; +export type VpnBearerInput = VpnBearerItemsOutput; +export function decodeVpnBearerItemsOutput(value: unknown): VpnBearerItemsOutput { + return extractResult(VpnBearerItemsOutputValidator.decode(value)); +} + +export type EvcAttachmentInput = { + 'evc-attachment': EvcAttachmentOutput[]; +}; + +const VpnBearerOutputValidator = t.type({ + 'vpn-bearers': optional(VpnBearerItemsOutputValidator), +}); export type VpnBearerOutput = t.TypeOf; diff --git a/packages/frinx-gamma/src/pages/create-bearer/create-bearer.tsx b/packages/frinx-gamma/src/pages/create-bearer/create-bearer.tsx new file mode 100644 index 000000000..a19947c56 --- /dev/null +++ b/packages/frinx-gamma/src/pages/create-bearer/create-bearer.tsx @@ -0,0 +1,65 @@ +import { Box, Container, Heading } from '@chakra-ui/react'; +import React, { useEffect, VoidFunctionComponent } from 'react'; +import callbackUtils from '../../callback-utils'; +import { VpnBearer } from '../../components/forms/bearer-types'; +import VpnBearerForm from '../../components/forms/vpn-bearer-form'; +import { generateBearerId } from '../../helpers/id-helpers'; + +const defaultVpnBearer: VpnBearer = { + neId: '', + portId: '', + spBearerReference: '', + carrier: null, + defaultUpstreamBearer: null, + connection: null, + description: null, + evcAttachments: [], + status: null, +}; + +type Props = { + onSuccess: () => void; + onCancel: () => void; +}; + +const CreateBearerPage: VoidFunctionComponent = ({ onSuccess, onCancel }) => { + useEffect(() => { + const fetchData = async () => { + // TODO; possible fetches goes here + }; + + fetchData(); + }, []); + + const handleSubmit = async (bearer: VpnBearer) => { + // eslint-disable-next-line no-console + console.log('submit clicked', bearer); + // eslint-disable-next-line no-param-reassign + const newBearer: VpnBearer = { + ...bearer, + spBearerReference: generateBearerId(), + }; + const callbacks = callbackUtils.getCallbacks; + await callbacks.createVpnBearer(newBearer); + // eslint-disable-next-line no-console + console.log('bearer created'); + onSuccess(); + }; + + const handleCancel = () => { + // eslint-disable-next-line no-console + console.log('cancel clicked'); + onCancel(); + }; + + return ( + + + Create VPN Bearer + + + + ); +}; + +export default CreateBearerPage; diff --git a/packages/frinx-gamma/src/pages/edit-bearer/edit-bearer.tsx b/packages/frinx-gamma/src/pages/edit-bearer/edit-bearer.tsx new file mode 100644 index 000000000..4180d9ef1 --- /dev/null +++ b/packages/frinx-gamma/src/pages/edit-bearer/edit-bearer.tsx @@ -0,0 +1,66 @@ +import { Box, Container, Heading } from '@chakra-ui/react'; +import React, { useEffect, useState, VoidFunctionComponent } from 'react'; +import { useParams } from 'react-router'; +import callbackUtils from '../../callback-utils'; +import { VpnBearer } from '../../components/forms/bearer-types'; +import { apiBearerToClientBearer } from '../../components/forms/converters'; +import VpnBearerForm from '../../components/forms/vpn-bearer-form'; +import { generateBearerId } from '../../helpers/id-helpers'; + +type Props = { + onSuccess: () => void; + onCancel: () => void; +}; + +const EditBearerPage: VoidFunctionComponent = ({ onSuccess, onCancel }) => { + const [bearer, setBearer] = useState(null); + const { bearerId } = useParams<{ bearerId: string }>(); + useEffect(() => { + const fetchData = async () => { + // TODO; possible fetches goes here + const callbacks = callbackUtils.getCallbacks; + const response = await callbacks.getVpnBearers(); + const clientVpnBearers = apiBearerToClientBearer(response); + const [selectedBearer] = clientVpnBearers.filter((b) => b.spBearerReference === bearerId); + setBearer(selectedBearer); + }; + + fetchData(); + }, [bearerId]); + + const handleSubmit = async (vpnBearer: VpnBearer) => { + // eslint-disable-next-line no-console + console.log('submit clicked', vpnBearer); + // eslint-disable-next-line no-param-reassign + const newBearer: VpnBearer = { + ...vpnBearer, + spBearerReference: generateBearerId(), + }; + const callbacks = callbackUtils.getCallbacks; + await callbacks.editVpnBearer(newBearer); + // eslint-disable-next-line no-console + console.log('bearer created'); + onSuccess(); + }; + + const handleCancel = () => { + // eslint-disable-next-line no-console + console.log('cancel clicked'); + onCancel(); + }; + + if (!bearer) { + return null; + } + + return ( + + + kEdit VPN Bearer + + + + ); +}; + +export default EditBearerPage; diff --git a/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-list.tsx b/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-list.tsx index b60e2b0b4..3ceeee074 100644 --- a/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-list.tsx +++ b/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-list.tsx @@ -1,20 +1,24 @@ -import { Box, Button, Container, Flex, Heading, HStack, Icon } from '@chakra-ui/react'; +import { useDisclosure, Box, Button, Container, Flex, Heading, HStack, Icon } from '@chakra-ui/react'; import FeatherIcon from 'feather-icons-react'; import React, { useEffect, useState, VoidFunctionComponent } from 'react'; +import ConfirmDeleteModal from '../../components/confirm-delete-modal/confirm-delete-modal'; import callbackUtils from '../../callback-utils'; import CommitStatusModal from '../../components/commit-status-modal/commit-status-modal'; import { VpnBearer } from '../../components/forms/bearer-types'; import { apiBearerToClientBearer } from '../../components/forms/converters'; import VpnBearerTable from './vpn-bearer-table'; +import unwrap from '../../helpers/unwrap'; type Props = { onCreateVpnBearerClick: () => void; - onEditVpnBearerClick: () => void; + onEditVpnBearerClick: (bearerId: string) => void; }; const VpnBearerList: VoidFunctionComponent = ({ onCreateVpnBearerClick, onEditVpnBearerClick }) => { const [vpnBearers, setVpnBearers] = useState(null); const [workflowId, setWorkflowId] = useState(null); + const [bearerIdToDelete, setBearerIdToDelete] = useState(null); + const deleteModalDisclosure = useDisclosure(); useEffect(() => { const fetchData = async () => { @@ -44,8 +48,26 @@ const VpnBearerList: VoidFunctionComponent = ({ onCreateVpnBearerClick, o }); } + function handleDeleteButtonClick(bearerId: string) { + setBearerIdToDelete(bearerId); + deleteModalDisclosure.onOpen(); + } + return ( <> + { + callbackUtils.getCallbacks.deleteVpnBearer(unwrap(bearerIdToDelete)).then(() => { + setVpnBearers(unwrap(vpnBearers).filter((bearer) => bearer.spBearerReference !== bearerIdToDelete)); + deleteModalDisclosure.onClose(); + }); + }} + title="Delete bearer" + > + Are you sure? You can't undo this action afterwards. + {workflowId != null && ( = ({ onCreateVpnBearerClick, o - {vpnBearers && } + + {vpnBearers && ( + + )} + ); diff --git a/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-table.tsx b/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-table.tsx index 6fd08d075..f3df4b942 100644 --- a/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-table.tsx +++ b/packages/frinx-gamma/src/pages/vpn-bearer-list/vpn-bearer-table.tsx @@ -1,14 +1,15 @@ -import { Icon, IconButton, Table, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react'; +import { Icon, IconButton, Table, Tbody, Td, Th, Thead, Tr, HStack } from '@chakra-ui/react'; import FeatherIcon from 'feather-icons-react'; import React, { VoidFunctionComponent } from 'react'; import { VpnBearer } from '../../components/forms/bearer-types'; type Props = { bearers: VpnBearer[]; + onDeleteVpnBearerClick: (id: string) => void; onEditVpnBearerClick: (id: string) => void; }; -const VpnBearerTable: VoidFunctionComponent = ({ bearers, onEditVpnBearerClick }) => { +const VpnBearerTable: VoidFunctionComponent = ({ bearers, onEditVpnBearerClick, onDeleteVpnBearerClick }) => { return ( @@ -24,12 +25,23 @@ const VpnBearerTable: VoidFunctionComponent = ({ bearers, onEditVpnBearer ))}
{b.spBearerReference} {b.status?.adminStatus?.status} - } - onClick={() => onEditVpnBearerClick(b.spBearerReference)} - /> + + } + onClick={() => onEditVpnBearerClick(b.spBearerReference)} + /> + } + onClick={() => { + onDeleteVpnBearerClick(b.spBearerReference); + }} + /> +