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
31 changes: 28 additions & 3 deletions ui/src/components/SCV/ScvInputIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@
<FeatherTooltip
:title="title ?? tooltipTitle"
v-slot="{ attrs, on }">

<FeatherButton
icon="SCV"
class="scv-edit-icon"
@click="$emit('click')"
>
<FeatherIcon
v-bind="attrs" v-on="on"
:icon="IconSecurity"
class="scv-icon"
@click="$emit('click')"
/>
</FeatherButton>
</FeatherTooltip>
</template>

<script setup lang="ts">
import { FeatherButton } from '@featherds/button'
import { FeatherIcon } from '@featherds/icon'
import { FeatherTooltip } from '@featherds/tooltip'
import IconSecurity from '@featherds/icon/network/Security'
Expand All @@ -29,7 +36,25 @@ const tooltipTitle = 'Use SCV to populate this field'
</script>

<style scoped lang="scss">
.scv-icon {
cursor: pointer;
@use '@featherds/styles/themes/variables';

.btn.btn-icon.scv-edit-icon {
border: 2px solid var(--feather-primary-text-on-surface);
border-radius: 100%;
height: 2.0rem;
width: 2.0rem;
min-width: 2.0rem;

svg.scv-icon {
cursor: pointer;
font-size: 1.25em !important;
background-color: var(--feather-background);
width: 1.5em;
height: 1.5em;

&:hover {
background-color: var(--feather-shade-4);
}
}
}
</style>
55 changes: 35 additions & 20 deletions ui/src/components/SnmpConfiguration/SnmpConfigDetailsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,15 @@

<div class="feather-row">
<div class="feather-col-6" v-if="!props.suppressMonitoringLocation">
<SnmpConfigMonitoringLocationsDropdown
:monitoringLocation="selectedMonitoringLocationValue"
@update:modelValue="selectedMonitoringLocation = $event"
/>
<FeatherSelect
label="Location"
data-test="snmp-monitoring-location-select"
hint="Select a monitoring location"
:options="monitoringLocations"
:modelValue="selectedMonitoringLocation"
@update:modelValue="(val: any) => selectedMonitoringLocation = val"
>
</FeatherSelect>
</div>
<div :class="!props.suppressMonitoringLocation ? 'feather-col-6' : 'feather-col-12'">
<div class="dropdown">
Expand All @@ -51,7 +56,6 @@
:modelValue="snmpVersion"
@update:modelValue="onSnmpVersionUpdated"
>
<FeatherIcon :icon="MoreVert" />
</FeatherSelect>
</div>
</div>
Expand Down Expand Up @@ -189,14 +193,12 @@
import { FeatherButton } from '@featherds/button'
import { FeatherCheckbox } from '@featherds/checkbox'
import { FeatherExpansionPanel } from '@featherds/expansion'
import MoreVert from '@featherds/icon/navigation/MoreVert'
import { FeatherInput } from '@featherds/input'
import { FeatherSelect, ISelectItemType } from '@featherds/select'
import { DEFAULT_SNMP_V3_SECURITY_LEVEL } from '@/lib/constants'
import { DEFAULT_MONITORING_LOCATION, DEFAULT_SNMP_V3_SECURITY_LEVEL } from '@/lib/constants'
import { getDefaultSnmpBaseConfiguration, useSnmpConfigStore } from '@/stores/snmpConfigStore'
import { SnmpAgentConfig, SnmpBaseConfiguration, SnmpConfigFormErrors, SnmpFieldInfo } from '@/types/snmpConfig'
import { validateDefinition } from '@/lib/snmpValidator'
import SnmpConfigMonitoringLocationsDropdown from './SnmpConfigMonitoringLocationsDropdown.vue'
import { validateDefinition, SecurityLevelSelectionOptions, SnmpAuthProtocols, SnmpPrivacyProtocols } from '@/lib/snmpValidator'
import SnmpConfigPairedFieldInputs from './SnmpConfigPairedFieldInputs.vue'
import ScvSearchDrawer from '../SCV/ScvSearchDrawer.vue'
import { ScvSearchItem } from '@/types/scv'
Expand Down Expand Up @@ -231,7 +233,7 @@ const errors = ref<SnmpConfigFormErrors>({})
// local data for form inputs
const firstIpAddress = ref('')
const lastIpAddress = ref('')
const selectedMonitoringLocation = ref<ISelectItemType>()
const selectedMonitoringLocation = ref<ISelectItemType>({ _text: DEFAULT_MONITORING_LOCATION, _value: DEFAULT_MONITORING_LOCATION })
const formConfig = reactive<SnmpBaseConfiguration>(getDefaultSnmpBaseConfiguration())
const scvSearchDrawerOpen = ref(false)
const scvSelectedProperty = ref('')
Expand All @@ -241,6 +243,15 @@ const snmpV3Expanded = ref(false)
const displayAdvancedConfig = ref(false)
const displaySnmpV3ContextFields = ref(false)

const monitoringLocations = computed<ISelectItemType[]>(() => {
return store.monitoringLocations.map(loc => {
return {
_text: loc.name,
_value: loc.name
}
})
})

const displaySnmp2Params = computed(() => {
const version = String(snmpVersion.value?._value || '')
return version === 'v1' || version === 'v2c'
Expand All @@ -251,7 +262,7 @@ const displaySnmp3Params = computed(() => {
return version === 'v3'
})

// Field metadata for v-for rendering
// Field metadata for v-for rendering using SnmpConfigPairedFieldInputs
const generalParamFields: SnmpFieldInfo[] = [
{ key: 'timeout', label: 'Timeout', hint: 'Timeout in milliseconds', dataTest: 'snmp-definition-timeout', isNumeric: true },
{ key: 'retry', label: 'Retries', hint: 'Number of retries', dataTest: 'snmp-definition-retry', isNumeric: true }
Expand All @@ -273,11 +284,20 @@ const snmpV2Fields: SnmpFieldInfo[] = [

const snmpV3Fields: SnmpFieldInfo[] = [
{ key: 'securityName', label: 'Security Name', hint: 'SNMP v3 security name', dataTest: 'snmp-definition-security-name', scvEnabled: true },
{ key: 'securityLevel', label: 'Security Level', hint: 'SNMP v3 security level', dataTest: 'snmp-definition-security-level', isNumeric: true },
{
key: 'securityLevel', label: 'Security Level', hint: 'SNMP v3 security level', dataTest: 'snmp-definition-security-level', isNumeric: true,
isSelect: true, selectOptions: SecurityLevelSelectionOptions
},
{ key: 'authPassphrase', label: 'Auth Passphrase', hint: 'Authentication passphrase', dataTest: 'snmp-definition-auth-passphrase', scvEnabled: true },
{ key: 'authProtocol', label: 'Auth Protocol', hint: 'Authentication protocol', dataTest: 'snmp-definition-auth-protocol' },
{
key: 'authProtocol', label: 'Auth Protocol', hint: 'Authentication protocol', dataTest: 'snmp-definition-auth-protocol',
isSelect: true, selectOptions: SnmpAuthProtocols.map(protocol => ({ _text: protocol, _value: protocol }))
},
{ key: 'privacyPassphrase', label: 'Privacy Passphrase', hint: 'Privacy passphrase', dataTest: 'snmp-definition-privacy-passphrase', scvEnabled: true },
{ key: 'privacyProtocol', label: 'Privacy Protocol', hint: 'Privacy protocol', dataTest: 'snmp-definition-privacy-protocol' }
{
key: 'privacyProtocol', label: 'Privacy Protocol', hint: 'Privacy protocol', dataTest: 'snmp-definition-privacy-protocol',
isSelect: true, selectOptions: SnmpPrivacyProtocols.map(protocol => ({ _text: protocol, _value: protocol }))
}
]

const snmpV3ContextFields: SnmpFieldInfo[] = [
Expand All @@ -287,10 +307,6 @@ const snmpV3ContextFields: SnmpFieldInfo[] = [
{ key: 'enterpriseId', label: 'Enterprise ID', hint: 'Enterprise ID', dataTest: 'snmp-definition-enterprise-id' }
]

const selectedMonitoringLocationValue = computed<string>(() => {
return String(selectedMonitoringLocation.value?._value ?? '')
})

const loadInitialValues = () => {
const currentConfig: SnmpAgentConfig = props.config ?? getDefaultSnmpBaseConfiguration()

Expand All @@ -304,8 +320,7 @@ const loadInitialValues = () => {

firstIpAddress.value = props.firstIp || ''
lastIpAddress.value = props.lastIp || ''
const matchedLoc = store.monitoringLocations.find(x => x.name === currentConfig.location)
selectedMonitoringLocation.value = matchedLoc ? { _text: matchedLoc.name, _value: matchedLoc.name } : undefined
selectedMonitoringLocation.value = { _text: DEFAULT_MONITORING_LOCATION, _value: DEFAULT_MONITORING_LOCATION }

// Load all config fields into formConfig
Object.assign(formConfig, {
Expand Down
32 changes: 20 additions & 12 deletions ui/src/components/SnmpConfiguration/SnmpConfigLookupPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@
<label class="label">Location:</label>
</div>
<div class="feather-col-8">
<SnmpConfigMonitoringLocationsDropdown
:monitoringLocation="lookupMonitoringLocationValue"
@update:modelValue="lookupMonitoringLocation = $event"
/>
</div>
<FeatherSelect
label="Location"
data-test="snmp-monitoring-location-select"
hint="Select a monitoring location"
:options="monitoringLocations"
:modelValue="lookupMonitoringLocation"
@update:modelValue="(val: any) => lookupMonitoringLocation = val"
>
</FeatherSelect>
</div>
</div>

<div class="feather-row">
Expand All @@ -56,18 +61,17 @@
<script setup lang="ts">
import { FeatherButton } from '@featherds/button'
import { FeatherInput } from '@featherds/input'
import { ISelectItemType } from '@featherds/select'
import { FeatherSelect, ISelectItemType } from '@featherds/select'
import useSnackbar from '@/composables/useSnackbar'
import { SnmpLookupEditMode, useSnmpConfigStore } from '@/stores/snmpConfigStore'
import { SnmpAgentConfig } from '@/types/snmpConfig'
import SnmpConfigMonitoringLocationsDropdown from './SnmpConfigMonitoringLocationsDropdown.vue'
import { DEFAULT_MONITORING_LOCATION } from '@/lib/constants'

const snackbar = useSnackbar()
const store = useSnmpConfigStore()
const lookupIpAddress = ref('')
const lookupConfig = ref<SnmpAgentConfig>()
const lookupMonitoringLocation = ref<ISelectItemType>()
const lookupMonitoringLocation = ref<ISelectItemType>({ _text: DEFAULT_MONITORING_LOCATION, _value: DEFAULT_MONITORING_LOCATION })
const isLoading = ref(false)

// lookup config response individual parameters to edit
Expand All @@ -77,15 +81,19 @@ const emit = defineEmits<{
(e: 'lookup-complete', config: SnmpAgentConfig, ipAddress: string): void
}>()

const lookupMonitoringLocationValue = computed<string>(() => {
return String(lookupMonitoringLocation.value?._value ?? DEFAULT_MONITORING_LOCATION)
const monitoringLocations = computed<ISelectItemType[]>(() => {
return store.monitoringLocations.map(loc => {
return {
_text: loc.name,
_value: loc.name
}
})
})

const resetValues = () => {
lookupIpAddress.value = ''
lookupConfig.value = undefined
const defaultLoc = store.monitoringLocations.find(loc => loc.name === DEFAULT_MONITORING_LOCATION)
lookupMonitoringLocation.value = defaultLoc ? { _text: defaultLoc.name, _value: defaultLoc.name } : undefined
lookupMonitoringLocation.value = { _text: DEFAULT_MONITORING_LOCATION, _value: DEFAULT_MONITORING_LOCATION }
ipAddress.value = ''
}

Expand Down

This file was deleted.

Loading