Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add port forward page #48

Merged
merged 14 commits into from
Oct 4, 2023
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
52 changes: 51 additions & 1 deletion public/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"http_404": "Resource not found",
"http_500": "Server error",
"required": "Required",
"required_option": "Select at least one option",
"validation_failed": "Validation failed",
"invalid_hostname": "Invalid hostname",
"hostname_is_too_long": "Hostname has too many characters",
Expand All @@ -34,6 +35,7 @@
"invalid_ip_v6_address": "Invalid IPv6 address",
"invalid_cidr_v4_address": "Enter a valid IPv4 address with CIDR notation",
"invalid_cidr_v6_address": "Enter a valid IPv6 address with CIDR notation",
"invalid_port": "Enter an integer number between 1 and 65535",
"invalid_uci_name": "Only letters, numbers and underscore (_) are allowed",
"cannot_apply_configuration_changes": "Cannot apply configuration changes",
"cannot_revert_configuration_changes": "Cannot revert configuration changes",
Expand All @@ -54,7 +56,16 @@
"cannot_retrieve_wan_list": "Cannot retrieve WAN list",
"cannot_retrieve_wan_traffic": "Cannot retrieve WAN traffic",
"register_unit_error": "Cannot register unit",
"cancel_registration_error": "Cannot cancel registration"
"cancel_registration_error": "Cannot cancel registration",
"cannot_delete_port_forward": "Cannot delete port forward",
"cannot_create_port_forward": "Cannot create port forward",
"cannot_edit_port_forward": "Cannot edit port forward",
"cannot_duplicate_port_forward": "Cannot duplicate port forward",
"cannot_enable_port_forward": "Cannot enable port forward",
"cannot_disable_port_forward": "Cannot disable port forward",
"cannot_retrieve_protocols": "Cannot retrieve protocols",
"cannot_retrieve_zones": "Cannot retrieve zones",
"cannot_retrieve_wan_interfaces": "Cannot retrieve WAN interfaces"
},
"ne_text_input": {
"show_password": "Show password",
Expand Down Expand Up @@ -459,6 +470,45 @@
"enable_logging": "Enable logging on this zone",
"delete_zone": "Delete \"{0}\"?"
},
"port_forward": {
"title": "Port forward",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"add_port_forward": "Add port forward",
"name": "Name",
"source_port": "Source port",
"destination_port": "Destination port",
"protocols": "Protocols",
"wan_ip": "WAN IP",
"restrict_access_to": "Restrict access to",
"status": "Status",
"enabled": "Enabled",
"disabled": "Disabled",
"filter": "Filter",
"enable": "Enable",
"disable": "Disable",
"duplicate": "Duplicate",
"delete_port_forward": "Delete port forward",
"delete_port_forward_message": "You are about to delete port forward '{name}'",
"destination": "Destination",
"edit_port_forward": "Edit port forward",
"destination_address": "Destination address",
"destination_zone": "Destination zone",
"advanced_settings": "Advanced settings",
"add_ip_address": "Add IP address",
"log": "Log",
"hairpin_nat": "Hairpin NAT",
"hairpin_nat_zones": "Hairpin NAT enabled on following zones",
"choose_zone": "Choose zone",
"choose_protocol": "Choose protocol",
"any_zone": "Any zone",
"any": "Any",
"destination_address_tooltip": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"restrict_access_to_tooltip": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"no_port_forward_configured": "No port forward configured",
"no_port_forward_found": "No port forward found",
"filter_change_suggestion": "Try changing filter value",
"copy": "Copy"
},
"firewall": {
"title": "Firewall"
},
Expand Down
83 changes: 83 additions & 0 deletions src/components/standalone/NeMultiTextInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<script setup lang="ts">
import { onMounted } from 'vue'
import { ref } from 'vue'
import { NeButton, NeTextInput } from '@nethserver/vue-tailwind-lib'
import { watch } from 'vue'

const props = defineProps<{
modelValue: string[]
addItemLabel: string
invalidMessages?: string[]
title?: string
optional?: boolean
disableInputs?: boolean
disableAddButton?: boolean
optionalLabel?: string
}>()

const emit = defineEmits(['delete-item', 'add-item', 'update:modelValue'])

const items = ref<string[]>([])

function deleteItem(idx: number) {
items.value.splice(idx, 1)
emit('update:modelValue', items.value)
emit('delete-item')
}

function addItem() {
items.value.push('')
emit('update:modelValue', items.value)
emit('add-item')
}

function updateModelValue(idx: number, newValue: string) {
items.value[idx] = newValue
emit('update:modelValue', items.value)
}

watch(props.modelValue, () => {
items.value = [...props.modelValue]
})

onMounted(() => {
items.value = [...props.modelValue]
})
</script>

<template>
<div>
<div v-if="title" class="mb-4 flex items-end justify-between">
<div>
<span class="mr-2 text-sm font-medium leading-6 text-gray-700 dark:text-gray-200">
{{ title }}
</span>
<slot name="tooltip"></slot>
</div>
<span v-if="optional" class="ml-2 font-normal">{{ optionalLabel }}</span>
</div>

<div class="space-y-6">
<div class="space-y-4">
<div v-for="(item, i) in items" :key="i" class="flex items-start gap-2">
<NeTextInput
:value="items[i]"
@input="updateModelValue(i, $event.target.value)"
class="grow"
:invalid-message="invalidMessages ? invalidMessages[i] : ''"
:disabled="disableInputs"
/>
<NeButton kind="tertiary" size="md" @click="deleteItem(i)">
<font-awesome-icon :icon="['fas', 'trash']" class="h-4 w-4 py-1" aria-hidden="true" />
</NeButton>
</div>
<NeButton size="md" @click="addItem" :disabled="disableAddButton">
<template #prefix>
<font-awesome-icon :icon="['fas', 'plus']" class="h-4 w-4" aria-hidden="true" />
</template>
{{ addItemLabel }}
</NeButton>
</div>
</div>
</div>
</template>
2 changes: 1 addition & 1 deletion src/components/standalone/NeTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ table {

/* Base style CSS. */
.table-basic {
@apply -mx-4 overflow-hidden overflow-x-auto border-y border-gray-300 dark:border-gray-600 sm:mx-0 sm:rounded-lg sm:border-x;
@apply -mx-4 overflow-x-auto border-y border-gray-300 dark:border-gray-600 sm:mx-0 sm:rounded-lg sm:border-x;
}

.table-basic.ghost {
Expand Down
4 changes: 4 additions & 0 deletions src/components/standalone/SideMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ const navigation: Ref<any> = ref([
to: 'firewall',
icon: 'block-brick-fire',
children: [
{
name: t('standalone.port_forward.title'),
to: 'firewall/port-forward'
},
{
name: t('standalone.zones_and_policies.title'),
to: 'firewall/zones-and-policies'
Expand Down
Loading