Handle service modifications

This commit is contained in:
nemunaire 2020-06-11 01:18:33 +02:00
parent 23311495ce
commit 8c829ba656
10 changed files with 137 additions and 11 deletions

View File

@ -32,6 +32,7 @@
package admin
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
@ -58,6 +59,10 @@ func init() {
router.GET("/api/zones/:zoneid", api.ApiHandler(zoneHandler(getZone)))
router.PUT("/api/zones/:zoneid", api.ApiHandler(zoneHandler(updateZone)))
router.DELETE("/api/zones/:zoneid", api.ApiHandler(deleteZone))
router.GET("/api/users/:userid/domains/:domain/zones/:zoneid/:serviceid", api.ApiHandler(zoneHandler(getZoneService)))
router.PUT("/api/users/:userid/domains/:domain/zones/:zoneid/:serviceid", api.ApiHandler(zoneHandler(updateZoneService)))
router.PATCH("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(zoneHandler(patchZoneService)))
}
func getUserDomainZones(_ *config.Options, domain *happydns.Domain, _ httprouter.Params, _ io.Reader) api.Response {
@ -115,6 +120,50 @@ func updateZone(_ *config.Options, zone *happydns.Zone, _ httprouter.Params, bod
return api.NewAPIResponse(uz, storage.MainStore.UpdateZone(uz))
}
func getZoneService(_ *config.Options, zone *happydns.Zone, ps httprouter.Params, body io.Reader) api.Response {
serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid"))
if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err)
}
return api.NewAPIResponse(zone.FindService(serviceid), nil)
}
func updateZoneService(_ *config.Options, zone *happydns.Zone, ps httprouter.Params, body io.Reader) api.Response {
serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid"))
if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err)
}
usc := &happydns.ServiceCombined{}
err = json.NewDecoder(body).Decode(&usc)
if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, fmt.Errorf("Something is wrong in received data: %w", err))
}
err = zone.EraseService(usc.Domain, serviceid, usc)
if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err)
}
return api.NewAPIResponse(zone.Services, storage.MainStore.UpdateZone(zone))
}
func patchZoneService(_ *config.Options, zone *happydns.Zone, _ httprouter.Params, body io.Reader) api.Response {
usc := &happydns.ServiceCombined{}
err := json.NewDecoder(body).Decode(&usc)
if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, fmt.Errorf("Something is wrong in received data: %w", err))
}
err = zone.EraseService(usc.Domain, usc.Id, usc)
if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err)
}
return api.NewAPIResponse(zone.Services, storage.MainStore.UpdateZone(zone))
}
func deleteZone(opts *config.Options, ps httprouter.Params, body io.Reader) api.Response {
zoneid, err := strconv.ParseInt(ps.ByName("zoneid"), 10, 64)
if err != nil {

View File

@ -32,7 +32,9 @@
package api
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strconv"
@ -47,6 +49,7 @@ import (
func init() {
router.GET("/api/domains/:domain/zone/:zoneid", apiAuthHandler(zoneHandler(getZone)))
router.PATCH("/api/domains/:domain/zone/:zoneid", apiAuthHandler(zoneHandler(updateZoneService)))
router.POST("/api/domains/:domain/import_zone", apiAuthHandler(domainHandler(importZone)))
}
@ -146,3 +149,31 @@ func importZone(opts *config.Options, domain *happydns.Domain, body io.Reader) R
response: myZone.Id,
}
}
func updateZoneService(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, body io.Reader) Response {
usc := &happydns.ServiceCombined{}
err := json.NewDecoder(body).Decode(&usc)
if err != nil {
return APIErrorResponse{
err: fmt.Errorf("Something is wrong in received data: %w", err),
}
}
err = zone.EraseService(usc.Domain, usc.Id, usc)
if err != nil {
return APIErrorResponse{
err: err,
}
}
err = storage.MainStore.UpdateZone(zone)
if err != nil {
return APIErrorResponse{
err: err,
}
}
return APIResponse{
response: zone,
}
}

View File

@ -44,13 +44,14 @@
</b-badge>
</b-list-group-item>
<b-list-group-item v-if="showDetails">
<h-resource-value v-model="service.Service" edit-toolbar :services="services" :type="service._svctype" />
<h-resource-value v-model="service.Service" edit-toolbar :services="services" :type="service._svctype" @saveService="saveService(service, $event)" />
</b-list-group-item>
</b-list-group>
</template>
<script>
import ServiceSpecsApi from '@/services/ServiceSpecsApi'
import ZoneApi from '@/services/ZoneApi'
export default {
name: 'HDomainService',
@ -95,6 +96,31 @@ export default {
},
methods: {
saveService (service, cbSuccess, cbFail) {
ZoneApi.updateZoneService(this.origin, this.zoneMeta.id, service)
.then(
(response) => {
this.$emit('updateMyServices', response.data)
if (cbSuccess != null) {
cbSuccess()
}
},
(error) => {
this.$bvToast.toast(
error.response.data.errmsg, {
title: 'An error occurs when updating the service!',
autoHideDelay: 5000,
variant: 'danger',
toaster: 'b-toaster-content-right'
}
)
if (cbFail != null) {
cbFail(error)
}
}
)
},
toogleShowDetails () {
this.showDetails = !this.showDetails
}

View File

@ -32,7 +32,7 @@
-->
<template>
<component :is="itemComponent" :value="value" @input="$emit('input', $event)" :edit="edit" :edit-toolbar="editToolbar" :index="index" :services="services" :specs="specs" :type="type" @saveService="$emit('saveService')" />
<component :is="itemComponent" :value="value" @input="$emit('input', $event)" :edit="edit" :edit-toolbar="editToolbar" :index="index" :services="services" :specs="specs" :type="type" @saveService="$emit('saveService', $event)" />
</template>
<script>

View File

@ -94,6 +94,8 @@ export default {
set (value) {
if (this.specs.type === 'time.Duration') {
this.$emit('input', value * 1000000000)
} else if (this.specs.type === 'int' || this.specs.type === 'int8' || this.specs.type === 'int16' || this.specs.type === 'int32' || this.specs.type === 'int64' || this.specs.type === 'uint' || this.specs.type === 'uint8' || this.specs.type === 'uint16' || this.specs.type === 'uint32' || this.specs.type === 'uint64') {
this.$emit('input', parseInt(value, 10))
} else {
this.$emit('input', value)
}

View File

@ -52,7 +52,7 @@
:services="services"
:specs="spec"
:type="spec.type"
@saveService="$emit('saveService')"
@saveService="$emit('saveService', $event)"
/>
<b-button v-else>
Create {{ spec.id }}
@ -65,7 +65,7 @@
<b-icon icon="pencil" />
Edit
</b-button>
<b-button v-else type="button" size="sm" variant="primary" class="mx-1" @click="$emit('saveService')">
<b-button v-else type="button" size="sm" variant="primary" class="mx-1" @click="$emit('saveService', editDone)">
<b-icon icon="check" />
Save those modifications
</b-button>
@ -82,7 +82,7 @@
:services="services"
:specs="spec"
:type="spec.type"
@saveService="$emit('saveService')"
@saveService="$emit('saveService', $event)"
/>
</div>
</div>
@ -151,6 +151,10 @@ export default {
},
methods: {
editDone () {
this.serviceEdit = false
},
pullServiceSpecs () {
ServiceSpecsApi.getServiceSpecs(this.type)
.then(

View File

@ -40,14 +40,14 @@
</b-button>
</template>
<template v-slot:cell()="row">
<h-resource-value v-if="service_specs.fields" v-model="row.item[row.field.key]" :edit="edit_row.indexOf(row.index) >= 0" :index="row.index" :services="services" :specs="service_specs.fields[row.field.index]" :type="service_specs.fields[row.field.index].type" no-decorate @saveService="$emit('saveService')" />
<h-resource-value v-else v-model="row.item" :edit="edit_row.indexOf(row.index) >= 0" :index="row.index" :services="services" :specs="specs" :type="row_type" no-decorate @saveService="$emit('saveService')" />
<h-resource-value v-if="service_specs.fields" v-model="row.item[row.field.key]" :edit="edit_row.indexOf(row.index) >= 0" :index="row.index" :services="services" :specs="service_specs.fields[row.field.index]" :type="service_specs.fields[row.field.index].type" no-decorate @saveService="$emit('saveService', $event)" />
<h-resource-value v-else v-model="row.item" :edit="edit_row.indexOf(row.index) >= 0" :index="row.index" :services="services" :specs="specs" :type="row_type" no-decorate @saveService="$emit('saveService', $event)" />
</template>
<template v-slot:cell(_actions)="row">
<b-button v-if="edit_row.indexOf(row.index) < 0" size="sm" title="Edit" variant="outline-primary" class="mx-1" @click="editService(row)">
<b-icon icon="pencil" />
</b-button>
<b-button v-else type="button" title="Save the modifications" size="sm" variant="primary" class="mx-1" @click="$emit('saveService')">
<b-button v-else type="button" title="Save the modifications" size="sm" variant="primary" class="mx-1" @click="$emit('saveService', function () { editDone(row) })">
<b-icon icon="check" />
</b-button>
<b-button type="button" title="Delete" size="sm" variant="outline-danger" class="mx-1" @click="deleteService(row.item)">
@ -143,6 +143,12 @@ export default {
},
methods: {
editDone (row) {
if (this.edit_row.indexOf(row.index) >= 0) {
this.edit_row.splice(this.edit_row.indexOf(row.index), 1)
}
},
pullServiceSpecs () {
if (this.row_type === 'string') {
this.service_specs = {}
@ -158,7 +164,7 @@ export default {
editService (row) {
if (this.edit_row.indexOf(row.index) >= 0) {
this.edit_row = this.edit_row.splice(this.edit_row.indexOf(row.index), 1)
this.edit_row.splice(this.edit_row.indexOf(row.index), 1)
} else {
this.edit_row.push(row.index)
}

View File

@ -69,7 +69,7 @@
</b-button>
</h2>
<div v-show="showResources">
<h-domain-service v-for="(svc, idx) in services" :key="idx" :origin="origin" :service="svc" :zone-meta="zoneMeta" />
<h-domain-service v-for="(svc, idx) in services" :key="idx" :origin="origin" :service="svc" :zone-meta="zoneMeta" @updateMyServices="$emit('updateMyServices', $event)" />
</div>
</div>
</div>

View File

@ -33,7 +33,7 @@
<template>
<div v-if="!isLoading" class="pt-3">
<h-subdomain-item v-for="(dn, index) in sortedDomains" :key="index" :dn="dn" :origin="domain.domain" :services="myServices.services[dn]===undefined?[]:myServices.services[dn]" :aliases="myServices.aliases[dn]===undefined?[]:myServices.aliases[dn]" :zone-meta="zoneMeta" />
<h-subdomain-item v-for="(dn, index) in sortedDomains" :key="index" :dn="dn" :origin="domain.domain" :services="myServices.services[dn]===undefined?[]:myServices.services[dn]" :aliases="myServices.aliases[dn]===undefined?[]:myServices.aliases[dn]" :zone-meta="zoneMeta" @updateMyServices="updateMyServices($event)" />
</div>
</template>
@ -142,6 +142,10 @@ export default {
this.$router.push('/domains/' + encodeURIComponent(this.domain.domain))
}
)
},
updateMyServices (myS) {
this.myServices = myS
}
}
}

View File

@ -34,5 +34,9 @@ import Api from '@/services/Api'
export default {
getZone (domain, id) {
return Api().get('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id))
},
updateZoneService (domain, id, service) {
return Api().patch('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id), service)
}
}