Full update/deletion on abstract page

This commit is contained in:
nemunaire 2020-06-14 22:58:28 +02:00
parent 717123ad7f
commit 4a19149b51
9 changed files with 261 additions and 81 deletions

View File

@ -52,17 +52,17 @@ func init() {
router.PUT("/api/users/:userid/domains/:domain/zones", api.ApiHandler(userHandler(domainHandler(updateUserDomainZones)))) router.PUT("/api/users/:userid/domains/:domain/zones", api.ApiHandler(userHandler(domainHandler(updateUserDomainZones))))
router.POST("/api/users/:userid/domains/:domain/zones", api.ApiHandler(userHandler(domainHandler(newUserDomainZone)))) router.POST("/api/users/:userid/domains/:domain/zones", api.ApiHandler(userHandler(domainHandler(newUserDomainZone))))
router.GET("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(zoneHandler(getZone))) router.GET("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(userHandler(zoneHandler(getZone))))
router.PUT("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(zoneHandler(updateZone))) router.PUT("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(userHandler(zoneHandler(updateZone))))
router.DELETE("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(deleteZone)) router.DELETE("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(deleteZone))
router.GET("/api/zones/:zoneid", api.ApiHandler(zoneHandler(getZone))) router.GET("/api/zones/:zoneid", api.ApiHandler(userHandler(zoneHandler(getZone))))
router.PUT("/api/zones/:zoneid", api.ApiHandler(zoneHandler(updateZone))) router.PUT("/api/zones/:zoneid", api.ApiHandler(userHandler(zoneHandler(updateZone))))
router.DELETE("/api/zones/:zoneid", api.ApiHandler(deleteZone)) router.DELETE("/api/zones/:zoneid", api.ApiHandler(deleteZone))
router.GET("/api/users/:userid/domains/:domain/zones/:zoneid/:serviceid", api.ApiHandler(zoneHandler(getZoneService))) router.GET("/api/users/:userid/domains/:domain/zones/:zoneid/*serviceid", api.ApiHandler(userHandler(zoneHandler(getZoneService))))
router.PUT("/api/users/:userid/domains/:domain/zones/:zoneid/:serviceid", api.ApiHandler(zoneHandler(updateZoneService))) router.PUT("/api/users/:userid/domains/:domain/zones/:zoneid/*serviceid", api.ApiHandler(userHandler(zoneHandler(updateZoneService))))
router.PATCH("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(zoneHandler(patchZoneService))) router.PATCH("/api/users/:userid/domains/:domain/zones/:zoneid", api.ApiHandler(userHandler(zoneHandler(patchZoneService))))
} }
func getUserDomainZones(_ *config.Options, domain *happydns.Domain, _ httprouter.Params, _ io.Reader) api.Response { func getUserDomainZones(_ *config.Options, domain *happydns.Domain, _ httprouter.Params, _ io.Reader) api.Response {
@ -89,27 +89,41 @@ func newUserDomainZone(_ *config.Options, domain *happydns.Domain, _ httprouter.
return api.NewAPIResponse(uz, storage.MainStore.CreateZone(uz)) return api.NewAPIResponse(uz, storage.MainStore.CreateZone(uz))
} }
func zoneHandler(f func(*config.Options, *happydns.Zone, httprouter.Params, io.Reader) api.Response) func(*config.Options, httprouter.Params, io.Reader) api.Response { func zoneHandler(f func(*config.Options, *happydns.Domain, *happydns.Zone, httprouter.Params, io.Reader) api.Response) func(*config.Options, *happydns.User, httprouter.Params, io.Reader) api.Response {
return func(opts *config.Options, ps httprouter.Params, body io.Reader) api.Response { return func(opts *config.Options, user *happydns.User, ps httprouter.Params, body io.Reader) api.Response {
zoneid, err := strconv.ParseInt(ps.ByName("zoneid"), 10, 64) return domainHandler(func(opts *config.Options, domain *happydns.Domain, ps httprouter.Params, body io.Reader) api.Response {
if err != nil { zoneid, err := strconv.ParseInt(ps.ByName("zoneid"), 10, 64)
return api.NewAPIErrorResponse(http.StatusNotFound, err) if err != nil {
} else { return api.NewAPIErrorResponse(http.StatusNotFound, err)
}
// Check that the zoneid exists in the domain history
found := false
for _, v := range domain.ZoneHistory {
if v.Id == zoneid {
found = true
break
}
}
if !found {
return api.NewAPIErrorResponse(http.StatusNotFound, fmt.Errorf("Zone not found"))
}
zone, err := storage.MainStore.GetZone(zoneid) zone, err := storage.MainStore.GetZone(zoneid)
if err != nil { if err != nil {
return api.NewAPIErrorResponse(http.StatusNotFound, err) return api.NewAPIErrorResponse(http.StatusNotFound, err)
} else { } else {
return f(opts, zone, ps, body) return f(opts, domain, zone, ps, body)
} }
} })(opts, user, ps, body)
} }
} }
func getZone(_ *config.Options, zone *happydns.Zone, _ httprouter.Params, _ io.Reader) api.Response { func getZone(_ *config.Options, domain *happydns.Domain, zone *happydns.Zone, _ httprouter.Params, _ io.Reader) api.Response {
return api.NewAPIResponse(zone, nil) return api.NewAPIResponse(zone, nil)
} }
func updateZone(_ *config.Options, zone *happydns.Zone, _ httprouter.Params, body io.Reader) api.Response { func updateZone(_ *config.Options, domain *happydns.Domain, zone *happydns.Zone, _ httprouter.Params, body io.Reader) api.Response {
uz := &happydns.Zone{} uz := &happydns.Zone{}
err := json.NewDecoder(body).Decode(&uz) err := json.NewDecoder(body).Decode(&uz)
if err != nil { if err != nil {
@ -120,17 +134,19 @@ func updateZone(_ *config.Options, zone *happydns.Zone, _ httprouter.Params, bod
return api.NewAPIResponse(uz, storage.MainStore.UpdateZone(uz)) return api.NewAPIResponse(uz, storage.MainStore.UpdateZone(uz))
} }
func getZoneService(_ *config.Options, zone *happydns.Zone, ps httprouter.Params, body io.Reader) api.Response { func getZoneService(_ *config.Options, domain *happydns.Domain, zone *happydns.Zone, ps httprouter.Params, body io.Reader) api.Response {
serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid")) serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid")[1:])
if err != nil { if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err) return api.NewAPIErrorResponse(http.StatusBadRequest, err)
} }
return api.NewAPIResponse(zone.FindService(serviceid), nil) _, svc := zone.FindService(serviceid)
return api.NewAPIResponse(svc, nil)
} }
func updateZoneService(_ *config.Options, zone *happydns.Zone, ps httprouter.Params, body io.Reader) api.Response { func updateZoneService(_ *config.Options, domain *happydns.Domain, zone *happydns.Zone, ps httprouter.Params, body io.Reader) api.Response {
serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid")) serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid")[1:])
if err != nil { if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err) return api.NewAPIErrorResponse(http.StatusBadRequest, err)
} }
@ -141,7 +157,7 @@ func updateZoneService(_ *config.Options, zone *happydns.Zone, ps httprouter.Par
return api.NewAPIErrorResponse(http.StatusBadRequest, fmt.Errorf("Something is wrong in received data: %w", err)) return api.NewAPIErrorResponse(http.StatusBadRequest, fmt.Errorf("Something is wrong in received data: %w", err))
} }
err = zone.EraseService(usc.Domain, serviceid, usc) err = zone.EraseService(usc.Domain, domain.DomainName, serviceid, usc)
if err != nil { if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err) return api.NewAPIErrorResponse(http.StatusBadRequest, err)
} }
@ -149,14 +165,14 @@ func updateZoneService(_ *config.Options, zone *happydns.Zone, ps httprouter.Par
return api.NewAPIResponse(zone.Services, storage.MainStore.UpdateZone(zone)) return api.NewAPIResponse(zone.Services, storage.MainStore.UpdateZone(zone))
} }
func patchZoneService(_ *config.Options, zone *happydns.Zone, _ httprouter.Params, body io.Reader) api.Response { func patchZoneService(_ *config.Options, domain *happydns.Domain, zone *happydns.Zone, _ httprouter.Params, body io.Reader) api.Response {
usc := &happydns.ServiceCombined{} usc := &happydns.ServiceCombined{}
err := json.NewDecoder(body).Decode(&usc) err := json.NewDecoder(body).Decode(&usc)
if err != nil { if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, fmt.Errorf("Something is wrong in received data: %w", err)) return api.NewAPIErrorResponse(http.StatusBadRequest, fmt.Errorf("Something is wrong in received data: %w", err))
} }
err = zone.EraseService(usc.Domain, usc.Id, usc) err = zone.EraseService(usc.Domain, domain.DomainName, usc.Id, usc)
if err != nil { if err != nil {
return api.NewAPIErrorResponse(http.StatusBadRequest, err) return api.NewAPIErrorResponse(http.StatusBadRequest, err)
} }

