@ -112,7 +112,7 @@
< span class = "max-md:hidden text-sm" > {{$t("backup")}}< / span >
< / a >
<!-- New client -->
< button @ click = "clientCreate = true; clientCreateName = ''; clientCreateAllowedIps = ''; "
< button @ click = "clientCreate = true; clientCreateName = '';"
class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-600 py-2 px-4 rounded inline-flex items-center transition">
< svg class = "w-4 mr-2" inline xmlns = "http://www.w3.org/2000/svg" fill = "none" viewBox = "0 0 24 24"
stroke="currentColor">
@ -308,7 +308,7 @@
<!-- AllowedIPs -->
< button
class="align-middle bg-gray-100 dark:bg-neutral-600 dark:text-neutral-300 hover:bg-red-800 dark:hover:bg-red-800 hover:text-white dark:hover:text-white p-2 rounded transition"
title="Edit Allowed IPs " @click="clientEditAllowedIPs = client">
:title="$t('editAllowedIPs') " @click="clientEditAllowedIPs = client">
< svg xmlns = "http://www.w3.org/2000/svg" class = "w-5 icon icon-tabler icon-tabler-list" viewBox = "0 0 24 24" stroke-width = "2" stroke = "currentColor" fill = "none" stroke-linecap = "round" stroke-linejoin = "round" >
< path stroke = "none" d = "M0 0h24v24H0z" fill = "none" / >
< path d = "M9 6l11 0" / >
@ -467,12 +467,6 @@
type="text" v-model.trim="clientCreateName" :placeholder="$t('name')" />
< / p >
< / div >
< div class = "mt-2" >
< p class = "text-sm text-gray-500" >
< input class = "rounded p-2 border-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 dark:placeholder:text-neutral-400 outline-none w-full"
type="text" v-model.trim="clientCreateAllowedIps" placeholder="Allowed IPs (optional)" />
< / p >
< / div >
< / div >
< / div >
< / div >
@ -562,80 +556,101 @@
< / div >
< / div >
< / div >
< / div >
<!-- edit allowedIPs dialog -->
< div v-if = "clientEditAllowedIPs" class = "fixed z-10 inset-0 overflow-y-auto" >
< div class = "flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0" >
< div class = "fixed inset-0 transition-opacity" aria-hidden = "true" >
< div class = "absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50" > < / div >
< / div >
< span class = "hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden = "true" > ​ < / span >
< div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
role="dialog" aria-modal="true" aria-labelledby="modal-headline">
< div class = "bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4" >
< div class = "sm:flex sm:items-start" >
< div class = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full text-white bg-red-800 sm:mx-0 sm:h-10 sm:w-10" >
< svg xmlns = "http://www.w3.org/2000/svg" class = "icon icon-tabler icon-tabler-topology-star" width = "24" height = "24" viewBox = "0 0 24 24" stroke-width = "2" stroke = "currentColor" fill = "none" stroke-linecap = "round" stroke-linejoin = "round" >
< path stroke = "none" d = "M0 0h24v24H0z" fill = "none" / >
< path d = "M8 18a2 2 0 1 0 -4 0a2 2 0 0 0 4 0z" / >
< path d = "M20 6a2 2 0 1 0 -4 0a2 2 0 0 0 4 0z" / >
< path d = "M8 6a2 2 0 1 0 -4 0a2 2 0 0 0 4 0z" / >
< path d = "M20 18a2 2 0 1 0 -4 0a2 2 0 0 0 4 0z" / >
< path d = "M14 12a2 2 0 1 0 -4 0a2 2 0 0 0 4 0z" / >
< path d = "M7.5 7.5l3 3" / >
< path d = "M7.5 16.5l3 -3" / >
< path d = "M13.5 13.5l3 3" / >
< path d = "M16.5 7.5l-3 3" / >
< / svg >
< / div >
< div class = "mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left" >
< h3 class = "text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200" id = "modal-headline" >
Edit AllowedIPs
< / h3 >
< div class = "mt-2 flex items-center flex-col" >
< div class = "w-full min-h-5 flex flex-wrap" >
< div :class = "[item.address!==clientEditAllowedIPs.address?'pr-8':'']" class = "bg-white text-gray-700 relative h-8 tracking-widest border-2 border-gray-100 text-sm items-center rounded p-1 mb-2 mr-2 px-2 cursor-pointer flex w-fit" v-for = "(item,index) in clientEditAllowedIPs.allowedIPs" >
{{item.address+'/'+item.cidr}}
< div v-if = "item.address!==clientEditAllowedIPs.address" style = "width:calc(2rem - 4px);height:calc(2rem - 4px)" class = "hover:bg-red-800 hover:text-white rounded top-0 right-0 w-8 h-8 flex justify-center items-center absolute" >
< svg @ click = "removeIP(index)" xmlns = "http://www.w3.org/2000/svg" class = "icon icon-tabler icon-tabler-x" width = "15" height = "15" viewBox = "0 0 24 24" stroke-width = "2" stroke = "currentColor" fill = "none" stroke-linecap = "round" stroke-linejoin = "round" >
< path stroke = "none" d = "M0 0h24v24H0z" fill = "none" / >
< line x1 = "18" y1 = "6" x2 = "6" y2 = "18" / >
< line x1 = "6" y1 = "6" x2 = "18" y2 = "18" / > < / svg >
< / div >
< / div >
< / div >
< div class = "w-full flex items-center" >
< div class = "h-8 text-gray-700 w-fit text-sm bg-white border-2 border-gray-100 rounded flex items-center px-2" >
< input maxlength = "3" v-model . number = "userInputIP[0]" class = "w-8 text-center outline-none border-none bg-transparent" / > < span > ⋅< / span >
< input maxlength = "3" v-model . number = "userInputIP[1]" class = "w-8 text-center outline-none border-none bg-transparent" / > < span > ⋅< / span >
< input maxlength = "3" v-model . number = "userInputIP[2]" class = "w-8 text-center outline-none border-none bg-transparent" / > < span > ⋅< / span >
< input maxlength = "3" v-model . number = "userInputIP[3]" class = "w-8 text-center outline-none border-none bg-transparent" / > < span > /< / span >
< input maxlength = "2" v-model . number = "userInputIP[4]" class = "w-8 text-center outline-none border-none bg-transparent" / >
<!-- Allowed Ips -->
< div v-if = "clientEditAllowedIPs" class = "fixed z-10 inset-0 overflow-y-auto" >
< div class = "flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0" >
< div class = "fixed inset-0 transition-opacity" aria-hidden = "true" >
< div class = "absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50" > < / div >
< / div >
<!-- This element is to trick the browser into centering the modal contents. -->
< span class = "hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden = "true" > ​ < / span >
< div class = "inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full"
role="dialog" aria-modal="true" aria-labelledby="modal-headline">
< div class = "bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4" >
< div class = "sm:flex sm:items-start" >
< div class = "mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-800 sm:mx-0 sm:h-10 sm:w-10" >
< svg class = "h-6 w-6 text-white" inline xmlns = "http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
< path stroke-linecap = "round" stroke-linejoin = "round" stroke-width = "2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
< / svg >
< / div >
< div class = "flex-grow mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left" >
< h3 class = "text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200" id = "modal-headline" >
{{$t("allowedIPs")}}
< / h3 >
<!-- Ip address input -->
< div class = "w-full flex items-center mt-3" >
< div class = "rounded p-1 border-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 dark:placeholder:text-neutral-400 outline-none" >
< input maxlength = "3" v-model . number = "userInputIP[0]" placeholder = "10" @ keydown = "handleKeyDown($event, '.', 'ip1')" class = "w-8 text-center outline-none border-none bg-transparent" / >
< sub class = "text-neutral-400" > ⋅< / sub >
< input maxlength = "3" v-model . number = "userInputIP[1]" placeholder = "0" ref = "ip1" @ keydown = "handleKeyDown($event, '.', 'ip2')" class = "w-8 text-center outline-none border-none bg-transparent" / >
< sub class = "text-neutral-400" > ⋅< / sub >
< input maxlength = "3" v-model . number = "userInputIP[2]" placeholder = "0" ref = "ip2" @ keydown = "handleKeyDown($event, '.', 'ip3')" class = "w-8 text-center outline-none border-none bg-transparent" / >
< sub class = "text-neutral-400" > ⋅< / sub >
< input maxlength = "3" v-model . number = "userInputIP[3]" placeholder = "0" ref = "ip3" @ keydown = "handleKeyDown($event, '/', 'ip4')" class = "w-8 text-center outline-none border-none bg-transparent" / >
< span class = "text-neutral-400" > /< / span >
< input maxlength = "2" v-model . number = "userInputIP[4]" placeholder = "8" ref = "ip4" class = "w-8 text-center outline-none border-none bg-transparent" / >
< / div >
< div @ click = "addNewIP" class = "w-8 h-8 rounded bg-white hover:border-red-800 hover:bg-red-800 hover:text-white text-gray-700 border-2 border-gray-100 cursor-pointer ml-2 flex justify-center items-center" >
< svg xmlns = "http://www.w3.org/2000/svg" class = "icon icon-tabler icon-tabler-plus" width = "18" height = "18" viewBox = "0 0 24 24" stroke-width = "2" stroke = "currentColor" fill = "none" stroke-linecap = "round" stroke-linejoin = "round" >
<!-- Ip address add -->
< button v-if = "userInputIP.length == 5" @ click = "addNewIP"
class="w-9 h-9 rounded p-1 ml-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 hover:border-red-700 dark:text-neutral-200 dark:border-neutral-600 cursor-pointer flex justify-center items-center">
< svg xmlns = "http://www.w3.org/2000/svg" class = "icon icon-tabler icon-tabler-plus"
width="18" height="18" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
< path stroke = "none" d = "M0 0h24v24H0z" fill = "none" / >
< path d = "M12 5l0 14" / >
< path d = "M5 12l14 0" / >
< / svg >
< / button >
< button v-else
class="w-9 h-9 rounded ml-2 bg-gray-200 dark:bg-neutral-400 text-white dark:text-neutral-300 border-gray-100 dark:border-neutral-600 dark:bg-neutral-500 flex justify-center items-center cursor-not-allowed">
< svg
xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-plus"
width="18" height="18" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
< path stroke = "none" d = "M0 0h24v24H0z" fill = "none" / >
< path d = "M12 5l0 14" / >
< path d = "M5 12l14 0" / > < / svg >
< path d = "M5 12l14 0" / >
< / svg >
< / button >
< / div >
<!-- Allowed ips inline display -->
< div class = "mt-5" >
< div class = "w-full min-h-5 flex flex-wrap" >
< div :class = "[item.address!==clientEditAllowedIPs.address?'pr-8':'']" v-for = "(item,index) in clientEditAllowedIPs.allowedIPs"
class="rounded p-1 border-2 mt-2 mb-2 mr-2 px-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 relative h-8 tracking-widest text-sm items-center cursor-pointer flex w-fit">
{{item.address+'/'+item.cidr}}
< div v-if = "item.address!==clientEditAllowedIPs.address" style = "width:calc(2rem - 4px);height:calc(2rem - 4px)"
class="rounded top-0 right-0 w-8 h-8 bg-red-800 hover:bg-red-700 text-white hover:text-white hover:border-red-700 dark:text-neutral-200 dark:border-neutral-600 flex justify-center items-center absolute">
< svg @ click = "removeIP(index)" xmlns = "http://www.w3.org/2000/svg" class = "icon icon-tabler icon-tabler-x"
width="15" height="15" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
< path stroke = "none" d = "M0 0h24v24H0z" fill = "none" / >
< line x1 = "18" y1 = "6" x2 = "6" y2 = "18" / >
< line x1 = "6" y1 = "6" x2 = "18" y2 = "18" / >
< / svg >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "bg-gray-50 dark:bg-neutral-600 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse" >
< button type = "button" @ click = "updateClientAllowedIPs(clientEditAllowedIPs); clientEditAllowedIPs = null"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 dark:bg-red-600 text-base font-medium text-white dark:text-white hover:bg-red-700 dark:hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm">
Save
< / button >
< button type = "button" @ click = "clientEditAllowedIPs = null"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
Cancel
< / button >
< div class = "bg-gray-50 dark:bg-neutral-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse" >
< button type = "button" @ click = "updateClientAllowedIPs(clientEditAllowedIPs); clientEditAllowedIPs = null"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm">
{{$t("update")}}
< / button >
< button type = "button" @ click = "clientEditAllowedIPs = null"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm">
{{$t("cancel")}}
< / button >
< / div >
< / div >
< / div >
< / div >
<!-- End Allowed Ips -->
< / div >
< div v-if = "authenticated === false" >