소스 검색

feat(webapp): export zonefile

Peter Thomassen 2 년 전
부모
커밋
58597eab01
3개의 변경된 파일40개의 추가작업 그리고 8개의 파일을 삭제
  1. 6 0
      www/webapp/src/utils.js
  2. 1 1
      www/webapp/src/views/CrudList.vue
  3. 33 7
      www/webapp/src/views/DomainList.vue

+ 6 - 0
www/webapp/src/utils.js

@@ -59,6 +59,12 @@ async function _digestError(error, app) {
         return ['Too much data. Try to reduce the length of your inputs.'];
       } else if ('data' in error.response) {
         let data = error.response.data;
+        if (data instanceof Blob) {
+          data = await data.text();
+          if (error.response.headers['content-type'] == 'application/json') {
+            data = JSON.parse(data);
+          }
+        }
         if (typeof data === 'object') {
           if ('detail' in data) {
             return [data.detail];

+ 1 - 1
www/webapp/src/views/CrudList.vue

@@ -400,7 +400,6 @@ export default {
       destroyWarning: () => (false),
     },
     columns: {},
-    actions: {},
     // resource
     paths: {
       list: 'needs/to/be/overwritten/',
@@ -426,6 +425,7 @@ export default {
     handleRowClick: () => {},
   }},
   computed: {
+    actions: () => {},
     createInhibited: () => false,
     defaultActions() {
       return {

+ 33 - 7
www/webapp/src/views/DomainList.vue

@@ -66,23 +66,34 @@ export default {
             advanced: true,
           }
         },
-        actions: {
-          'info': {
-            go: d => this.showDomainInfo(d),
-            icon: 'mdi-information',
-            tooltip: 'Setup instructions',
-          },
-        },
         paths: {
           list: 'domains/',
           create: 'domains/',
           delete: 'domains/:{name}/',
+          export: 'domains/:{name}/zonefile/',
         },
         itemDefaults: () => ({ name: '' }),
         postcreate: d => {
           this.close();
           this.showDomainInfo(d, true);
         },
+        async exportDomain(domain) {
+          const url = this.resourcePath(this.paths.export, domain, ':');
+          await withWorking(this.error, () => HTTP
+              .get(url, {responseType: 'blob'})
+              .then(r => new Blob([r.data], {type: r.headers['content-type']}))
+              .then(zoneblob => {
+                const elem = window.document.createElement('a');
+                elem.href = window.URL.createObjectURL(zoneblob);
+                elem.download = `${domain.name}.zone`;
+                elem.style.display = 'none';
+                document.body.appendChild(elem);
+                elem.click();
+                window.URL.revokeObjectURL(elem.href);
+                document.body.removeChild(elem);
+            })
+          );
+        },
         async showDomainInfo(d, isNew = false) {
           const url = this.resourcePath(this.paths.delete, d, ':');
           if (d.keys === undefined) {
@@ -105,6 +116,21 @@ export default {
     }
   },
   computed: {
+    actions() {
+      return {
+        'info': {
+          go: d => this.showDomainInfo(d),
+          icon: 'mdi-information',
+          tooltip: 'Setup instructions',
+        },
+        'export': {
+          go: d => this.exportDomain(d),
+          icon: 'mdi-download',
+          if: this.showAdvanced,
+          tooltip: 'Export (zonefile format)',
+        },
+      };
+    },
     availableCount: function () {
       return this.limit_domains - this.rows.length;
     },