![xusongfu](/assets/img/avatar_default.png)
Add alias policy introduction to document Change-Id: I1e0ee2026173c6d6b588adea74ed8823a37eac7b
402 lines
14 KiB
Markdown
402 lines
14 KiB
Markdown
English | [简体中文](../../zh/develop/3-7-ModalAction-introduction.md)
|
||
|
||
# Usage
|
||
|
||
![Modal Form](../../zh/develop/images/form/modal.png)
|
||
|
||
- After click the action button, the form modal will display.
|
||
- After click the `Confirm` button, the `loading` status will be displayed according to the status of request.
|
||
- After click the `Cancel` button, the modal form will disappear.
|
||
- If the request is sent successfully, a prompt message of successful action will be displayed in the upper right corner, and it will automatically disappear after a few seconds.
|
||
- If the request fails, an error message will be displayed in the upper right corner of the form page, which can only disappear after clicking the close button.
|
||
- Support batch action, after selecting multiple items in the table, you can click the action button above the table to perform batch action.
|
||
|
||
# ModalAction code file
|
||
|
||
- `src/containers/Action/ModalAction/index.jsx`
|
||
|
||
# ModalAction attribute and function definitions introduction
|
||
|
||
- Modal forms are all inherited from `ModalAction` component
|
||
- Code location: `pages/xxxx/containers/XXXX/actions/xxx.jsx`
|
||
- For the case where the form item is relatively less, the modal form is usually used
|
||
- Only need to override some functions and the development of page will be completed
|
||
- Attributes and functions are divided into the following four types:
|
||
- The attributes and functions that must be override, mainly include:
|
||
- Action ID
|
||
- Action title
|
||
- Action permissions
|
||
- Judgment whether to disable the action button
|
||
- Form Item config
|
||
- Function to send request
|
||
- The attributes and functions that override in need, mainly include:
|
||
- Form default value
|
||
- Form size
|
||
- Form's label & content layout
|
||
- Whether it is an asynchronous action
|
||
- Resource name
|
||
- Whether to display the resource name in the prompt of the request result
|
||
- Action button text
|
||
- The attributes and functions that do not need to be override, mainly include:
|
||
- Whether the current page is a admin page
|
||
- The basic functions in the parent class, mainly include:
|
||
- Render page
|
||
- Display of request status
|
||
- Display of request results
|
||
- See below for a more detailed and comprehensive introduction
|
||
|
||
## The attributes and functions that must be override
|
||
|
||
- `id`
|
||
- Static
|
||
- Resource action ID
|
||
- Need to be unique, only for all actions in the `actions` of the resource to be unique
|
||
- Must be override
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
static id = 'attach-volume';
|
||
```
|
||
|
||
- `title`
|
||
- Static
|
||
- Resource action title
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
static title = t('Attach Volume');
|
||
```
|
||
|
||
- `name`
|
||
- Resource action name
|
||
- Use the name in the prompt after the request
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
get name() {
|
||
return t('Attach volume');
|
||
}
|
||
```
|
||
|
||
- `policy`
|
||
- Static (Fill in the policy that complies with the openstack rules here)
|
||
- Action permission, if the permission verify failed, the action button will not be displayed on the resource list page
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
static policy = 'os_compute_api:os-volumes-attachments:create';
|
||
```
|
||
|
||
- `aliasPolicy`
|
||
- Static (Fill in the custom policy with module prefix here)
|
||
- Action permission, if the permission verify failed, the action button will not be displayed on the resource list page
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
static aliasPolicy = 'nova:os_compute_api:os-volumes-attachments:create';
|
||
```
|
||
|
||
- `allowed`
|
||
- Static
|
||
- Determine whether the action button needs to be disabled
|
||
- Return `Promise`
|
||
- Button that no need to be disabled, write directly:
|
||
|
||
```javascript
|
||
static allowed() {
|
||
return Promise.resolve(true);
|
||
}
|
||
```
|
||
|
||
- Param `item`, the item data in the resource list is generally used to determine the action of the item in the resource list.
|
||
- Param `containerProps`, parent container's (That is, the resource list page where the button is located) `props` attribute, generally used to determine the action of related resources under the details page.
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
- The admin page does not display the action button
|
||
- The button will show when the server is not: active / deleting / locked / ironic
|
||
|
||
```javascript
|
||
static allowed = (item, containerProps) => {
|
||
const { isAdminPage } = containerProps;
|
||
return Promise.resolve(
|
||
!isAdminPage &&
|
||
isActive(item) &&
|
||
isNotDeleting(item) &&
|
||
isNotLocked(item) &&
|
||
!isIronicInstance(item)
|
||
);
|
||
};
|
||
```
|
||
|
||
- `formItems`
|
||
- The form item configuration list corresponding to the action
|
||
- The configuration of each form item can be referred to [3-10-FormItem introduction](3-10-FormItem-introduction.md)
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
- Form items includes: instance name label, volume selector
|
||
|
||
```javascript
|
||
get formItems() {
|
||
return [
|
||
{
|
||
name: 'instance',
|
||
label: t('Instance'),
|
||
type: 'label',
|
||
iconType: 'instance',
|
||
},
|
||
{
|
||
name: 'volume',
|
||
label: t('Volume'),
|
||
type: 'volume-select-table',
|
||
tip: multiTip,
|
||
isMulti: false,
|
||
required: true,
|
||
serverId: this.item.id,
|
||
disabledFunc: (record) => {
|
||
const diskFormat = _get(
|
||
record,
|
||
'origin_data.volume_image_metadata.disk_format'
|
||
);
|
||
return diskFormat === 'iso';
|
||
},
|
||
},
|
||
];
|
||
}
|
||
```
|
||
|
||
- `onSubmit`
|
||
- The request function of the action
|
||
- After the action request is successful, the modal will disappear, and a successful prompt will be displayed, and the prompt will disappear after a few seconds
|
||
- After the action fails, the modal will disappear and an error message will be displayed. You need to close the prompt manually before the prompt disappears.
|
||
- Return `Promise`.
|
||
- Return the function in the `store` that corresponding to the form.
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
onSubmit = (values) => {
|
||
const { volume } = values;
|
||
const { id } = this.item;
|
||
const volumeId = volume.selectedRowKeys[0];
|
||
const body = {
|
||
volumeAttachment: {
|
||
volumeId,
|
||
},
|
||
};
|
||
return this.store.attachVolume({ id, body });
|
||
};
|
||
```
|
||
|
||
## The attributes and functions that override in need
|
||
|
||
- `init`
|
||
- Initial operation
|
||
- Defines `this.store` in it, `loading` status is based on `this.store.isSubmitting`
|
||
- Call the function to obtain other data required by the form in it
|
||
- Update attributes in `this.state` .
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
- Defines the corresponding `store` for the action
|
||
|
||
```javascript
|
||
init() {
|
||
this.store = globalServerStore;
|
||
}
|
||
```
|
||
|
||
- `defaultValue`
|
||
- The initial value of the form
|
||
- Default value is `{}`
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx`为例
|
||
- Set the initial value of the server name in the form
|
||
|
||
```javascript
|
||
get defaultValue() {
|
||
const { name } = this.item;
|
||
const value = {
|
||
instance: name,
|
||
};
|
||
return value;
|
||
}
|
||
```
|
||
|
||
- `nameForStateUpdate`
|
||
- Update key-value into `this.state` when form item value changed
|
||
- The key-value stored in `this.state` often affect the display of form items, generally need to be used with `get formItems`
|
||
- Such as expand and hide more configuration items
|
||
- Such as the `required` attribute change of some form items
|
||
- By default, the change of form item which `type` is `radio` or `more` will automaticly save to `this.state`
|
||
- Take attach interface to instance as an example `src/pages/compute/containers/Instance/actions/AttachInterface.jsx` :
|
||
- After select network in the form, the content of the subnet list will be updated
|
||
- However, after select the subnet in the form, the judgment of the input IP will be updated, etc.
|
||
|
||
```javascript
|
||
get nameForStateUpdate() {
|
||
return ['network', 'ipType', 'subnet'];
|
||
}
|
||
```
|
||
|
||
- `instanceName`
|
||
- After the request is sent, the resource name in the prompt message
|
||
- Default is `this.values.name`
|
||
- Take edit fip as an example `src/pages/network/containers/FloatingIp/actions/Edit.jsx` :
|
||
- The prompt name is the address of the floating IP
|
||
|
||
```javascript
|
||
get instanceName() {
|
||
return this.item.floating_ip_address;
|
||
}
|
||
```
|
||
|
||
- `isAsyncAction`
|
||
- Whether the current action is an asynchronous action
|
||
- Default is `false`
|
||
- If is asynchronous action, the prompt will be : `The xxx instruction has been issued, instance: xxx. \n You can wait for a few seconds to follow the changes of the list data or manually refresh the data to get the final display result.`
|
||
- If is synchronous action, the prompt will be : `xxx successfully, instance: xxx.`
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
|
||
```javascript
|
||
get isAsyncAction() {
|
||
return true;
|
||
}
|
||
```
|
||
|
||
- `messageHasItemName`
|
||
- Whether to include the instance name in the prompt of the request result
|
||
- Default is `true`
|
||
- For some resources without `name` attribute, you can set the value `false`
|
||
- Take create snat as an example `src/pages/network/containers/Router/Snat/actions/Create.jsx` :
|
||
|
||
```javascript
|
||
get messageHasItemName() {
|
||
return false;
|
||
}
|
||
```
|
||
|
||
- `buttonText`
|
||
- Static
|
||
- When the text on the action button is inconsistent with the title of the modal, this attribute needs to be override
|
||
- Take edit image as an example `src/pages/compute/containers/Image/actions/Edit.jsx` :
|
||
|
||
```javascript
|
||
static buttonText = t('Edit');
|
||
```
|
||
|
||
- `buttonType`
|
||
- Static
|
||
- The type of button, support `primary`, `default`, `link`
|
||
|
||
- `isDanger`
|
||
- Static
|
||
- Support boolean `false`, `true`, the default value is `false`
|
||
- When the button is to emphasize the risk of action, the button or the text on the button is generally red, use `true`
|
||
- As the example of disable cinder service`src/pages/configuration/containers/SystemInfo/CinderService/actions/Disable.jsx` :
|
||
|
||
```javascript
|
||
static isDanger = true;
|
||
```
|
||
|
||
- `modalSize`
|
||
- Static
|
||
- Identifies the width of the modal: the value is`small`、`middle`、`large`
|
||
- The correspondence between value and width is :
|
||
- `small`: 520
|
||
- `middle`: 720
|
||
- `large`: 1200
|
||
- Use with `getModalSize`
|
||
- Default is `small`, means the width of modal is 520px
|
||
|
||
```javascript
|
||
static get modalSize() {
|
||
return 'small';
|
||
}
|
||
```
|
||
|
||
- Take attach volume as an example `src/pages/compute/containers/Instance/actions/AttachVolume.jsx` :
|
||
- the size of modal is `large`
|
||
|
||
```javascript
|
||
static get modalSize() {
|
||
return 'large';
|
||
}
|
||
|
||
getModalSize() {
|
||
return 'large';
|
||
}
|
||
```
|
||
|
||
- `getModalSize`
|
||
- Identifies the width of the modal
|
||
- The value is`small`、`middle`、`large`
|
||
|
||
- `labelCol`
|
||
- Configure the layout of the labels on the left side of the form
|
||
- Default is :
|
||
|
||
```javascript
|
||
get labelCol() {
|
||
const size = this.getModalSize();
|
||
if (size === 'large') {
|
||
return {
|
||
xs: { span: 6 },
|
||
sm: { span: 4 },
|
||
};
|
||
}
|
||
return {
|
||
xs: { span: 8 },
|
||
sm: { span: 6 },
|
||
};
|
||
}
|
||
```
|
||
|
||
- Take edit domain as an example `src/pages/identity/containers/Domain/actions/Edit.jsx` :
|
||
|
||
```javascript
|
||
get labelCol() {
|
||
return {
|
||
xs: { span: 6 },
|
||
sm: { span: 5 },
|
||
};
|
||
}
|
||
```
|
||
|
||
- `wrapperCol`
|
||
- Configure the layout of the content on the right side of the form
|
||
- Default is :
|
||
|
||
```javascript
|
||
get wrapperCol() {
|
||
return {
|
||
xs: { span: 16 },
|
||
sm: { span: 16 },
|
||
};
|
||
}
|
||
```
|
||
|
||
- Take manage metadata of flavor as an example `src/pages/compute/containers/Flavor/actions/ManageMetadata.jsx` :
|
||
|
||
```javascript
|
||
get wrapperCol() {
|
||
return {
|
||
xs: { span: 18 },
|
||
sm: { span: 20 },
|
||
};
|
||
}
|
||
```
|
||
|
||
## The attributes and functions that do not need to be override
|
||
|
||
- `isAdminPage`
|
||
- Whether current page is a "management platform" page
|
||
- `successText`
|
||
- Successful prompt generated after the request
|
||
- `errorText`
|
||
- Error prompt generated after the request fails
|
||
- `containerProps`
|
||
- Get the `props` of the father component of the button
|
||
- `item`
|
||
- Get the data of the item that the action corresponding to
|
||
- `items`
|
||
- Get the data corresponding to the batch action
|
||
|
||
## The basic functions in the parent class
|
||
|
||
- `ModalAction` extends `BaseForm`
|
||
- Recommend to see `src/components/Form/index.jsx`
|