feat: Update share actions && fetch

1. Add public policy check when create public share
2. Add public policy check when edit share
3. Disable actions for public share that do not belong to you
4. Remove update-time info from share detail page
5. Remove update-time info from share group detail page
6. Fix share api fetch: add is_public=true to fetch all data
7. Support share api fetch sorter
8. Support share group api fetch sorter

Change-Id: I737747086900626872df3e566f6e4f21c48893f2
This commit is contained in:
Jingwei.Zhang 2022-05-17 13:22:30 +08:00
parent 020defa50b
commit 3643ca912c
17 changed files with 133 additions and 56 deletions

View File

@ -17,7 +17,8 @@ import { ModalAction } from 'containers/Action';
import globalShareAccessRuleStore from 'stores/manila/share-access-rule'; import globalShareAccessRuleStore from 'stores/manila/share-access-rule';
import { keyValueValidator } from 'pages/share/containers/ShareType/actions/Create'; import { keyValueValidator } from 'pages/share/containers/ShareType/actions/Create';
import KeyValueInput from 'components/FormItem/KeyValueInput'; import KeyValueInput from 'components/FormItem/KeyValueInput';
import { updateAddSelectValueToObj } from 'utils/index'; import { updateAddSelectValueToObj, getOptions } from 'utils/index';
import { shareAccessLevel, shareAccessType } from 'resources/manila/share';
export const metadataFormItem = { export const metadataFormItem = {
name: 'metadata', name: 'metadata',
@ -55,37 +56,11 @@ export class Create extends ModalAction {
static allowed = () => Promise.resolve(true); static allowed = () => Promise.resolve(true);
get typeOptions() { get typeOptions() {
return [ return getOptions(shareAccessType);
{
value: 'ip',
label: t('IP'),
},
{
value: 'cert',
label: t('Cert'),
},
{
value: 'user',
label: t('User'),
},
{
value: 'cephx',
label: t('Cephx'),
},
];
} }
get levelOptions() { get levelOptions() {
return [ return getOptions(shareAccessLevel);
{
value: 'rw',
label: t('Read and write'),
},
{
value: 'ro',
label: t('Read only'),
},
];
} }
get defaultValue() { get defaultValue() {

View File

@ -15,7 +15,8 @@
import { observer, inject } from 'mobx-react'; import { observer, inject } from 'mobx-react';
import Base from 'containers/List'; import Base from 'containers/List';
import globalShareAccessRuleStore from 'stores/manila/share-access-rule'; import globalShareAccessRuleStore from 'stores/manila/share-access-rule';
import { shareAccessRuleState } from 'resources/manila/share'; import { shareAccessRuleState, shareAccessLevel } from 'resources/manila/share';
import { emptyActionConfig } from 'utils/constants';
import actionConfigs from './actions'; import actionConfigs from './actions';
export class ShareAccessRule extends Base { export class ShareAccessRule extends Base {
@ -32,9 +33,14 @@ export class ShareAccessRule extends Base {
} }
get actionConfigs() { get actionConfigs() {
return this.isAdminPage if (this.isAdminPage) {
? actionConfigs.actionConfigsAdmin return actionConfigs.actionConfigsAdmin;
: actionConfigs.actionConfigs; }
const { detail: { isMine } = {} } = this.props;
if (isMine) {
return actionConfigs.actionConfigs;
}
return emptyActionConfig;
} }
getColumns = () => [ getColumns = () => [
@ -53,6 +59,7 @@ export class ShareAccessRule extends Base {
{ {
title: t('Access Level'), title: t('Access Level'),
dataIndex: 'access_level', dataIndex: 'access_level',
render: (value) => shareAccessLevel[value] || value,
}, },
{ {
title: t('State'), title: t('State'),

View File

@ -15,6 +15,7 @@
import { observer, inject } from 'mobx-react'; import { observer, inject } from 'mobx-react';
import Base from 'containers/List'; import Base from 'containers/List';
import { ShareMetadataStore } from 'stores/manila/share-metadata'; import { ShareMetadataStore } from 'stores/manila/share-metadata';
import { emptyActionConfig } from 'utils/constants';
import actionConfigs from './actions'; import actionConfigs from './actions';
export class Metadata extends Base { export class Metadata extends Base {
@ -42,9 +43,14 @@ export class Metadata extends Base {
]; ];
get actionConfigs() { get actionConfigs() {
return this.isAdminPage if (this.isAdminPage) {
? actionConfigs.actionConfigsAdmin return actionConfigs.actionConfigsAdmin;
: actionConfigs.actionConfigs; }
const { detail: { isMine } = {} } = this.props;
if (isMine) {
return actionConfigs.actionConfigs;
}
return emptyActionConfig;
} }
get searchFilters() { get searchFilters() {

View File

@ -60,11 +60,6 @@ export class Detail extends Base {
dataIndex: 'created_at', dataIndex: 'created_at',
valueRender: 'toLocalTime', valueRender: 'toLocalTime',
}, },
{
title: t('Updated'),
dataIndex: 'updated_at',
valueRender: 'toLocalTime',
},
]; ];
} }

View File

@ -38,6 +38,7 @@ import { cloneDeep } from 'lodash';
import { idNameColumn } from 'utils/table'; import { idNameColumn } from 'utils/table';
import { extraFormItem } from 'pages/share/containers/ShareType/actions/Create'; import { extraFormItem } from 'pages/share/containers/ShareType/actions/Create';
import { updateAddSelectValueToObj, getOptions } from 'utils/index'; import { updateAddSelectValueToObj, getOptions } from 'utils/index';
import { checkPolicyRule } from 'resources/skyline/policy';
export class Create extends FormAction { export class Create extends FormAction {
static id = 'create'; static id = 'create';
@ -135,6 +136,14 @@ export class Create extends FormAction {
return [idNameColumn, ...rest]; return [idNameColumn, ...rest];
} }
get shareProtocolOptions() {
return getOptions(shareProtocol);
}
checkShowPublic() {
return checkPolicyRule('manila:share:create_public_share');
}
get formItems() { get formItems() {
const { showNetworks = false, shareGroups = [] } = this.state; const { showNetworks = false, shareGroups = [] } = this.state;
const minSize = 1; const minSize = 1;
@ -175,7 +184,7 @@ export class Create extends FormAction {
label: t('Share Protocol'), label: t('Share Protocol'),
type: 'select', type: 'select',
required: true, required: true,
options: getOptions(shareProtocol), options: this.shareProtocolOptions,
}, },
{ {
name: 'size', name: 'size',
@ -183,7 +192,7 @@ export class Create extends FormAction {
type: 'slider-input', type: 'slider-input',
max: this.maxSize, max: this.maxSize,
min: minSize, min: minSize,
description: `${minSize}GB-${this.maxSize}GB`, description: `${minSize}GiB-${this.maxSize}GiB`,
required: this.quotaIsLimit, required: this.quotaIsLimit,
display: this.quotaIsLimit, display: this.quotaIsLimit,
}, },
@ -201,6 +210,7 @@ export class Create extends FormAction {
type: 'check', type: 'check',
content: t('Public'), content: t('Public'),
tip: t('If set then all tenants will be able to see this share.'), tip: t('If set then all tenants will be able to see this share.'),
display: this.checkShowPublic(),
}, },
{ {
name: 'shareType', name: 'shareType',
@ -246,14 +256,24 @@ export class Create extends FormAction {
} }
onSubmit = (values) => { onSubmit = (values) => {
const { shareType, shareNetwork, shareGroup, project, metadata, ...rest } = const {
values; shareType,
shareNetwork,
shareGroup,
project,
metadata,
is_public,
...rest
} = values;
const { showNetworks = false } = this.state; const { showNetworks = false } = this.state;
const body = { const body = {
...rest, ...rest,
share_type: shareType.selectedRowKeys[0], share_type: shareType.selectedRowKeys[0],
metadata: updateAddSelectValueToObj(metadata), metadata: updateAddSelectValueToObj(metadata),
}; };
if (this.checkShowPublic() && is_public) {
body.is_public = is_public;
}
const { selectedRowKeys: networkKeys = [] } = shareNetwork || {}; const { selectedRowKeys: networkKeys = [] } = shareNetwork || {};
const { selectedRowKeys: groupKeys = [] } = shareGroup || {}; const { selectedRowKeys: groupKeys = [] } = shareGroup || {};
if (showNetworks && networkKeys.length) { if (showNetworks && networkKeys.length) {

View File

@ -38,5 +38,9 @@ export default class Delete extends ConfirmAction {
policy = 'manila:share:delete'; policy = 'manila:share:delete';
allowedCheckFunc = (item) => {
return this.isAdminPage || item.isMine;
};
onSubmit = (data) => globalShareStore.delete(data); onSubmit = (data) => globalShareStore.delete(data);
} }

View File

@ -15,6 +15,7 @@
import { inject, observer } from 'mobx-react'; import { inject, observer } from 'mobx-react';
import { ModalAction } from 'containers/Action'; import { ModalAction } from 'containers/Action';
import globalShareStore from 'stores/manila/share'; import globalShareStore from 'stores/manila/share';
import { checkPolicyRule } from 'resources/skyline/policy';
export class Edit extends ModalAction { export class Edit extends ModalAction {
static id = 'edit'; static id = 'edit';
@ -33,7 +34,11 @@ export class Edit extends ModalAction {
static policy = 'manila:share:update'; static policy = 'manila:share:update';
static allowed = () => Promise.resolve(true); static allowed = (item) => Promise.resolve(item.isMine);
checkShowPublic() {
return checkPolicyRule('manila:share:set_public_share');
}
get formItems() { get formItems() {
return [ return [
@ -54,6 +59,7 @@ export class Edit extends ModalAction {
type: 'check', type: 'check',
content: t('Public'), content: t('Public'),
tip: t('If set then all tenants will be able to see this share.'), tip: t('If set then all tenants will be able to see this share.'),
display: this.checkShowPublic(),
}, },
]; ];
} }
@ -64,7 +70,14 @@ export class Edit extends ModalAction {
onSubmit = (values) => { onSubmit = (values) => {
const { id } = this.item; const { id } = this.item;
return this.store.update(id, values); const { is_public, ...rest } = values;
const body = {
...rest,
};
if (this.checkShowPublic()) {
body.is_public = is_public;
}
return this.store.update(id, body);
}; };
} }

View File

@ -36,7 +36,7 @@ export class ExtendShare extends ModalAction {
static policy = 'manila:share:extend'; static policy = 'manila:share:extend';
static allowed = () => Promise.resolve(true); static allowed = (item) => Promise.resolve(item.isMine);
get tips() { get tips() {
return t('After the share is expanded, the share cannot be reduced.'); return t('After the share is expanded, the share cannot be reduced.');

View File

@ -38,7 +38,7 @@ export class ManageAccessRule extends FormAction {
static policy = 'manila:share_access_rule:index'; static policy = 'manila:share_access_rule:index';
static allowed = () => Promise.resolve(true); static allowed = (item) => Promise.resolve(item.isMine);
} }
export default inject('rootStore')(observer(ManageAccessRule)); export default inject('rootStore')(observer(ManageAccessRule));

View File

@ -38,7 +38,7 @@ export class ManageMetadata extends FormAction {
static policy = 'manila:share:update_share_metadata'; static policy = 'manila:share:update_share_metadata';
static allowed = () => Promise.resolve(true); static allowed = (item) => Promise.resolve(item.isMine);
} }
export default inject('rootStore')(observer(ManageMetadata)); export default inject('rootStore')(observer(ManageMetadata));

View File

@ -20,7 +20,7 @@ import actionConfigs from './actions';
export class Share extends Base { export class Share extends Base {
init() { init() {
this.store = globalShareStore; this.store = this.inDetailPage ? new ShareStore() : globalShareStore;
this.downloadStore = new ShareStore(); this.downloadStore = new ShareStore();
} }
@ -56,6 +56,14 @@ export class Share extends Base {
return this.inDetailPage && pathname.includes('share-server'); return this.inDetailPage && pathname.includes('share-server');
} }
get isSortByBackend() {
return true;
}
get defaultSortKey() {
return 'created_at';
}
updateFetchParamsByPage = (params) => { updateFetchParamsByPage = (params) => {
const { id, ...rest } = params; const { id, ...rest } = params;
const newParams = { ...rest }; const newParams = { ...rest };
@ -92,20 +100,24 @@ export class Share extends Base {
dataIndex: 'project_name', dataIndex: 'project_name',
isHideable: true, isHideable: true,
hidden: !this.isAdminPage, hidden: !this.isAdminPage,
sortKey: 'project_id',
}, },
{ {
title: t('Description'), title: t('Description'),
dataIndex: 'description', dataIndex: 'description',
isHideable: true, isHideable: true,
sorter: false,
}, },
{ {
title: t('Availability Zone'), title: t('Availability Zone'),
dataIndex: 'availability_zone', dataIndex: 'availability_zone',
sorter: false,
}, },
{ {
title: t('Share Type'), title: t('Share Type'),
dataIndex: 'share_type_name', dataIndex: 'share_type_name',
render: (value, record) => value || record.share_type, render: (value, record) => value || record.share_type,
sortKey: 'share_type_id',
}, },
{ {
title: t('Size'), title: t('Size'),
@ -122,6 +134,7 @@ export class Share extends Base {
dataIndex: 'is_public', dataIndex: 'is_public',
isHideable: true, isHideable: true,
valueRender: 'yesNo', valueRender: 'yesNo',
sorter: false,
}, },
{ {
title: t('Status'), title: t('Status'),
@ -155,6 +168,7 @@ export class Share extends Base {
}); });
return link; return link;
}, },
// sorter: false,
}, },
{ {
title: t('Created At'), title: t('Created At'),

View File

@ -59,11 +59,6 @@ export class Detail extends Base {
dataIndex: 'created_at', dataIndex: 'created_at',
valueRender: 'toLocalTime', valueRender: 'toLocalTime',
}, },
{
title: t('Updated'),
dataIndex: 'updated_at',
valueRender: 'toLocalTime',
},
]; ];
} }

View File

@ -41,6 +41,14 @@ export class ShareGroup extends Base {
return true; return true;
} }
get isSortByBackend() {
return true;
}
get defaultSortKey() {
return 'created_at';
}
get actionConfigs() { get actionConfigs() {
return this.isAdminPage return this.isAdminPage
? actionConfigs.actionConfigsAdmin ? actionConfigs.actionConfigsAdmin

View File

@ -17,15 +17,18 @@ export const getShareGroupColumns = (self) => {
dataIndex: 'project_name', dataIndex: 'project_name',
isHideable: true, isHideable: true,
hidden: !self.isAdminPage, hidden: !self.isAdminPage,
sortKey: 'project_id',
}, },
{ {
title: t('Description'), title: t('Description'),
dataIndex: 'description', dataIndex: 'description',
isHideable: true, isHideable: true,
sorter: false,
}, },
{ {
title: t('Availability Zone'), title: t('Availability Zone'),
dataIndex: 'availability_zone', dataIndex: 'availability_zone',
sorter: false,
}, },
{ {
title: t('Share Network'), title: t('Share Network'),

View File

@ -60,3 +60,15 @@ export const shareAccessRuleState = {
denying: t('Denying'), denying: t('Denying'),
applying: t('Applying'), applying: t('Applying'),
}; };
export const shareAccessLevel = {
rw: t('Read and write'),
ro: t('Read only'),
};
export const shareAccessType = {
ip: t('IP'),
cert: t('Cert'),
user: t('User'),
cephx: t('Cephx'),
};

View File

@ -37,6 +37,13 @@ export class ShareGroupStore extends Base {
}; };
} }
updateParamsSortPage = (params, sortKey, sortOrder) => {
if (sortKey && sortOrder) {
params.sort_key = sortKey;
params.sort_dir = sortOrder === 'descend' ? 'desc' : 'asc';
}
};
async detailDidFetch(item, all_projects) { async detailDidFetch(item, all_projects) {
const { share_network_id, share_group_type_id, share_types } = item; const { share_network_id, share_group_type_id, share_types } = item;
const shareGroupType = await new ShareGroupTypeStore().fetchDetail({ const shareGroupType = await new ShareGroupTypeStore().fetchDetail({

View File

@ -73,10 +73,28 @@ export class ShareStore extends Base {
all_tenants: all_projects ? 1 : 0, all_tenants: all_projects ? 1 : 0,
offset: marker, offset: marker,
limit, limit,
is_public: true,
}; };
}; };
} }
get mapper() {
return (data) => {
const { project_id } = data;
return {
...data,
isMine: project_id === this.currentProjectId,
};
};
}
updateParamsSortPage = (params, sortKey, sortOrder) => {
if (sortKey && sortOrder) {
params.sort_key = sortKey;
params.sort_dir = sortOrder === 'descend' ? 'desc' : 'asc';
}
};
@action @action
async fetchAvailableZones() { async fetchAvailableZones() {
const { availability_zones: zones = [] } = await this.zoneClient.list(); const { availability_zones: zones = [] } = await this.zoneClient.list();