From 8129af966e2584d5a164bed2de5fcbb5a5bc4fe1 Mon Sep 17 00:00:00 2001 From: "Jingwei.Zhang" Date: Thu, 21 Apr 2022 17:26:44 +0800 Subject: [PATCH] feat: Support manila share group type page 1. Add share group type page in administrator 2. Add create share group type 3. Add delete share group type 4. Add share group type detail page 5. Add create group spec 6. Add edit group spec 7. Add delete group spec 8. Add manage group type access Change-Id: I5292d157ae1b06ba3b35b6f6fd2eeb455b7582a7 --- src/client/client/constants.js | 2 +- src/client/manila/index.js | 25 ++++ src/layouts/admin-menu.jsx | 16 +++ src/locales/en.json | 6 + src/locales/zh.json | 6 + .../Detail/ExtraSpec/actions/Create.jsx | 71 ++++++++++ .../Detail/ExtraSpec/actions/Delete.jsx | 52 ++++++++ .../Detail/ExtraSpec/actions/Edit.jsx | 77 +++++++++++ .../Detail/ExtraSpec/actions/index.jsx | 32 +++++ .../ShareGroupType/Detail/ExtraSpec/index.jsx | 58 +++++++++ .../ShareGroupType/Detail/index.jsx | 68 ++++++++++ .../ShareGroupType/actions/Create.jsx | 111 ++++++++++++++++ .../ShareGroupType/actions/Delete.jsx | 42 ++++++ .../ShareGroupType/actions/ManageAccess.jsx | 123 ++++++++++++++++++ .../ShareGroupType/actions/index.jsx | 32 +++++ .../share/containers/ShareGroupType/index.jsx | 62 +++++++++ src/pages/share/routes/index.js | 12 ++ src/stores/manila/group-spec.js | 58 +++++++++ src/stores/manila/share-group-type.js | 104 +++++++++++++++ 19 files changed, 956 insertions(+), 1 deletion(-) create mode 100644 src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Create.jsx create mode 100644 src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Delete.jsx create mode 100644 src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Edit.jsx create mode 100644 src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/index.jsx create mode 100644 src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/index.jsx create mode 100644 src/pages/share/containers/ShareGroupType/Detail/index.jsx create mode 100644 src/pages/share/containers/ShareGroupType/actions/Create.jsx create mode 100644 src/pages/share/containers/ShareGroupType/actions/Delete.jsx create mode 100644 src/pages/share/containers/ShareGroupType/actions/ManageAccess.jsx create mode 100644 src/pages/share/containers/ShareGroupType/actions/index.jsx create mode 100644 src/pages/share/containers/ShareGroupType/index.jsx create mode 100644 src/stores/manila/group-spec.js create mode 100644 src/stores/manila/share-group-type.js diff --git a/src/client/client/constants.js b/src/client/client/constants.js index 48838ef5..ac991d7a 100644 --- a/src/client/client/constants.js +++ b/src/client/client/constants.js @@ -101,7 +101,7 @@ export const apiVersionMaps = { }, manila: { key: 'X-OpenStack-Manila-API-Version', - value: '2.51', + value: '2.55', }, }; diff --git a/src/client/manila/index.js b/src/client/manila/index.js index 107dd5cd..d74d2e00 100644 --- a/src/client/manila/index.js +++ b/src/client/manila/index.js @@ -65,6 +65,31 @@ class ManilaClient extends Base { }, ], }, + { + name: 'shareGroupTypes', + key: 'share-group-types', + responseKey: 'share_group_type', + extendOperations: [ + { + key: 'action', + method: 'post', + }, + { + name: 'getAccess', + key: 'access', + }, + { + key: 'default', + }, + ], + subResources: [ + { + name: 'groupSpecs', + key: 'group-specs', + responseKey: 'group_spec', + }, + ], + }, ]; } } diff --git a/src/layouts/admin-menu.jsx b/src/layouts/admin-menu.jsx index 6b0e8993..d2a6d122 100644 --- a/src/layouts/admin-menu.jsx +++ b/src/layouts/admin-menu.jsx @@ -421,6 +421,22 @@ const renderMenu = (t) => { }, ], }, + { + path: '/share/share-group-type-admin', + name: t('Share Group Type'), + key: 'shareGroupTypeAdmin', + level: 1, + endpoints: 'manilav2', + children: [ + { + path: /^\/share\/share-group-type-admin\/detail\/.[^/]+$/, + name: t('Share Group Type Detail'), + key: 'shareGroupTypeDetailAdmin', + level: 2, + routePath: '/share/share-group-type-admin/detail/:id', + }, + ], + }, ], }, { diff --git a/src/locales/en.json b/src/locales/en.json index fba89b9e..f849d269 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -412,6 +412,7 @@ "Create Rule": "Create Rule", "Create Security Group": "Create Security Group", "Create Server Group": "Create Server Group", + "Create Share Group Type": "Create Share Group Type", "Create Share Type": "Create Share Type", "Create Snapshot": "Create Snapshot", "Create Stack": "Create Stack", @@ -554,6 +555,7 @@ "Delete Rule": "Delete Rule", "Delete Security Group": "Delete Security Group", "Delete Server Group": "Delete Server Group", + "Delete Share Group Type": "Delete Share Group Type", "Delete Share Type": "Delete Share Type", "Delete Snapshot": "Delete Snapshot", "Delete Static Route": "Delete Static Route", @@ -1749,6 +1751,8 @@ "Set IP": "Set IP", "Seychelles": "Seychelles", "Share File Storage": "Share File Storage", + "Share Group Type": "Share Group Type", + "Share Group Type Detail": "Share Group Type Detail", "Share Type": "Share Type", "Share Type Detail": "Share Type Detail", "Shared": "Shared", @@ -2250,6 +2254,7 @@ "create ipsec site connection": "create ipsec site connection", "create network": "create network", "create router": "create router", + "create share group type": "create share group type", "create share type": "create share type", "create snapshot": "create snapshot", "create stack": "create stack", @@ -2399,6 +2404,7 @@ "server groups": "server groups", "services": "services", "settings": "settings", + "share group type": "share group type", "share type": "share type", "share types": "share types", "shelve instance": "shelve instance", diff --git a/src/locales/zh.json b/src/locales/zh.json index 2bde9417..85810e9d 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -412,6 +412,7 @@ "Create Rule": "创建规则", "Create Security Group": "创建安全组", "Create Server Group": "创建云主机组", + "Create Share Group Type": "创建共享组类型", "Create Share Type": "创建共享类型", "Create Snapshot": "创建快照", "Create Stack": "创建堆栈", @@ -554,6 +555,7 @@ "Delete Rule": "删除规则", "Delete Security Group": "删除安全组", "Delete Server Group": "删除云主机组", + "Delete Share Group Type": "删除共享组类型", "Delete Share Type": "删除共享类型", "Delete Snapshot": "删除快照", "Delete Static Route": "删除静态路由", @@ -1749,6 +1751,8 @@ "Set IP": "设置IP", "Seychelles": "塞舌尔", "Share File Storage": "文件存储", + "Share Group Type": "共享组类型", + "Share Group Type Detail": "共享组类型详情", "Share Type": "共享类型", "Share Type Detail": "共享类型详情", "Shared": "共享", @@ -2250,6 +2254,7 @@ "create ipsec site connection": "创建IPsec站点连接", "create network": "创建网络", "create router": "创建路由", + "create share group type": "创建共享组类型", "create share type": "创建共享类型", "create snapshot": "创建快照", "create stack": "创建堆栈", @@ -2399,6 +2404,7 @@ "server groups": "云主机组", "services": "服务", "settings": "配置", + "share group type": "共享组类型", "share type": "共享类型", "share types": "共享类型", "shelve instance": "归档云主机", diff --git a/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Create.jsx b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Create.jsx new file mode 100644 index 00000000..218ccbdd --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Create.jsx @@ -0,0 +1,71 @@ +// Copyright 2021 99cloud +// +// 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 { inject, observer } from 'mobx-react'; +import { ModalAction } from 'containers/Action'; +import globalGroupSpecStore from 'stores/manila/group-spec'; + +export class Create extends ModalAction { + static id = 'create'; + + static title = t('Create Extra Specs'); + + get name() { + return t('Create Extra Specs'); + } + + static policy = 'manila:share_group_types_spec:create'; + + static allowed = () => Promise.resolve(true); + + get defaultValue() { + return {}; + } + + get instanceName() { + return this.values.keyName; + } + + get formItems() { + return [ + { + name: 'keyName', + label: t('Key'), + type: 'input', + required: true, + placeholder: t('Please input key'), + }, + { + name: 'value', + label: t('Value'), + type: 'input', + placeholder: t('Please input value'), + required: true, + }, + ]; + } + + init() { + this.store = globalGroupSpecStore; + } + + onSubmit = (values) => { + const { id } = this.containerProps.detail; + const { keyName, value } = values; + const extra_specs = { [keyName]: value }; + return this.store.createOrUpdate(id, extra_specs); + }; +} + +export default inject('rootStore')(observer(Create)); diff --git a/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Delete.jsx b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Delete.jsx new file mode 100644 index 00000000..530a53db --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Delete.jsx @@ -0,0 +1,52 @@ +// Copyright 2021 99cloud +// +// 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 { ConfirmAction } from 'containers/Action'; +import globalGroupSpecStore from 'stores/manila/group-spec'; + +export default class Delete extends ConfirmAction { + get id() { + return 'delete'; + } + + get title() { + return t('Delete Extra Specs'); + } + + get buttonType() { + return 'danger'; + } + + get buttonText() { + return t('Delete'); + } + + get actionName() { + return t('Delete Extra Specs'); + } + + policy = 'manila:share_group_types_spec:delete'; + + allowedCheckFunc = () => true; + + onSubmit = (data) => { + const { id } = this.containerProps.detail; + const { keyName } = data; + const body = { + id, + keyName, + }; + return globalGroupSpecStore.delete(body); + }; +} diff --git a/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Edit.jsx b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Edit.jsx new file mode 100644 index 00000000..4ad4b91e --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/Edit.jsx @@ -0,0 +1,77 @@ +// Copyright 2021 99cloud +// +// 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 { inject, observer } from 'mobx-react'; +import { ModalAction } from 'containers/Action'; +import globalGroupSpecStore from 'stores/manila/group-spec'; + +export class Edit extends ModalAction { + static id = 'edit'; + + static title = t('Edit Extra Specs'); + + static buttonText = t('Edit'); + + get name() { + return t('Edit Extra Specs'); + } + + get instanceName() { + return this.item.keyName; + } + + get defaultValue() { + const { keyName, value } = this.item; + const defaultValue = { + keyName, + value, + }; + return defaultValue; + } + + static policy = 'manila:share_group_types_spec:update'; + + static allowed = () => Promise.resolve(true); + + get formItems() { + return [ + { + name: 'keyName', + label: t('Key'), + type: 'input', + disabled: true, + placeholder: t('Please input key'), + }, + { + name: 'value', + label: t('Value'), + type: 'input', + placeholder: t('Please input value'), + }, + ]; + } + + init() { + this.store = globalGroupSpecStore; + } + + onSubmit = (values) => { + const { id } = this.containerProps.detail; + const { keyName, value } = values; + const extra_specs = { [keyName]: value }; + return this.store.createOrUpdate(id, extra_specs); + }; +} + +export default inject('rootStore')(observer(Edit)); diff --git a/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/index.jsx b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/index.jsx new file mode 100644 index 00000000..19482145 --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/actions/index.jsx @@ -0,0 +1,32 @@ +// Copyright 2021 99cloud +// +// 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 Create from './Create'; +import Edit from './Edit'; +import Delete from './Delete'; + +const actionConfigs = { + rowActions: { + firstAction: Delete, + moreActions: [ + { + action: Edit, + }, + ], + }, + batchActions: [Delete], + primaryActions: [Create], +}; + +export default actionConfigs; diff --git a/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/index.jsx b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/index.jsx new file mode 100644 index 00000000..91605fad --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/Detail/ExtraSpec/index.jsx @@ -0,0 +1,58 @@ +// Copyright 2021 99cloud +// +// 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 { observer, inject } from 'mobx-react'; +import Base from 'containers/List'; +import { GroupSpecStore } from 'stores/manila/group-spec'; +import actionConfigs from './actions'; + +export class ExtraSpecs extends Base { + init() { + this.store = new GroupSpecStore(); + } + + get policy() { + return 'manila:share_group_types_spec:index'; + } + + get name() { + return t('extra specs'); + } + + getColumns = () => [ + { + title: t('Key'), + dataIndex: 'keyName', + }, + { + title: t('Value'), + dataIndex: 'value', + }, + ]; + + get actionConfigs() { + return actionConfigs; + } + + get searchFilters() { + return [ + { + label: t('Key'), + name: 'keyName', + }, + ]; + } +} + +export default inject('rootStore')(observer(ExtraSpecs)); diff --git a/src/pages/share/containers/ShareGroupType/Detail/index.jsx b/src/pages/share/containers/ShareGroupType/Detail/index.jsx new file mode 100644 index 00000000..b80bc325 --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/Detail/index.jsx @@ -0,0 +1,68 @@ +// Copyright 2021 99cloud +// +// 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 { inject, observer } from 'mobx-react'; +import { ShareGroupTypeStore } from 'stores/manila/share-group-type'; +import Base from 'containers/TabDetail'; +import ExtraSpec from './ExtraSpec'; +import actionConfigs from '../actions'; + +export class Detail extends Base { + get name() { + return t('share group type'); + } + + get policy() { + return 'manila:share_group_type:show'; + } + + get listUrl() { + return this.getRoutePath('shareGroupType'); + } + + get actionConfigs() { + return actionConfigs; + } + + get detailInfos() { + return [ + { + title: t('Name'), + dataIndex: 'name', + }, + { + title: t('Public'), + dataIndex: 'is_public', + isHideable: true, + valueRender: 'yesNo', + }, + ]; + } + + get tabs() { + return [ + { + title: t('Extra Spec'), + key: 'extraSpec', + component: ExtraSpec, + }, + ]; + } + + init() { + this.store = new ShareGroupTypeStore(); + } +} + +export default inject('rootStore')(observer(Detail)); diff --git a/src/pages/share/containers/ShareGroupType/actions/Create.jsx b/src/pages/share/containers/ShareGroupType/actions/Create.jsx new file mode 100644 index 00000000..4fa6a095 --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/actions/Create.jsx @@ -0,0 +1,111 @@ +// Copyright 2021 99cloud +// +// 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 { inject, observer } from 'mobx-react'; +import { ModalAction } from 'containers/Action'; +import globalShareGroupTypeStore from '@/stores/manila/share-group-type'; +import { projectTableOptions } from 'resources/project'; +import { ProjectStore } from 'stores/keystone/project'; +import { updateAddSelectValueToObj } from 'utils/index'; +import { extraFormItem } from 'pages/share/containers/ShareType/actions/Create'; + +export class Create extends ModalAction { + static id = 'create'; + + static title = t('Create Share Group Type'); + + get name() { + return t('create share group type'); + } + + init() { + this.store = globalShareGroupTypeStore; + this.projectStore = new ProjectStore(); + this.getProjects(); + } + + getProjects() { + this.projectStore.fetchList(); + } + + get projects() { + return this.projectStore.list.data || []; + } + + static policy = 'manila:share_group_type:create'; + + static allowed = () => Promise.resolve(true); + + static get modalSize() { + return 'large'; + } + + getModalSize() { + return 'large'; + } + + get nameForStateUpdate() { + return ['isPublic']; + } + + get defaultValue() { + return { is_public: true }; + } + + get formItems() { + const { isPublic } = this.state; + return [ + { + name: 'name', + label: t('Name'), + type: 'input-name', + names: this.store.list.data.map((it) => it.name), + required: true, + }, + { + name: 'is_public', + label: t('Public'), + type: 'check', + content: t('Public'), + required: true, + }, + { + name: 'accessControl', + label: t('Access Control'), + type: 'select-table', + isMulti: true, + hidden: isPublic, + data: this.projects, + isLoading: this.projectStore.list.isLoading, + ...projectTableOptions, + }, + extraFormItem, + ]; + } + + onSubmit = (values) => { + const { is_public, accessControl = {}, extra = [], ...rest } = values; + const body = { is_public, ...rest }; + let projectIds = []; + const extraSpecs = updateAddSelectValueToObj(extra); + body.group_specs = extraSpecs; + if (!is_public) { + const { selectedRowKeys = [] } = accessControl; + projectIds = [...selectedRowKeys]; + } + return this.store.create(body, projectIds); + }; +} + +export default inject('rootStore')(observer(Create)); diff --git a/src/pages/share/containers/ShareGroupType/actions/Delete.jsx b/src/pages/share/containers/ShareGroupType/actions/Delete.jsx new file mode 100644 index 00000000..7c8121af --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/actions/Delete.jsx @@ -0,0 +1,42 @@ +// Copyright 2021 99cloud +// +// 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 { ConfirmAction } from 'containers/Action'; +import globalShareGroupTypeStore from '@/stores/manila/share-group-type'; + +export default class Delete extends ConfirmAction { + get id() { + return 'delete'; + } + + get title() { + return t('Delete Share Group Type'); + } + + get buttonType() { + return 'danger'; + } + + get buttonText() { + return t('Delete'); + } + + get actionName() { + return t('Delete Share Group Type'); + } + + policy = 'manila:share_group_type:delete'; + + onSubmit = (data) => globalShareGroupTypeStore.delete(data); +} diff --git a/src/pages/share/containers/ShareGroupType/actions/ManageAccess.jsx b/src/pages/share/containers/ShareGroupType/actions/ManageAccess.jsx new file mode 100644 index 00000000..b94e84c0 --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/actions/ManageAccess.jsx @@ -0,0 +1,123 @@ +// Copyright 2021 99cloud +// +// 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 { inject, observer } from 'mobx-react'; +import globalShareGroupTypeStore, { + ShareGroupTypeStore, +} from '@/stores/manila/share-group-type'; +import { ModalAction } from 'containers/Action'; +import { ProjectStore } from 'stores/keystone/project'; +import { projectTableOptions } from 'resources/project'; + +export class ManageAccess extends ModalAction { + static id = 'manage-access'; + + static title = t('Manage Access'); + + init() { + this.store = new ShareGroupTypeStore(); + this.projectStore = new ProjectStore(); + this.getAccess(); + this.getProjects(); + } + + static get modalSize() { + return 'large'; + } + + getModalSize() { + return 'large'; + } + + static policy = [ + 'manila:share_group_type:list_project_access', + 'manila:share_group_type:add_project_access', + 'manila:share_group_type:remove_project_access', + ]; + + static allowed = (item) => Promise.resolve(!item.is_public); + + async getAccess() { + const { is_public } = this.item; + if (!is_public) { + await this.store.fetchProjectAccess(this.item.id); + this.updateDefaultValue(); + } + } + + async getProjects() { + await this.projectStore.fetchList(); + this.updateDefaultValue(); + } + + get name() { + return t('Manage Access'); + } + + get projects() { + return this.projectStore.list.data || []; + } + + get defaultValue() { + const { name } = this.item; + return { + name, + access: { + selectedRowKeys: this.currentAccess, + }, + }; + } + + get currentAccess() { + return (this.store.access || []).map((it) => it.project_id); + } + + get formItems() { + const { isPublic } = this.state; + return [ + { + name: 'name', + label: t('Share Type'), + type: 'label', + iconType: 'volume', + }, + { + name: 'access', + label: t('Access Control'), + type: 'select-table', + isMulti: true, + hidden: isPublic, + data: this.projects, + isLoading: this.projectStore.list.isLoading, + ...projectTableOptions, + }, + ]; + } + + onSubmit = (values) => { + const { access = {} } = values; + const { id } = this.item; + const body = { id }; + const { selectedRowKeys = [] } = access; + body.adds = selectedRowKeys.filter( + (it) => this.currentAccess.indexOf(it) < 0 + ); + body.dels = this.currentAccess.filter( + (it) => selectedRowKeys.indexOf(it) < 0 + ); + return globalShareGroupTypeStore.updateProjectAccess(body); + }; +} + +export default inject('rootStore')(observer(ManageAccess)); diff --git a/src/pages/share/containers/ShareGroupType/actions/index.jsx b/src/pages/share/containers/ShareGroupType/actions/index.jsx new file mode 100644 index 00000000..d3a35fa2 --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/actions/index.jsx @@ -0,0 +1,32 @@ +// Copyright 2021 99cloud +// +// 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 Create from './Create'; +import Delete from './Delete'; +import ManageAccess from './ManageAccess'; + +const actionConfigs = { + rowActions: { + firstAction: ManageAccess, + moreActions: [ + { + action: Delete, + }, + ], + }, + primaryActions: [Create], + batchActions: [Delete], +}; + +export default actionConfigs; diff --git a/src/pages/share/containers/ShareGroupType/index.jsx b/src/pages/share/containers/ShareGroupType/index.jsx new file mode 100644 index 00000000..d485e386 --- /dev/null +++ b/src/pages/share/containers/ShareGroupType/index.jsx @@ -0,0 +1,62 @@ +// Copyright 2021 99cloud +// +// 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 { observer, inject } from 'mobx-react'; +import Base from 'containers/List'; +import globalShareGroupTypeStore from '@/stores/manila/share-group-type'; +import actionConfigs from './actions'; + +export class ShareGroupType extends Base { + init() { + this.store = globalShareGroupTypeStore; + } + + get policy() { + return 'manila:share_type:index'; + } + + get name() { + return t('share types'); + } + + get fetchDataByAllProjects() { + return false; + } + + get actionConfigs() { + return actionConfigs; + } + + updateFetchParams = (params) => { + return { + ...params, + is_public: 'all', + }; + }; + + getColumns = () => [ + { + title: t('ID/Name'), + dataIndex: 'name', + routeName: 'shareGroupTypeDetailAdmin', + }, + { + title: t('Public'), + dataIndex: 'is_public', + valueRender: 'yesNo', + }, + ]; +} + +export default inject('rootStore')(observer(ShareGroupType)); diff --git a/src/pages/share/routes/index.js b/src/pages/share/routes/index.js index d1e8773f..4fabad99 100644 --- a/src/pages/share/routes/index.js +++ b/src/pages/share/routes/index.js @@ -16,6 +16,8 @@ import BaseLayout from 'layouts/Basic'; import E404 from 'pages/base/containers/404'; import ShareType from '../containers/ShareType'; import ShareTypeDetail from '../containers/ShareType/Detail'; +import ShareGroupType from '../containers/ShareGroupType'; +import ShareGroupTypeDetail from '../containers/ShareGroupType/Detail'; const PATH = '/share'; export default [ @@ -29,6 +31,16 @@ export default [ component: ShareTypeDetail, exact: true, }, + { + path: `${PATH}/share-group-type-admin`, + component: ShareGroupType, + exact: true, + }, + { + path: `${PATH}/share-group-type-admin/detail/:id`, + component: ShareGroupTypeDetail, + exact: true, + }, { path: '*', component: E404 }, ], }, diff --git a/src/stores/manila/group-spec.js b/src/stores/manila/group-spec.js new file mode 100644 index 00000000..16e70be6 --- /dev/null +++ b/src/stores/manila/group-spec.js @@ -0,0 +1,58 @@ +// Copyright 2021 99cloud +// +// 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 { action } from 'mobx'; +import client from 'client'; +import Base from 'stores/base'; + +export class GroupSpecStore extends Base { + get client() { + return client.manila.shareGroupTypes.groupSpecs; + } + + get isSubResource() { + return true; + } + + getFatherResourceId = (params) => params.id; + + getListDataFromResult = (result) => { + const { group_specs } = result; + const data = []; + Object.keys(group_specs).forEach((key) => { + data.push({ + id: key, + keyName: key, + name: key, + value: group_specs[key], + }); + }); + return data; + }; + + @action + createOrUpdate(id, data) { + const body = { + group_specs: data, + }; + return this.submitting(this.client.create(id, body)); + } + + @action + delete = ({ id, keyName }) => { + return this.submitting(this.client.delete(id, keyName)); + }; +} +const globalGroupSpecStore = new GroupSpecStore(); +export default globalGroupSpecStore; diff --git a/src/stores/manila/share-group-type.js b/src/stores/manila/share-group-type.js new file mode 100644 index 00000000..6775c90f --- /dev/null +++ b/src/stores/manila/share-group-type.js @@ -0,0 +1,104 @@ +// Copyright 2021 99cloud +// +// 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 { action, observable } from 'mobx'; +import client from 'client'; +import Base from 'stores/base'; + +export class ShareGroupTypeStore extends Base { + @observable + access = []; + + get client() { + return client.manila.shareGroupTypes; + } + + get paramsFunc() { + return (params) => params; + } + + @action + async create(data, projectIds = []) { + const body = {}; + body[this.responseKey] = data; + if (projectIds.length === 0) { + return this.submitting(this.client.create(body)); + } + this.isSubmitting = true; + const result = await this.client.create(body); + const { id } = result[this.responseKey]; + return this.addProjectAccess(id, projectIds); + } + + @action + update(id, data) { + const body = {}; + body[this.responseKey] = data; + return this.submitting(this.client.update(id, body)); + } + + @action + addProjectAccess(id, projectIds = []) { + return this.submitting( + Promise.all( + projectIds.map((it) => { + const actionBody = { + addProjectAccess: { + project: it, + }, + }; + return this.client.action(id, actionBody); + }) + ) + ); + } + + @action + removeProjectAccess(id, projectIds = []) { + return this.submitting( + Promise.all( + projectIds.map((it) => { + const actionBody = { + removeProjectAccess: { + project: it, + }, + }; + return this.client.action(id, actionBody); + }) + ) + ); + } + + @action + async updateProjectAccess({ id, adds = [], dels = [], newPublic }) { + const more = adds.length > 0 || dels.length > 0; + if (newPublic !== undefined) { + if (newPublic || !more) { + return this.update(id, { 'share_type_access:is_public': newPublic }); + } + await this.update(id, { 'share_type_access:is_public': newPublic }); + } + await this.removeProjectAccess(id, dels); + return this.addProjectAccess(id, adds); + } + + @action + async fetchProjectAccess(id) { + const result = await this.client.getAccess(id); + this.access = result.share_group_type_access; + } +} + +const globalShareGroupTypeStore = new ShareGroupTypeStore(); +export default globalShareGroupTypeStore;