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:
parent
020defa50b
commit
3643ca912c
@ -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() {
|
||||||
|
@ -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'),
|
||||||
|
@ -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() {
|
||||||
|
@ -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',
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.');
|
||||||
|
@ -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));
|
||||||
|
@ -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));
|
||||||
|
@ -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'),
|
||||||
|
@ -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',
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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'),
|
||||||
|
@ -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'),
|
||||||
|
};
|
||||||
|
@ -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({
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user