View File

@ -32,6 +32,7 @@
package api package api
import ( import (
"encoding/base64"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -50,11 +51,14 @@ import (
func init() { func init() {
router.GET("/api/domains/:domain/zone/:zoneid", apiAuthHandler(zoneHandler(getZone))) router.GET("/api/domains/:domain/zone/:zoneid", apiAuthHandler(zoneHandler(getZone)))
router.PATCH("/api/domains/:domain/zone/:zoneid", apiAuthHandler(zoneHandler(updateZoneService))) router.PATCH("/api/domains/:domain/zone/:zoneid", apiAuthHandler(zoneHandler(updateZoneService)))
router.GET("/api/domains/:domain/zone/:zoneid/:subdomain", apiAuthHandler(zoneHandler(getZoneSubdomain)))
router.GET("/api/domains/:domain/zone/:zoneid/:subdomain/*serviceid", apiAuthHandler(zoneHandler(getZoneService)))
router.DELETE("/api/domains/:domain/zone/:zoneid/:subdomain/*serviceid", apiAuthHandler(zoneHandler(deleteZoneService)))
router.POST("/api/domains/:domain/import_zone", apiAuthHandler(domainHandler(importZone))) router.POST("/api/domains/:domain/import_zone", apiAuthHandler(domainHandler(importZone)))
} }
func zoneHandler(f func(*config.Options, *happydns.Domain, *happydns.Zone, io.Reader) Response) func(*config.Options, *happydns.User, httprouter.Params, io.Reader) Response { func zoneHandler(f func(*config.Options, *happydns.Domain, *happydns.Zone, httprouter.Params, io.Reader) Response) func(*config.Options, *happydns.User, httprouter.Params, io.Reader) Response {
return func(opts *config.Options, u *happydns.User, ps httprouter.Params, body io.Reader) Response { return func(opts *config.Options, u *happydns.User, ps httprouter.Params, body io.Reader) Response {
zoneid, err := strconv.ParseInt(ps.ByName("zoneid"), 10, 64) zoneid, err := strconv.ParseInt(ps.ByName("zoneid"), 10, 64)
if err != nil { if err != nil {
@ -85,18 +89,40 @@ func zoneHandler(f func(*config.Options, *happydns.Domain, *happydns.Zone, io.Re
err: errors.New("Zone not found"), err: errors.New("Zone not found"),
} }
} else { } else {
return f(opts, domain, zone, body) return f(opts, domain, zone, ps, body)
} }
})(opts, u, ps, body) })(opts, u, ps, body)
} }
} }
func getZone(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, body io.Reader) Response { func getZone(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, _ httprouter.Params, body io.Reader) Response {
return APIResponse{ return APIResponse{
response: zone, response: zone,
} }
} }
func getZoneSubdomain(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, ps httprouter.Params, body io.Reader) Response {
return APIResponse{
response: map[string]interface{}{
"aliases": zone.Aliases[ps.ByName("subdomain")],
"services": zone.Services[ps.ByName("subdomain")],
},
}
}
func getZoneService(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, ps httprouter.Params, body io.Reader) Response {
serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid")[1:])
if err != nil {
return APIErrorResponse{
err: err,
}
}
return APIResponse{
response: zone.FindSubdomainService(ps.ByName("subdomain"), serviceid),
}
}
func importZone(opts *config.Options, domain *happydns.Domain, body io.Reader) Response { func importZone(opts *config.Options, domain *happydns.Domain, body io.Reader) Response {
source, err := storage.MainStore.GetSource(&happydns.User{Id: domain.IdUser}, domain.IdSource) source, err := storage.MainStore.GetSource(&happydns.User{Id: domain.IdUser}, domain.IdSource)
if err != nil { if err != nil {
@ -150,7 +176,7 @@ func importZone(opts *config.Options, domain *happydns.Domain, body io.Reader) R
} }
} }
func updateZoneService(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, body io.Reader) Response { func updateZoneService(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, _ httprouter.Params, body io.Reader) Response {
usc := &happydns.ServiceCombined{} usc := &happydns.ServiceCombined{}
err := json.NewDecoder(body).Decode(&usc) err := json.NewDecoder(body).Decode(&usc)
if err != nil { if err != nil {
@ -159,7 +185,34 @@ func updateZoneService(opts *config.Options, domain *happydns.Domain, zone *happ
} }
} }
err = zone.EraseService(usc.Domain, usc.Id, usc) err = zone.EraseService(usc.Domain, domain.DomainName, 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,
}
}
func deleteZoneService(opts *config.Options, domain *happydns.Domain, zone *happydns.Zone, ps httprouter.Params, body io.Reader) Response {
serviceid, err := base64.StdEncoding.DecodeString(ps.ByName("serviceid")[1:])
if err != nil {
return APIErrorResponse{
err: err,
}
}
err = zone.EraseService(ps.ByName("subdomain"), domain.DomainName, serviceid, nil)
if err != nil { if err != nil {
return APIErrorResponse{ return APIErrorResponse{
err: err, err: err,

View File

@ -44,7 +44,7 @@
</b-badge> </b-badge>
</b-list-group-item> </b-list-group-item>
<b-list-group-item v-if="showDetails"> <b-list-group-item v-if="showDetails">
<h-resource-value v-model="service.Service" edit-toolbar :services="services" :type="service._svctype" @saveService="saveService(service, $event)" /> <h-resource-value v-model="service.Service" edit-toolbar :services="services" :type="service._svctype" @deleteService="deleteService(service, $event)" @saveService="saveService(service, $event)" />
</b-list-group-item> </b-list-group-item>
</b-list-group> </b-list-group>
</template> </template>
@ -96,29 +96,52 @@ export default {
}, },
methods: { methods: {
saveService (service, cbSuccess, cbFail) { deleteService (service) {
ZoneApi.updateZoneService(this.origin, this.zoneMeta.id, service) this.showDetails = false
ZoneApi.deleteZoneService(this.origin, this.zoneMeta.id, service)
.then( .then(
(response) => { (response) => {
this.$emit('updateMyServices', response.data) this.$emit('updateMyServices', response.data)
if (cbSuccess != null) {
cbSuccess()
}
}, },
(error) => { (error) => {
this.$bvToast.toast( this.$bvToast.toast(
error.response.data.errmsg, { error.response.data.errmsg, {
title: 'An error occurs when updating the service!', title: 'An error occurs when deleting the service!',
autoHideDelay: 5000, autoHideDelay: 5000,
variant: 'danger', variant: 'danger',
toaster: 'b-toaster-content-right' toaster: 'b-toaster-content-right'
} }
) )
if (cbFail != null) { })
cbFail(error) },
saveService (service, cbSuccess, cbFail) {
if (service.Service === undefined) {
this.deleteService(service)
} else {
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 () { toogleShowDetails () {

View File

@ -32,7 +32,7 @@
--> -->
<template> <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', $event)" /> <component :is="itemComponent" :value="value" :edit="edit" :edit-toolbar="editToolbar" :index="index" :services="services" :specs="specs" :type="type" @input="$emit('input', $event)" @deleteService="$emit('deleteService', $event)" @saveService="$emit('saveService', $event)" />
</template> </template>
<script> <script>
@ -100,7 +100,7 @@ export default {
methods: { methods: {
findComponent () { findComponent () {
if (Array.isArray(this.value)) { if (Array.isArray(this.value) || (this.type.substr(0, 2) === '[]' && this.type !== '[]byte' && this.type !== '[]uint8')) {
this.itemComponent = HResourceValueTable this.itemComponent = HResourceValueTable
} else if (this.type.substr(0, 3) === 'map') { } else if (this.type.substr(0, 3) === 'map') {
this.itemComponent = HResourceValueMap this.itemComponent = HResourceValueMap

View File

@ -39,11 +39,15 @@
<h3> <h3>
<span v-if="!editKeys[key]">{{ key }}</span> <span v-if="!editKeys[key]">{{ key }}</span>
<b-input-group v-else> <b-input-group v-else>
<b-form-input v-model="newKeys[key]" /> <b-form-input
v-model="newKeys[key]"
:placeholder="specs.id + ' key name'"
/>
<template v-slot:append> <template v-slot:append>
<b-button v-if="editKeys[key]" type="button" size="sm" variant="primary" @click="rename(key)"> <b-button v-if="editKeys[key]" type="button" size="sm" variant="primary" @click="rename(key)">
<b-icon icon="check" /> <b-icon icon="check" />
Rename <span v-if="key">Rename</span>
<span v-else>Create new {{ specs.id }} key</span>
</b-button> </b-button>
</template> </template>
</b-input-group> </b-input-group>
@ -52,14 +56,21 @@
</b-button> </b-button>
</h3> </h3>
</b-col> </b-col>
<b-col sm="auto"> <b-col v-if="!key || !editKeys[key]" sm="auto">
<b-button type="button" size="sm" variant="outline-danger" class="mx-1 float-right"> <b-button type="button" size="sm" variant="outline-danger" class="mx-1" @click="deleteKey(key)">
<b-icon icon="trash" /> <b-icon icon="trash" />
Delete Delete
</b-button> </b-button>
</b-col> </b-col>
<b-col v-else sm="auto">
<b-button type="button" variant="outline-danger" class="mx-1" @click="cancelKeyEdit(key)">
<b-icon icon="x-circle" />
Cancel edit
</b-button>
</b-col>
</b-row> </b-row>
<h-resource-value <h-resource-value
v-if="key"
v-model="value[key]" v-model="value[key]"
:services="services" :services="services"
:specs="service_specs" :specs="service_specs"
@ -68,7 +79,7 @@
/> />
<hr> <hr>
</div> </div>
<b-button> <b-button @click="createKey()">
Add new {{ specs.id }} Add new {{ specs.id }}
</b-button> </b-button>
</div> </div>
@ -132,7 +143,7 @@ export default {
watch: { watch: {
type: function () { type: function () {
this.key_type = this.type.substr(this.type.indexOf('[') + 1, this.type.indexOf(']') - this.type.indexOf('[')) this.key_type = this.type.substr(this.type.indexOf('[') + 1, this.type.indexOf(']') - this.type.indexOf('[') - 1)
this.main_type = this.type.substr(this.type.indexOf(']') + 1) this.main_type = this.type.substr(this.type.indexOf(']') + 1)
this.pullServiceSpecs() this.pullServiceSpecs()
} }
@ -140,7 +151,7 @@ export default {
created () { created () {
if (this.type !== undefined) { if (this.type !== undefined) {
this.key_type = this.type.substr(this.type.indexOf('[') + 1, this.type.indexOf(']') - this.type.indexOf('[')) this.key_type = this.type.substr(this.type.indexOf('[') + 1, this.type.indexOf(']') - this.type.indexOf('[') - 1)
this.main_type = this.type.substr(this.type.indexOf(']') + 1) this.main_type = this.type.substr(this.type.indexOf(']') + 1)
this.pullServiceSpecs() this.pullServiceSpecs()
} }
@ -156,17 +167,42 @@ export default {
) )
}, },
cancelKeyEdit (key) {
Vue.delete(this.editKeys, key)
},
createKey () {
var newObj = {}
if (this.main_type.substr(0, 2) === '[]') {
newObj = []
}
Vue.set(this.value, '', newObj)
this.toogleKeyEdit('', true)
},
deleteKey (key) {
Vue.delete(this.value, key)
if (Object.keys(this.value).length === 0) {
this.$emit('input', undefined)
this.$emit('saveService')
}
},
rename (key) { rename (key) {
if (key !== this.newKeys[key]) { if (key !== this.newKeys[key]) {
Vue.set(this.value, this.newKeys[key], this.value[key]) Vue.set(this.value, this.newKeys[key], this.value[key])
Vue.delete(this.value, key) Vue.delete(this.value, key)
} }
Vue.delete(this.editKeys, key) Vue.delete(this.editKeys, key)
this.$emit('saveService')
}, },
toogleKeyEdit (key) { toogleKeyEdit (key, forceValue) {
Vue.set(this.newKeys, key, key) Vue.set(this.newKeys, key, key)
Vue.set(this.editKeys, key, !this.editKeys[key]) if (forceValue == null) {
forceValue = !this.editKeys[key]
}
Vue.set(this.editKeys, key, forceValue)
} }
} }
} }

View File

@ -52,20 +52,25 @@
:services="services" :services="services"
:specs="spec" :specs="spec"
:type="spec.type" :type="spec.type"
@saveService="$emit('saveService', $event)" @saveService="serviceEdit=false;$emit('saveService', $event)"
/> />
<b-button v-else @click="createObject(spec)"> <b-button v-else :disable="value['']" @click="createObject(spec)">
Create {{ spec.id }} Create {{ spec.id }}
</b-button> </b-button>
</b-tab> </b-tab>
</b-tabs> </b-tabs>
<div v-else-if="!value">
<b-button @click="createObject(spec)">
Create {{ spec.id }}
</b-button>
</div>
<div v-else> <div v-else>
<div v-if="editToolbar" class="text-right mb-2"> <div v-if="editToolbar" class="text-right mb-2">
<b-button v-if="!editChildren" type="button" size="sm" variant="outline-primary" class="mx-1" @click="toogleServiceEdit()"> <b-button v-if="!editChildren" type="button" size="sm" variant="outline-primary" class="mx-1" @click="toogleServiceEdit()">
<b-icon icon="pencil" /> <b-icon icon="pencil" />
Edit Edit
</b-button> </b-button>
<b-button v-else type="button" size="sm" variant="primary" class="mx-1" @click="$emit('saveService', editDone)"> <b-button v-else type="button" size="sm" variant="primary" class="mx-1" @click="saveObject()">
<b-icon icon="check" /> <b-icon icon="check" />
Save those modifications Save those modifications
</b-button> </b-button>
@ -77,11 +82,12 @@
<h-resource-value <h-resource-value
v-for="(spec, index) in service_specs.fields" v-for="(spec, index) in service_specs.fields"
:key="index" :key="index"
v-model="value[spec.id]" :value="val[spec.id]"
:edit="editChildren" :edit="editChildren"
:services="services" :services="services"
:specs="spec" :specs="spec"
:type="spec.type" :type="spec.type"
@input="val[spec.id] = $event;$emit('input', val)"
@saveService="$emit('saveService', $event)" @saveService="$emit('saveService', $event)"
/> />
</div> </div>
@ -122,14 +128,15 @@ export default {
}, },
value: { value: {
type: Object, type: Object,
required: true default: null
} }
}, },
data () { data () {
return { return {
serviceEdit: false, serviceEdit: false,
service_specs: null service_specs: null,
val: {}
} }
}, },
@ -142,6 +149,9 @@ export default {
watch: { watch: {
type: function () { type: function () {
this.pullServiceSpecs() this.pullServiceSpecs()
},
value: function () {
this.updateValues()
} }
}, },
@ -149,6 +159,9 @@ export default {
if (this.type !== undefined) { if (this.type !== undefined) {
this.pullServiceSpecs() this.pullServiceSpecs()
} }
if (this.value !== undefined) {
this.updateValues()
}
}, },
methods: { methods: {
@ -166,10 +179,6 @@ export default {
this.$emit('saveService') this.$emit('saveService')
}, },
editDone () {
this.serviceEdit = false
},
pullServiceSpecs () { pullServiceSpecs () {
ServiceSpecsApi.getServiceSpecs(this.type) ServiceSpecsApi.getServiceSpecs(this.type)
.then( .then(
@ -179,8 +188,23 @@ export default {
) )
}, },
saveObject () {
var vm = this
this.$emit('saveService', function () {
vm.serviceEdit = false
})
},
toogleServiceEdit () { toogleServiceEdit () {
this.serviceEdit = !this.serviceEdit this.serviceEdit = !this.serviceEdit
},
updateValues () {
if (this.value != null) {
this.val = Object.assign({}, this.value)
} else {
this.val = {}
}
} }
} }
} }

View File

@ -86,7 +86,7 @@ export default {
}, },
value: { value: {
type: Array, type: Array,
required: true default: null
} }
}, },
@ -165,7 +165,9 @@ export default {
}, },
addRow () { addRow () {
this.tmp_values.push({ _key: this.value.length, _edit: true }) if ((this.value == null && this.tmp_values.length <= 1) || (this.value != null && this.tmp_values.length <= this.value.length)) {
this.tmp_values.push({ _key: this.tmp_values.length, _edit: true })
}
}, },
cancelEdit (row) { cancelEdit (row) {
@ -191,11 +193,17 @@ export default {
val[sspec.id] = row.item[sspec.id] val[sspec.id] = row.item[sspec.id]
}, this) }, this)
if (this.value[row.item._key] !== undefined) { if (this.value !== null && this.value[row.item._key] !== undefined) {
this.value[row.item._key] = val this.value[row.item._key] = val
this.$emit('input', this.value)
} else if (this.value === null) {
this.$emit('input', [val])
} else { } else {
this.value.push(val) this.value.push(val)
this.$emit('input', this.value)
} }
} else if (this.value === null) {
this.$emit('input', [row.item.value])
} else { } else {
this.value[row.item._key] = row.item.value this.value[row.item._key] = row.item.value
} }
@ -205,13 +213,15 @@ export default {
updateValues () { updateValues () {
this.tmp_values = [] this.tmp_values = []
this.value.forEach(function (v, k) { if (this.value !== null) {
if (typeof v === 'object') { this.value.forEach(function (v, k) {
this.tmp_values.push(Object.assign({ _key: k, _edit: false }, v)) if (typeof v === 'object') {
} else { this.tmp_values.push(Object.assign({ _key: k, _edit: false }, v))
this.tmp_values.push({ _key: k, _edit: false, value: v }) } else {
} this.tmp_values.push({ _key: k, _edit: false, value: v })
}, this) }
}, this)
}
} }
} }
} }

View File

@ -36,6 +36,10 @@ export default {
return Api().get('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id)) return Api().get('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id))
}, },
deleteZoneService (domain, id, service) {
return Api().delete('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id) + '/' + encodeURIComponent(service._domain) + '/' + encodeURIComponent(service._id))
},
updateZoneService (domain, id, service) { updateZoneService (domain, id, service) {
return Api().patch('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id), service) return Api().patch('/api/domains/' + encodeURIComponent(domain) + '/zone/' + encodeURIComponent(id), service)
} }

View File

@ -53,23 +53,37 @@ type Zone struct {
Services map[string][]*ServiceCombined `json:"services"` Services map[string][]*ServiceCombined `json:"services"`
} }
func (z *Zone) FindService(id []byte) *ServiceCombined { func (z *Zone) FindService(id []byte) (string, *ServiceCombined) {
for _, services := range z.Services { for subdomain := range z.Services {
for _, svc := range services { if svc := z.FindSubdomainService(subdomain, id); svc != nil {
if bytes.Equal(svc.Id, id) { return subdomain, svc
return svc }
} }
return "", nil
}
func (z *Zone) FindSubdomainService(domain string, id []byte) *ServiceCombined {
for _, svc := range z.Services[domain] {
if bytes.Equal(svc.Id, id) {
return svc
} }
} }
return nil return nil
} }
func (z *Zone) EraseService(domain string, id []byte, s *ServiceCombined) error { func (z *Zone) EraseService(subdomain string, origin string, id []byte, s *ServiceCombined) error {
if services, ok := z.Services[domain]; ok { if services, ok := z.Services[subdomain]; ok {
for k, svc := range services { for k, svc := range services {
if bytes.Equal(svc.Id, id) { if bytes.Equal(svc.Id, id) {
z.Services[domain][k] = s if s == nil {
z.Services[subdomain] = append(z.Services[subdomain][:k], z.Services[subdomain][k+1:]...)
} else {
s.Comment = s.GenComment(origin)
s.NbResources = s.GetNbResources()
z.Services[subdomain][k] = s
}
return nil return nil
} }
} }