Skip to content
Snippets Groups Projects
Commit e568f87f authored by Ryo Yamashita's avatar Ryo Yamashita Committed by Yas Naoi
Browse files

Issue #3309165 by Ryo Yamashita, yas: Add a delete function for the Cloud...

Issue #3309165 by Ryo Yamashita, yas: Add a delete function for the Cloud launch template list in SPA
parent d2744ee5
No related branches found
Tags 8.x-1.0-alpha1
No related merge requests found
......@@ -134,6 +134,21 @@ entity.cloud_config.geocoder:
# Public access.
_access: 'TRUE'
# Cloud launch template REST API
entity.cloud_launch_template.delete:
path: '/cloud_dashboard/{cloud_service_provider}/{cloud_context}/cloud_launch_template/{entity_id}/delete'
defaults:
_controller: '\Drupal\cloud\Controller\ApiController::operateEntity'
entity_type_id: cloud_launch_template
command: delete
methods: [POST]
requirements:
# Use custom access that will check for cloud_context and the desired permission.
# Desired permission is passed as an option in the "perm" variable
_custom_access: '\Drupal\cloud\Controller\CloudConfigController::access'
options:
perm: 'edit any cloud server templates+edit own cloud server templates'
# Cloud project entity view route
entity.cloud_project.canonical:
path: '/clouds/design/project/{cloud_context}/{cloud_project}'
......
......@@ -9,14 +9,15 @@ import AWS_CLOUD_SECURITY_GROUP_TEMPLATE from 'constant/form_template/aws_cloud/
import AWS_CLOUD_SNAPSHOT from 'constant/form_template/aws_cloud/snapshot';
import AWS_CLOUD_SUBNET_TEMPLATE from 'constant/form_template/aws_cloud/subnet';
import AWS_CLOUD_TRANSIT_GATEWAY_TEMPLATE from 'constant/form_template/aws_cloud/transit_gateway';
import AWS_CLOUD_VOLUME_TEMPLATE from 'constant/form_template/aws_cloud/volume';
import AWS_CLOUD_VPC_TEMPLATE from 'constant/form_template/aws_cloud/vpc';
import AWS_CLOUD_VPC_PEERING_CONNECTION from "constant/form_template/aws_cloud/vpc_peering_connection";
import AWS_CLOUD_VOLUME_TEMPLATE from "constant/form_template/aws_cloud/volume";
import AWS_CLOUD_VPC_PEERING_CONNECTION from 'constant/form_template/aws_cloud/vpc_peering_connection';
import K8S_DEPLOYMENT_TEMPLATE from 'constant/form_template/k8s/deployment';
import K8S_NAMESPACE_TEMPLATE from 'constant/form_template/k8s/namespace';
import K8S_OTHER_TEMPLATE from 'constant/form_template/k8s/other';
import K8S_POD_TEMPLATE from 'constant/form_template/k8s/pod';
import K8S_SCHEDULE_TEMPLATE from 'constant/form_template/k8s/schedule';
import AWS_CLOUD_LAUNCH_TEMPLATE from 'constant/form_template/launch_template/aws_cloud';
import OPENSTACK_FLOATING_IP_TEMPLATE from 'constant/form_template/openstack/floating_ip';
import OPENSTACK_IMAGE_TEMPLATE from 'constant/form_template/openstack/image';
import OPENSTACK_INSTANCE_TEMPLATE from 'constant/form_template/openstack/instance';
......@@ -57,6 +58,7 @@ const ENTITY_FORM_LIST = [
...OPENSTACK_SNAPSHOT_TEMPLATE,
...OPENSTACK_VOLUME_TEMPLATE,
...VMWARE_VM_TEMPLATE,
...AWS_CLOUD_LAUNCH_TEMPLATE,
];
export default ENTITY_FORM_LIST;
import EntityFormTemplate from 'model/EntityFormTemplate';
const AWS_CLOUD_LAUNCH_TEMPLATE: EntityFormTemplate[] = [
{
cloudServiceProvider: 'aws_cloud',
entityName: 'cloud_launch_template',
actionType: 'delete',
entityRecords: [
{
type: 'label',
text: 'Are you sure you want to delete the {{name}} Cloud Launch Template?'
},
],
submitButtonLabel: 'Delete'
},
]
export default AWS_CLOUD_LAUNCH_TEMPLATE;
import { ROUTE_URL } from 'constant/other';
import CloudContext from 'model/CloudContext';
import DataColumn from 'model/DataColumn';
import DataRecord from 'model/DataRecord';
import DataTableData from 'molecules/DataTableData';
import { useContext } from 'react';
import { ButtonGroup, Dropdown } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
import { AppContext } from 'service/state';
/**
* Wrapper of DataTableData.
......@@ -151,13 +154,22 @@ const getOperations = (dataRecord: DataRecord): string[] => {
*
* @param dataRecord Data record of the element.
* @param action Type of CxUD.
* @param cloudContextList CloudContext list.
*/
const updateAndDeleteData = (dataRecord: DataRecord, action: string) => {
const updateAndDeleteData = (dataRecord: DataRecord, action: string, cloudContextList: CloudContext[]) => {
let urlParts = dataRecord.entityTypeId;
const modules = ['aws_cloud', 'k8s', 'openstack', 'vmware'];
for (const module of modules) {
urlParts = urlParts.replace(`${module}_`, `${module}/${dataRecord.cloudContext}/`);
}
if (dataRecord.entityTypeId === 'cloud_launch_template') {
const moduleList = cloudContextList.filter((c) => {
return c.name === dataRecord.cloudContext;
});
if (moduleList.length >= 1) {
urlParts = urlParts.replace(`${dataRecord.entityTypeId}`, `${moduleList[0].cloudServiceProvider}/${dataRecord.cloudContext}/${dataRecord.entityTypeId}`);
}
}
window.location.href = `${ROUTE_URL}/${urlParts}/${dataRecord.id}/${action}`;
}
......@@ -180,6 +192,7 @@ const DataTableRowWithOperationLinks = ({ dataRecord, dataColumnList, className,
},
}) => {
const { cloudContextList } = useContext(AppContext);
const { t } = useTranslation();
if (['k8s_node', 'k8s_event'].includes(dataRecord.entityTypeId)) {
......@@ -210,7 +223,7 @@ const DataTableRowWithOperationLinks = ({ dataRecord, dataColumnList, className,
<Dropdown as={ButtonGroup} className="custom-dropdown">
<button type="button" className="dropdown-toggle links ripple-effect" onClick={(e) => {
e.preventDefault();
updateAndDeleteData(dataRecord, 'edit');
updateAndDeleteData(dataRecord, 'edit', cloudContextList);
}}>{t('Edit')}</button>
<button type="button" className="uparrow" data-bs-toggle="dropdown" aria-expanded="false">
......@@ -231,7 +244,7 @@ const DataTableRowWithOperationLinks = ({ dataRecord, dataColumnList, className,
{/* eslint-disable-next-line */}
<a href="#" onClick={(e) => {
e.preventDefault();
updateAndDeleteData(dataRecord, 'delete');
updateAndDeleteData(dataRecord, 'delete', cloudContextList);
}}>
<span className="delete glyphicon glyphicon-"></span>
{t('Delete')}
......@@ -252,10 +265,10 @@ const DataTableRowWithOperationLinks = ({ dataRecord, dataColumnList, className,
// becomes part of the URL in CxUD. If it does not match,
// set it individually with a switch-case statement.
case 'Start':
updateAndDeleteData(dataRecord, 'start');
updateAndDeleteData(dataRecord, 'start', cloudContextList);
break;
default:
updateAndDeleteData(dataRecord, menuInfo.toLowerCase().replaceAll(' ', '_'));
updateAndDeleteData(dataRecord, menuInfo.toLowerCase().replaceAll(' ', '_'), cloudContextList);
break;
}
}}>
......
......@@ -48,8 +48,13 @@ const EntityXxudPageImpl = ({ cloudContext, entityFormTemplate, entityName, enti
}, [formData]);
const initEntity = async () => {
const entityTypeId = `${entityFormTemplate.cloudServiceProvider}_${entityName}`;
const url = `/jsonapi/${entityTypeId}/${entityTypeId}?filter[drupal_internal__id]=${entityId}`;
let url = '';
if (entityName !== "cloud_launch_template") {
const entityTypeId = `${entityFormTemplate.cloudServiceProvider}_${entityName}`;
url = `/jsonapi/${entityTypeId}/${entityTypeId}?filter[drupal_internal__id]=${entityId}`;
} else {
url = `/jsonapi/cloud_launch_template/${entityFormTemplate.cloudServiceProvider}?filter[drupal_internal__id]=${entityId}`;
}
const rawEntityData = await getJsonData<{ data: EntityData[] }>(url);
if (rawEntityData.data.length >= 1) {
setEntityData(rawEntityData.data[0]);
......@@ -150,7 +155,9 @@ const EntityXxudPageImpl = ({ cloudContext, entityFormTemplate, entityName, enti
}
const save = async () => {
const url = `/cloud_dashboard/${entityFormTemplate.cloudServiceProvider}/${cloudContext}/${entityFormTemplate.cloudServiceProvider}_${entityName}/${entityId}/${entityFormTemplate.actionType}`;
const url = entityName !== 'cloud_launch_template'
? `/cloud_dashboard/${entityFormTemplate.cloudServiceProvider}/${cloudContext}/${entityFormTemplate.cloudServiceProvider}_${entityName}/${entityId}/${entityFormTemplate.actionType}`
: `/cloud_dashboard/${entityFormTemplate.cloudServiceProvider}/${cloudContext}/${entityName}/${entityId}/${entityFormTemplate.actionType}`;
const response = await fetch(url, {
method: 'POST',
......
<?php
namespace Drupal\cloud\Controller;
use Drupal\cloud\Traits\CloudContentEntityTrait;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityDeleteFormTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* Controller responsible for "update" URLs.
*
* This class is mainly responsible for updating the entities from URLs.
*/
class ApiController extends ControllerBase implements ApiControllerInterface {
use CloudContentEntityTrait;
use EntityDeleteFormTrait;
/**
* The entity used by this form.
*
* @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\Core\Entity\RevisionLogInterface
*/
private $entity;
/**
* Drupal\Core\Entity\EntityTypeManagerInterface definition.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* ApiController constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager
) {
$this->entityTypeManager = $entity_type_manager;
}
/**
* Dependency Injection.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* Instance of ContainerInterface.
*
* @return ApiController
* return created object.
*/
public static function create(ContainerInterface $container): ApiController {
return new static(
$container->get('entity_type.manager'),
);
}
/**
* Gets the entity of this form.
*
* Provided by \Drupal\Core\Entity\EntityForm.
*
* @return \Drupal\Core\Entity\EntityInterface
* The entity.
*/
public function getEntity(): EntityInterface {
return $this->entity;
}
/**
* {@inheritdoc}
*/
public function operateEntity(Request $request, string $cloud_service_provider, string $cloud_context, string $entity_type_id, string $entity_id, string $command): JsonResponse {
// Create an instance of the entity.
// The process splits between adding a new entity and when reading an
// existing entity.
/** @var \Drupal\cloud\Entity\CloudLaunchTemplateInterface $entity */
$entity = $command !== 'create'
? $this->entityTypeManager
->getStorage($entity_type_id)
->load($entity_id)
: $this->entityTypeManager
->getStorage($entity_type_id)
->create([
'cloud_context' => $cloud_context,
]);
if (empty($entity)) {
return new JsonResponse([
'result' => 'NG',
'reason' => 'The entity has already been deleted.',
], 404);
}
try {
$this->entity = $entity;
$entity->delete();
$this->messenger->addStatus($this->getDeletionMessage());
$this->logDeletionMessage();
// Clear block and menu cache.
$this->clearCacheValues($this->entity->getCacheTags());
return new JsonResponse([
'result' => 'OK',
], 200);
}
catch (\Exception $e) {
$this->handleException($e);
return new JsonResponse([
'result' => 'NG',
'reason' => 'Internal Server Error',
], 500);
}
}
}
<?php
namespace Drupal\cloud\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
/**
* {@inheritdoc}
*/
interface ApiControllerInterface {
/**
* Operate OpenStack entity.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* HTTP request.
* @param string $cloud_service_provider
* The cloud service provider.
* @param string $cloud_context
* The cloud context.
* @param string $entity_type_id
* The entity type ID.
* @param string $entity_id
* The entity ID.
* @param string $command
* Operation command.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* The JSON response.
*/
public function operateEntity(Request $request, string $cloud_service_provider, string $cloud_context, string $entity_type_id, string $entity_id, string $command): JsonResponse;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment