diff --git a/ui/src/components/SCV/ScvInputIcon.vue b/ui/src/components/SCV/ScvInputIcon.vue
index 85d204e33f08..50118a75f98b 100644
--- a/ui/src/components/SCV/ScvInputIcon.vue
+++ b/ui/src/components/SCV/ScvInputIcon.vue
@@ -2,16 +2,23 @@
+
+
+
diff --git a/ui/src/components/SnmpConfiguration/SnmpConfigDetailsPanel.vue b/ui/src/components/SnmpConfiguration/SnmpConfigDetailsPanel.vue
index ea6aa8b5d8b8..2ef3ebb73299 100644
--- a/ui/src/components/SnmpConfiguration/SnmpConfigDetailsPanel.vue
+++ b/ui/src/components/SnmpConfiguration/SnmpConfigDetailsPanel.vue
@@ -36,10 +36,15 @@
-
+ selectedMonitoringLocation = val"
+ >
+
@@ -51,7 +56,6 @@
:modelValue="snmpVersion"
@update:modelValue="onSnmpVersionUpdated"
>
-
@@ -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'
@@ -231,7 +233,7 @@ const errors = ref
({})
// local data for form inputs
const firstIpAddress = ref('')
const lastIpAddress = ref('')
-const selectedMonitoringLocation = ref()
+const selectedMonitoringLocation = ref({ _text: DEFAULT_MONITORING_LOCATION, _value: DEFAULT_MONITORING_LOCATION })
const formConfig = reactive(getDefaultSnmpBaseConfiguration())
const scvSearchDrawerOpen = ref(false)
const scvSelectedProperty = ref('')
@@ -241,6 +243,15 @@ const snmpV3Expanded = ref(false)
const displayAdvancedConfig = ref(false)
const displaySnmpV3ContextFields = ref(false)
+const monitoringLocations = computed(() => {
+ 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'
@@ -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 }
@@ -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[] = [
@@ -287,10 +307,6 @@ const snmpV3ContextFields: SnmpFieldInfo[] = [
{ key: 'enterpriseId', label: 'Enterprise ID', hint: 'Enterprise ID', dataTest: 'snmp-definition-enterprise-id' }
]
-const selectedMonitoringLocationValue = computed(() => {
- return String(selectedMonitoringLocation.value?._value ?? '')
-})
-
const loadInitialValues = () => {
const currentConfig: SnmpAgentConfig = props.config ?? getDefaultSnmpBaseConfiguration()
@@ -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, {
diff --git a/ui/src/components/SnmpConfiguration/SnmpConfigLookupPanel.vue b/ui/src/components/SnmpConfiguration/SnmpConfigLookupPanel.vue
index f824f99448ea..0e265ab1dcc7 100644
--- a/ui/src/components/SnmpConfiguration/SnmpConfigLookupPanel.vue
+++ b/ui/src/components/SnmpConfiguration/SnmpConfigLookupPanel.vue
@@ -29,11 +29,16 @@
-
-
+ lookupMonitoringLocation = val"
+ >
+
+
@@ -56,18 +61,17 @@
diff --git a/ui/src/components/SnmpConfiguration/SnmpConfigPairedFieldInputs.vue b/ui/src/components/SnmpConfiguration/SnmpConfigPairedFieldInputs.vue
index 5e3d2408f869..b4b0b4058921 100644
--- a/ui/src/components/SnmpConfiguration/SnmpConfigPairedFieldInputs.vue
+++ b/ui/src/components/SnmpConfiguration/SnmpConfigPairedFieldInputs.vue
@@ -10,10 +10,31 @@
+
+
+
+ handleFormInputUpdate(String(field.key), String(val ?? ''), field.isNumeric)"
+ >
+
+
+
+
+ scvButtonClick(String(field.key))">
+
+
+
+
handleFormInputUpdate(String(field.key), String(val ?? ''), field.isNumeric)"
>
-
- scvButtonClick(String(field.key))">
-
+
+
handleFormSelectUpdate(String(field.key), val, field.isNumeric)"
+ >
+
@@ -33,6 +62,7 @@
diff --git a/ui/src/components/SnmpConfiguration/SnmpConfigTabContainer.vue b/ui/src/components/SnmpConfiguration/SnmpConfigTabContainer.vue
index 5e055189b905..7666f41099fa 100644
--- a/ui/src/components/SnmpConfiguration/SnmpConfigTabContainer.vue
+++ b/ui/src/components/SnmpConfiguration/SnmpConfigTabContainer.vue
@@ -6,8 +6,8 @@
>
Lookup by IP
- Definitions
- Profiles
+ Browse Definitions
+ Browse Profiles
Upload/Download
diff --git a/ui/src/containers/SnmpConfiguration.vue b/ui/src/containers/SnmpConfiguration.vue
index 6b122b66fa00..d1c6b6ad0504 100644
--- a/ui/src/containers/SnmpConfiguration.vue
+++ b/ui/src/containers/SnmpConfiguration.vue
@@ -62,6 +62,7 @@ const breadcrumbs = computed(() => {
const onCreateDefinition = () => {
store.setDefinitionCreateEditMode(SnmpConfigEditMode.Create)
+ store.resetCurrentDefinition()
store.setActiveTab(ActiveTabs.Definitions)
}
@@ -71,6 +72,7 @@ const onCreateProfile = () => {
}
onMounted(async () => {
+ store.resetState()
store.fetchMonitoringLocations()
store.populateSnmpConfig()
scvStore.getAliases()
diff --git a/ui/src/lib/snmpValidator.ts b/ui/src/lib/snmpValidator.ts
index e131d2cea7c4..5bf8c1a79696 100644
--- a/ui/src/lib/snmpValidator.ts
+++ b/ui/src/lib/snmpValidator.ts
@@ -30,7 +30,13 @@ const MIN_PORT = 1
const MAX_PORT = 65535
const MAX_REQUEST_SIZE_MINIMUM = 484
-const SnmpAuthProtocols = [
+export const SecurityLevelSelectionOptions = [
+ { _text: 'No Auth (1)', _value: String(SnmpSecurityLevel.NoAuthNoPriv) },
+ { _text: 'Auth Only (2)', _value: String(SnmpSecurityLevel.AuthNoPriv) },
+ { _text: 'Auth and Privacy (3)', _value: String(SnmpSecurityLevel.AuthPriv) }
+]
+
+export const SnmpAuthProtocols = [
'MD5',
'SHA',
'SHA-224',
@@ -38,7 +44,7 @@ const SnmpAuthProtocols = [
'SHA-512'
]
-const SnmpPrivacyProtocols = [
+export const SnmpPrivacyProtocols = [
'DES',
'AES',
'AES192',
diff --git a/ui/src/stores/snmpConfigStore.ts b/ui/src/stores/snmpConfigStore.ts
index 2ed1f9b24b1d..943026567020 100644
--- a/ui/src/stores/snmpConfigStore.ts
+++ b/ui/src/stores/snmpConfigStore.ts
@@ -199,6 +199,20 @@ export const useSnmpConfigStore = defineStore('useSnmpConfigStore', () => {
currentDefinition.value = definition
}
+ const resetCurrentDefinition = () => {
+ currentDefinition.value = getDefaultSnmpDefinition()
+ }
+
+ const resetState = () => {
+ isLoading.value = false
+ setActiveTab(0)
+ resetCurrentDefinition()
+ setDefinitionCreateEditMode(SnmpConfigEditMode.Table)
+ setSnmpLookupEditMode(SnmpLookupEditMode.Lookup)
+ setProfileLabel('')
+ setSnmpProfileEditMode(SnmpConfigEditMode.Table)
+ }
+
const setProfileLabel = (label: string) => {
profileLabel.value = label
}
@@ -260,13 +274,11 @@ export const useSnmpConfigStore = defineStore('useSnmpConfigStore', () => {
} as SnmpConfigInfoDto
const resp = await saveSnmpDefinition(dto)
-
return resp
}
const removeDefinition = async (ipAddress: string, location: string): Promise => {
const resp = await deleteSnmpDefinition(ipAddress, location)
-
return resp
}
@@ -300,13 +312,11 @@ export const useSnmpConfigStore = defineStore('useSnmpConfigStore', () => {
} as SnmpSaveProfileDto
const resp = await saveSnmpProfile(dto)
-
return resp
}
const deleteProfile = async (label: string): Promise => {
const resp = await deleteSnmpProfile(label)
-
return resp
}
@@ -326,6 +336,8 @@ export const useSnmpConfigStore = defineStore('useSnmpConfigStore', () => {
saveDefinition,
saveProfile,
setActiveTab,
+ resetCurrentDefinition,
+ resetState,
setCurrentDefinition,
setDefinitionCreateEditMode,
setProfileLabel,
diff --git a/ui/src/types/snmpConfig.ts b/ui/src/types/snmpConfig.ts
index 3c14381030f9..5ade2fa6c2a0 100644
--- a/ui/src/types/snmpConfig.ts
+++ b/ui/src/types/snmpConfig.ts
@@ -20,6 +20,8 @@
/// License.
///
+import { ISelectItemType } from '@featherds/select'
+
export enum SnmpSecurityLevel {
None = 0,
NoAuthNoPriv = 1,
@@ -189,11 +191,26 @@ export interface SnmpProfileFormErrors extends SnmpConfigFormErrors {
label?: string
filterExpression?: string
}
+
+// Used for defining the fields for the SnmpConfigPairedFieldInputs component
export interface SnmpFieldInfo {
+ // The key for the field, used to bind to the config object
key: string
+
label: string
hint?: string
dataTest: string
+
+ // if true, the field will display an SCV input icon
scvEnabled?: boolean
+
+ // true if the underlying value is numeric
isNumeric?: boolean
+
+ // true if the field is a select dropdown
+ isSelect?: boolean
+
+ // options for the select dropdown. _text is display label, _value is the underlying value.
+ // _value should be a string even if isNumeric is true
+ selectOptions?: ISelectItemType[]
}