From f7ded6afc7e9eacd5e2b737416b8cc08ff3d27d0 Mon Sep 17 00:00:00 2001 From: zhangjingwei Date: Mon, 30 Oct 2023 10:41:17 +0800 Subject: [PATCH] feat: support dns zone and recordsets in administrator 1. support dns zone page in the administrator 2. support dns zone's recordsets in the administrator 3. update dns zone fetch to pagination request 4. update recordsets fetch to pagination request 5. support sort zone by api 6. support sort recordsets by api 7. update search filters for the dns zone list page 8. update search filters for the recordset list Change-Id: If426060bcb0c3ecd3fa485a9be09953ae74734dc --- src/layouts/admin-menu.jsx | 36 ++++++++-- src/layouts/menu.jsx | 8 +-- src/locales/en.json | 1 + src/locales/ko-kr.json | 1 + src/locales/zh-hans.json | 1 + .../DNS/Zones/Detail/RecordSets/index.jsx | 51 ++++++++++++-- .../network/containers/DNS/Zones/index.jsx | 42 +++++++++-- src/pages/network/routes/index.js | 29 +++++++- src/resources/dns/record.jsx | 1 + src/stores/base.js | 8 ++- src/stores/designate/base.js | 70 +++++++++++++++++++ src/stores/designate/record-set.js | 11 ++- src/stores/designate/zones.js | 2 +- src/stores/octavia/loadbalancer.js | 4 +- 14 files changed, 231 insertions(+), 34 deletions(-) create mode 100644 src/stores/designate/base.js diff --git a/src/layouts/admin-menu.jsx b/src/layouts/admin-menu.jsx index 8ffd0819..f8fd164f 100644 --- a/src/layouts/admin-menu.jsx +++ b/src/layouts/admin-menu.jsx @@ -447,6 +447,30 @@ const renderMenu = (t) => { }, ], }, + { + path: '/network/dns-admin/zones', + name: t('DNS Zones'), + key: 'dnsZonesAdmin', + endpoints: 'designate', + level: 1, + children: [ + { + path: /^\/network\/dns-admin\/zones\/detail\/.[^/]+$/, + name: t('Zones Detail'), + key: 'dnsZonesDetailAdmin', + level: 2, + routePath: '/network/dns-admin/zones/detail/:id', + }, + { + path: /^\/network\/dns-admin\/zones\/detail\/.[^/]+\/recordsets\/.[^/]+$/, + name: t('Recordsets Detail'), + key: 'dnsRecordSetDetailAdmin', + level: 2, + routePath: + '/network/dns-admin/zones/detail/:zoneId/recordsets/:id', + }, + ], + }, ], }, { @@ -977,7 +1001,7 @@ const renderMenu = (t) => { level: 2, routePath: '/ha/segments-admin/detail/:id', }, - ] + ], }, { path: '/ha/hosts-admin', @@ -992,7 +1016,7 @@ const renderMenu = (t) => { level: 2, routePath: '/ha/hosts-admin/detail/:id', }, - ] + ], }, { path: '/ha/notifications-admin', @@ -1007,10 +1031,10 @@ const renderMenu = (t) => { level: 2, routePath: '/ha/notifications-admin/detail/:id', }, - ] - } - ] - } + ], + }, + ], + }, ]; return menu; }; diff --git a/src/layouts/menu.jsx b/src/layouts/menu.jsx index 93cc0439..2292d8f9 100644 --- a/src/layouts/menu.jsx +++ b/src/layouts/menu.jsx @@ -467,9 +467,9 @@ const renderMenu = (t) => { name: t('Recordsets Detail'), key: 'dnsRecordSetDetail', level: 2, - routePath: '/network/dns/zones/detail/:id/recordsets/:recordset_id', + routePath: '/network/dns/zones/detail/:zoneId/recordsets/:id', }, - ] + ], }, { path: '/network/dns/reverse', @@ -485,8 +485,8 @@ const renderMenu = (t) => { level: 2, routePath: '/network/dns/reverse/detail/:id', }, - ] - } + ], + }, ], }, { diff --git a/src/locales/en.json b/src/locales/en.json index 47a245e6..422c6f6f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -2785,6 +2785,7 @@ "Zimbabwe": "Zimbabwe", "Zone": "Zone", "Zone ID": "Zone ID", + "Zone ID/Name": "Zone ID/Name", "Zone Name": "Zone Name", "Zones Detail": "Zones Detail", "abandon stack": "abandon stack", diff --git a/src/locales/ko-kr.json b/src/locales/ko-kr.json index a85ac954..2581b93c 100644 --- a/src/locales/ko-kr.json +++ b/src/locales/ko-kr.json @@ -2785,6 +2785,7 @@ "Zimbabwe": "", "Zone": "", "Zone ID": "", + "Zone ID/Name": "영역 ID/이름", "Zone Name": "", "Zones Detail": "", "abandon stack": "", diff --git a/src/locales/zh-hans.json b/src/locales/zh-hans.json index 574116e2..4cce1d5a 100644 --- a/src/locales/zh-hans.json +++ b/src/locales/zh-hans.json @@ -2785,6 +2785,7 @@ "Zimbabwe": "津巴布韦", "Zone": "区域", "Zone ID": "区域ID", + "Zone ID/Name": "区域ID/名称", "Zone Name": "区域名称", "Zones Detail": "区域详情", "abandon stack": "废弃堆栈", diff --git a/src/pages/network/containers/DNS/Zones/Detail/RecordSets/index.jsx b/src/pages/network/containers/DNS/Zones/Detail/RecordSets/index.jsx index ebe9ec0a..c0330bc1 100644 --- a/src/pages/network/containers/DNS/Zones/Detail/RecordSets/index.jsx +++ b/src/pages/network/containers/DNS/Zones/Detail/RecordSets/index.jsx @@ -14,13 +14,19 @@ import React from 'react'; import Base from 'containers/List'; import { inject, observer } from 'mobx-react'; import { Tag } from 'antd'; -import globalDNSRecordSetsStore from 'stores/designate/record-set'; -import { RECORD_STATUS, getRecordSetType } from 'resources/dns/record'; +import { DNSRecordSetsStore } from 'stores/designate/record-set'; +import { + RECORD_STATUS, + dnsRRTypeList, + getRecordSetType, +} from 'resources/dns/record'; +import { getOptions } from 'utils'; import actionConfigs from './actions'; export class RecordSets extends Base { init() { - this.store = globalDNSRecordSetsStore; + this.store = new DNSRecordSetsStore(); + this.downloadStore = new DNSRecordSetsStore(); } get name() { @@ -31,6 +37,14 @@ export class RecordSets extends Base { return 'get_recordsets'; } + get isFilterByBackend() { + return true; + } + + get isSortByBackend() { + return true; + } + get actionConfigs() { return actionConfigs; } @@ -43,11 +57,12 @@ export class RecordSets extends Base { routeName: this.getRouteName('dnsRecordSetDetail'), routeParamsFunc: (data) => { return { - id: data.zone_id, - recordset_id: data.id, + zoneId: data.zone_id, + id: data.id, }; }, isLink: true, + sortKey: 'id', }, { title: t('Type'), @@ -59,11 +74,37 @@ export class RecordSets extends Base { dataIndex: 'records', render: (value) => value.map((item) => {item}), stringify: (value) => value.join('\n'), + sorter: false, }, { title: t('Status'), dataIndex: 'status', valueMap: RECORD_STATUS, + sorter: false, + }, + { + title: t('Created At'), + dataIndex: 'created_at', + valueRender: 'toLocalTime', + }, + ]; + } + + get searchFilters() { + return [ + { + label: t('Name'), + name: 'name', + }, + { + label: t('Type'), + name: 'type', + options: dnsRRTypeList(), + }, + { + label: t('Status'), + name: 'status', + options: getOptions(RECORD_STATUS), }, ]; } diff --git a/src/pages/network/containers/DNS/Zones/index.jsx b/src/pages/network/containers/DNS/Zones/index.jsx index 90f1de76..7cef56f3 100644 --- a/src/pages/network/containers/DNS/Zones/index.jsx +++ b/src/pages/network/containers/DNS/Zones/index.jsx @@ -14,6 +14,7 @@ import { observer, inject } from 'mobx-react'; import Base from 'containers/List'; import globalDNSZonesStore, { DNSZonesStore } from 'src/stores/designate/zones'; import { ZONE_STATUS, ZONE_TYPES } from 'resources/dns/zone'; +import { getOptions } from 'utils'; import actionConfigs from './actions'; export class Zones extends Base { @@ -34,13 +35,29 @@ export class Zones extends Base { return actionConfigs; } + get isFilterByBackend() { + return true; + } + + get isSortByBackend() { + return true; + } + getColumns = () => [ { - title: t('Name'), + title: t('Zone ID/Name'), dataIndex: 'name', isHideable: true, isLink: true, - routeName: 'dnsZonesDetail', + routeName: this.getRouteName('dnsZonesDetail'), + sortKey: 'id', + }, + { + title: t('Project ID/Name'), + dataIndex: 'project_name', + isHideable: true, + hidden: !this.isAdminPage, + sortKey: 'tenant_id', }, { title: t('Type'), @@ -54,15 +71,32 @@ export class Zones extends Base { dataIndex: 'status', isHideable: true, valueMap: ZONE_STATUS, - sorter: false, }, { title: t('Created At'), dataIndex: 'created_at', valueRender: 'sinceTime', - sorter: false, }, ]; + + get searchFilters() { + return [ + { + label: t('Name'), + name: 'name', + }, + { + label: t('Type'), + name: 'type', + options: getOptions(ZONE_TYPES), + }, + { + label: t('Status'), + name: 'status', + options: getOptions(ZONE_STATUS), + }, + ]; + } } export default inject('rootStore')(observer(Zones)); diff --git a/src/pages/network/routes/index.js b/src/pages/network/routes/index.js index bdfaa3ed..71e6098e 100644 --- a/src/pages/network/routes/index.js +++ b/src/pages/network/routes/index.js @@ -250,10 +250,33 @@ export default [ exact: true, }, { path: `${PATH}/dns/zones`, component: Zones, exact: true }, - { path: `${PATH}/dns/zones/detail/:id`, component: ZonesDetail, exact: true }, - { path: `${PATH}/dns/zones/detail/:id/recordsets/:recordset_id`, component: RecordSetDetail, exact: true }, + { path: `${PATH}/dns-admin/zones`, component: Zones, exact: true }, + { + path: `${PATH}/dns/zones/detail/:id`, + component: ZonesDetail, + exact: true, + }, + { + path: `${PATH}/dns-admin/zones/detail/:id`, + component: ZonesDetail, + exact: true, + }, + { + path: `${PATH}/dns/zones/detail/:zoneId/recordsets/:id`, + component: RecordSetDetail, + exact: true, + }, + { + path: `${PATH}/dns-admin/zones/detail/:zoneId/recordsets/:id`, + component: RecordSetDetail, + exact: true, + }, { path: `${PATH}/dns/reverse`, component: Reverse, exact: true }, - { path: `${PATH}/dns/reverse/detail/:id`, component: ReverseDetail, exact: true }, + { + path: `${PATH}/dns/reverse/detail/:id`, + component: ReverseDetail, + exact: true, + }, { path: '*', component: E404 }, ], }, diff --git a/src/resources/dns/record.jsx b/src/resources/dns/record.jsx index 321dfca0..134ef348 100644 --- a/src/resources/dns/record.jsx +++ b/src/resources/dns/record.jsx @@ -100,6 +100,7 @@ export const dnsRRTypeList = () => { .map((item) => ({ label: `${item} - ${DNS_RECORD_TYPE[item].name}`, value: item, + key: item, })); }; diff --git a/src/stores/base.js b/src/stores/base.js index 41202937..5031c0f5 100644 --- a/src/stores/base.js +++ b/src/stores/base.js @@ -437,7 +437,7 @@ export default class BaseStore { this.listResponseKey ? get(result, this.listResponseKey, []) : result; // eslint-disable-next-line no-unused-vars - async getCountForPage(newParams, all_projects, newData) { + async getCountForPage(newParams, newData, all_projects, result, params) { return {}; } @@ -517,13 +517,15 @@ export default class BaseStore { } @action - async fetchDetail({ all_projects, silent, ...rest }) { + async fetchDetail(params) { + const { all_projects, silent, ...rest } = params || {}; if (!silent) { this.isLoading = true; } const result = await this.detailFetchByClient( rest, - this.getDetailParams({ all_projects }) + this.getDetailParams({ all_projects }), + params ); const originData = get(result, this.responseKey) || result; const item = this.mapperBeforeFetchProject(originData, rest, true); diff --git a/src/stores/designate/base.js b/src/stores/designate/base.js new file mode 100644 index 00000000..0c4aaecb --- /dev/null +++ b/src/stores/designate/base.js @@ -0,0 +1,70 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Base from 'stores/base'; + +export default class DNSBaseStore extends Base { + get paramsFuncPage() { + return (params) => { + const { current, all_projects, ...rest } = params; + return rest; + }; + } + + updateParamsSortPage = (params, sortKey, sortOrder) => { + if (sortKey && sortOrder) { + params.sort_key = sortKey; + params.sort_dir = sortOrder === 'descend' ? 'desc' : 'asc'; + } + }; + + listFetchByClient(params, originParams) { + const { all_projects = false } = originParams; + + const config = { + headers: { + 'x-auth-all-projects': all_projects, + }, + }; + if (!this.isSubResource) { + return this.client.list(params, config); + } + const fatherId = this.getFatherResourceId(originParams); + console.log('originParams', originParams); + return this.client.list(fatherId, params, config); + } + + detailFetchByClient(resourceParams, detailParams, originParams) { + const { id } = resourceParams; + const { all_projects = false } = originParams; + const config = { + headers: { + 'x-auth-all-projects': all_projects, + }, + }; + if (!this.isSubResource) { + return this.client.show(id, detailParams, config); + } + const fatherId = this.getFatherResourceId(resourceParams); + return this.client.show(fatherId, id, detailParams, config); + } + + async getCountForPage(newParams, newData, allProjects, result) { + const { metadata = {} } = result; + const { total_count = 0 } = metadata || {}; + const total = total_count; + return { + total, + count: total, + }; + } +} diff --git a/src/stores/designate/record-set.js b/src/stores/designate/record-set.js index 850db3da..b81c8e1f 100644 --- a/src/stores/designate/record-set.js +++ b/src/stores/designate/record-set.js @@ -12,7 +12,7 @@ import client from 'client'; import { action } from 'mobx'; -import Base from 'stores/base'; +import Base from './base'; export class DNSRecordSetsStore extends Base { get client() { @@ -23,14 +23,11 @@ export class DNSRecordSetsStore extends Base { return true; } - detailFetchByClient(resourceParams) { - const { id, recordset_id } = resourceParams; - return this.client.show(id, recordset_id); - } + getFatherResourceId = (params) => params.zoneId || params.id; - get paramsFunc() { + get paramsFuncPage() { return (params) => { - const { id, ...rest } = params; + const { id, zoneId, all_projects, current, ...rest } = params; return rest; }; } diff --git a/src/stores/designate/zones.js b/src/stores/designate/zones.js index 3dfb0d2d..5f2c4840 100644 --- a/src/stores/designate/zones.js +++ b/src/stores/designate/zones.js @@ -12,7 +12,7 @@ import { action } from 'mobx'; import client from 'client'; -import Base from 'stores/base'; +import Base from './base'; export class DNSZonesStore extends Base { get client() { diff --git a/src/stores/octavia/loadbalancer.js b/src/stores/octavia/loadbalancer.js index 3e261b8c..e7934ee8 100644 --- a/src/stores/octavia/loadbalancer.js +++ b/src/stores/octavia/loadbalancer.js @@ -89,7 +89,9 @@ export class LbaasStore extends Base { const totalResult = await this.getCountForPage( newParams, newData, - all_projects + all_projects, + result, + params ); const { count: retCount, total: retTotal } = totalResult; count = retCount;