diff --git a/config.ts b/config.ts index 7ebf8a53..f8096148 100644 --- a/config.ts +++ b/config.ts @@ -176,7 +176,7 @@ const conf: Config = { ], // The number of items per page applicable to main lists: - // replicas, migrations, endpoints, users etc. + // transfers, deployments, endpoints, users etc. mainListItemsPerPage: 20, maxMinionPoolEventsPerPage: 50, diff --git a/cypress/e2e/dashboard/dashboard.cy.ts b/cypress/e2e/dashboard/dashboard.cy.ts index 9cc1c678..403e7efb 100644 --- a/cypress/e2e/dashboard/dashboard.cy.ts +++ b/cypress/e2e/dashboard/dashboard.cy.ts @@ -58,7 +58,7 @@ describe("Dashboard", () => { cy.get("*[class^='DashboardLicence__ChartHeaderCurrent']").should( "contain.text", - `${applianceStatus.appliance_licence_status.current_performed_replicas} Used Replica ${applianceStatus.appliance_licence_status.current_performed_migrations} Used Migrations` + `${applianceStatus.appliance_licence_status.current_performed_replicas} Fulfilled Replica ${applianceStatus.appliance_licence_status.current_performed_migrations} Fulfilled Migrations` ); }); diff --git a/jest.config.ts b/jest.config.ts index 9adf0b6d..ee7b1c48 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -22,7 +22,6 @@ export default { // An array of glob patterns indicating a set of files for which coverage information should be collected collectCoverageFrom: [ "**/*.tsx", // Include all .tsx files - "!**/AssessmentModule/**", // Exclude files within the AssessmentModule directory (this is a module that is not used in the app) "!**/story.tsx", // Exclude all storybook files "!**/test.tsx", // Exclude old test files "!**/plugins/**", // Exclude files within the plugins directory diff --git a/src/@types/Assessment.ts b/src/@types/Assessment.ts deleted file mode 100644 index ea13eaa8..00000000 --- a/src/@types/Assessment.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (C) 2017 Cloudbase Solutions SRL -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -import type { Endpoint } from "./Endpoint"; -import type { Instance } from "./Instance"; -import type { NetworkMap } from "./Network"; - -export type VmSize = { - name: string; - size?: string; -}; - -export type AzureLocation = { - id: string; - name: string; -}; - -export type Group = { - id: string; - name: string; -}; - -export type VmItem = { - id: string; - properties: { - recommendedSize: string; - disks: { - [diskName: string]: { - recommendedDiskType: string; - }; - }; - datacenterManagementServerName: string; - datacenterMachineArmId: string; - displayName: string; - operatingSystemName: string; - }; -}; - -export type Assessment = { - name: string; - id: string; - projectName: string; - resourceGroupName: string; - groupName: string; - assessmentName: string; - location: string; - project: { - name: string; - }; - group: Group; - properties: { - status: string; - updatedTimestamp: string; - azureLocation: string; - numberOfMachines: string; - }; - connectionInfo: { subscription_id: string } & Endpoint["connection_info"]; -}; - -export type MigrationInfo = { - source: Endpoint | null; - target: Endpoint; - selectedInstances: Instance[]; - fieldValues: { [fieldValue: string]: any }; - networks: NetworkMap[]; - vmSizes: { [vmSize: string]: VmSize }; -}; diff --git a/src/@types/Execution.ts b/src/@types/Execution.ts index 47283734..be6e4de8 100644 --- a/src/@types/Execution.ts +++ b/src/@types/Execution.ts @@ -22,10 +22,10 @@ export type Execution = { updated_at: string; deleted_at?: string; type: - | "replica_execution" - | "replica_disks_delete" - | "replica_deploy" - | "replica_update"; + | "transfer_execution" + | "transfer_disks_delete" + | "transfer_deploy" + | "transfer_update"; }; export type ExecutionTasks = Execution & { diff --git a/src/@types/MainItem.ts b/src/@types/MainItem.ts index 92d13a34..bd7c442f 100644 --- a/src/@types/MainItem.ts +++ b/src/@types/MainItem.ts @@ -83,7 +83,7 @@ type BaseItem = { destination_environment: { [prop: string]: any }; source_environment: { [prop: string]: any }; transfer_result: { [prop: string]: Instance } | null; - replication_count?: number; + // replication_count?: number; storage_mappings?: StorageMapping | null; network_map?: TransferNetworkMap; last_execution_status: string; @@ -92,8 +92,9 @@ type BaseItem = { user_scripts?: UserScriptData; }; -export type ReplicaItem = BaseItem & { - type: "replica"; +export type TransferItem = BaseItem & { + type: "transfer"; + scenario: string; }; export type UserScriptData = { @@ -106,29 +107,30 @@ export type UserScriptData = { }; }; -export type MigrationItem = BaseItem & { - type: "migration"; - replica_id?: string; +export type DeploymentItem = BaseItem & { + type: "deployment"; + transfer_id: string; + transfer_scenario: string; }; -export type MigrationItemOptions = MigrationItem & { +export type DeploymentItemOptions = DeploymentItem & { skip_os_morphing: boolean; shutdown_instances: boolean; }; -export type TransferItem = ReplicaItem | MigrationItem; +export type ActionItem = TransferItem | DeploymentItem; -export type ReplicaItemDetails = ReplicaItem & { +export type TransferItemDetails = TransferItem & { executions: Execution[]; }; -export type MigrationItemDetails = MigrationItem & { +export type DeploymentItemDetails = DeploymentItem & { tasks: Task[]; }; -export type TransferItemDetails = ReplicaItemDetails | MigrationItemDetails; +export type ActionItemDetails = TransferItemDetails | DeploymentItemDetails; -export const getTransferItemTitle = (item: TransferItem | null) => { +export const getTransferItemTitle = (item: ActionItem | null) => { if (!item) { return null; } diff --git a/src/@types/Schedule.ts b/src/@types/Schedule.ts index d2010983..213bdc8f 100644 --- a/src/@types/Schedule.ts +++ b/src/@types/Schedule.ts @@ -31,6 +31,6 @@ export type Schedule = { }; export type ScheduleBulkItem = { - replicaId: string; + transferId: string; schedules: Schedule[]; }; diff --git a/src/components/App.tsx b/src/components/App.tsx index 1213648b..29e73f96 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -21,16 +21,14 @@ import { observe } from "mobx"; import Fonts from "@src/components/ui/Fonts"; import NotificationsModule from "@src/components/modules/NotificationsModule"; import LoginPage from "@src/components/smart/LoginPage"; -import ReplicasPage from "@src/components/smart/ReplicasPage"; +import TransfersPage from "@src/components/smart/TransfersPage/TransfersPage"; import MessagePage from "@src/components/smart/MessagePage"; -import ReplicaDetailsPage from "@src/components/smart/ReplicaDetailsPage"; -import MigrationsPage from "@src/components/smart/MigrationsPage"; -import MigrationDetailsPage from "@src/components/smart/MigrationDetailsPage"; +import TransferDetailsPage from "@src/components/smart/TransferDetailsPage/TransferDetailsPage"; +import DeploymentsPage from "@src/components/smart/DeploymentsPage"; +import DeploymentDetailsPage from "@src/components/smart/DeploymentDetailsPage"; import MetalHubServersPage from "@src/components/smart/MetalHubServersPage"; import EndpointsPage from "@src/components/smart/EndpointsPage"; import EndpointDetailsPage from "@src/components/smart/EndpointDetailsPage"; -import AssessmentsPage from "@src/components/smart/AssessmentsPage"; -import AssessmentDetailsPage from "@src/components/smart/AssessmentDetailsPage"; import UsersPage from "@src/components/smart/UsersPage"; import UserDetailsPage from "@src/components/smart/UserDetailsPage"; import ProjectsPage from "@src/components/smart/ProjectsPage"; @@ -211,12 +209,12 @@ class App extends React.Component, State> { } {renderRoute("/dashboard", DashboardPage)} - {renderRoute("/replicas", ReplicasPage, true)} - {renderRoute("/replicas/:id", ReplicaDetailsPage, true)} - {renderRoute("/replicas/:id/:page", ReplicaDetailsPage)} - {renderRoute("/migrations", MigrationsPage, true)} - {renderRoute("/migrations/:id", MigrationDetailsPage, true)} - {renderRoute("/migrations/:id/:page", MigrationDetailsPage)} + {renderRoute("/transfers", TransfersPage, true)} + {renderRoute("/transfers/:id", TransferDetailsPage, true)} + {renderRoute("/transfers/:id/:page", TransferDetailsPage)} + {renderRoute("/deployments", DeploymentsPage, true)} + {renderRoute("/deployments/:id", DeploymentDetailsPage, true)} + {renderRoute("/deployments/:id/:page", DeploymentDetailsPage)} {renderRoute("/endpoints", EndpointsPage, true)} {renderRoute("/endpoints/:id", EndpointDetailsPage)} {renderRoute("/minion-pools", MinionPoolsPage, true)} @@ -225,15 +223,6 @@ class App extends React.Component, State> { {renderRoute("/bare-metal-servers", MetalHubServersPage, true)} {renderRoute("/bare-metal-servers/:id", MetalHubServerDetailsPage)} {renderRoute("/wizard/:type", WizardPage)} - {renderOptionalRoute({ - name: "planning", - component: AssessmentsPage, - })} - {renderOptionalRoute({ - name: "planning", - component: AssessmentDetailsPage, - path: "/assessment/:info", - })} {renderOptionalRoute({ name: "users", component: UsersPage, diff --git a/src/components/modules/AssessmentModule/AssessedVmListItem/AssessedVmListItem.tsx b/src/components/modules/AssessmentModule/AssessedVmListItem/AssessedVmListItem.tsx deleted file mode 100644 index 1354efe5..00000000 --- a/src/components/modules/AssessmentModule/AssessedVmListItem/AssessedVmListItem.tsx +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright (C) 2017 Cloudbase Solutions SRL -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -import React from "react"; -import { observer } from "mobx-react"; -import styled, { css } from "styled-components"; - -import Checkbox from "@src/components/ui/Checkbox"; -import InfoIcon from "@src/components/ui/InfoIcon"; -import DropdownLink from "@src/components/ui/Dropdowns/DropdownLink"; -import type { VmItem } from "@src/@types/Assessment"; -import { ThemePalette } from "@src/components/Theme"; - -const Wrapper = styled.div` - position: relative; - width: 100%; -`; -const Content = styled.div` - display: flex; - margin-left: -32px; - - & > div { - margin-left: 32px; - } - - opacity: ${(props: any) => (props.disabled ? 0.6 : 1)}; -`; -const columnWidth = (width: string) => css` - width: 100%; - max-width: ${width}; -`; -const DisplayName = styled.div` - display: flex; - ${(props: any) => columnWidth(props.width)} -`; -const Value = styled.div` - color: ${ThemePalette.grayscale[4]}; - ${(props: any) => columnWidth(props.width)} -`; -const DisplayNameLabel = styled.div` - margin-left: 8px; - word-break: break-word; -`; -const InfoIconStyled = styled(InfoIcon)` - position: absolute; - left: -36px; - top: 0px; - z-index: 10000; -`; - -type Props = { - item: VmItem; - selected: boolean; - onSelectedChange: (item: VmItem, isChecked: boolean) => void; - disabled: boolean; - loadingVmSizes: boolean; - vmSizes: string[]; - onVmSizeChange: (size: string) => void; - selectedVmSize: string | null; - recommendedVmSize: string; -}; -@observer -class AssessedVmListItem extends React.Component { - renderInfoIcon() { - if (!this.props.disabled) { - return null; - } - - return ( - - ); - } - - render() { - const { disks } = this.props.item.properties; - let standardCount = 0; - let premiumCount = 0; - Object.keys(disks).forEach(diskKey => { - if (disks[diskKey].recommendedDiskType === "Standard") { - standardCount += 1; - } - if (disks[diskKey].recommendedDiskType === "Premium") { - premiumCount += 1; - } - }); - - return ( - - {this.renderInfoIcon()} - - - { - this.props.onSelectedChange(this.props.item, checked); - }} - disabled={this.props.disabled} - /> - {`${this.props.item.properties.displayName}`} - - - {this.props.item.properties.operatingSystemName} - - - {standardCount} Standard, {premiumCount} Premium - - - ({ value: s, label: s })) - } - selectedItem={this.props.selectedVmSize || ""} - listWidth="200px" - onChange={item => { - this.props.onVmSizeChange(item.value); - }} - disabled={this.props.disabled} - highlightedItem={this.props.recommendedVmSize} - /> - - - - ); - } -} - -export default AssessedVmListItem; diff --git a/src/components/modules/AssessmentModule/AssessedVmListItem/package.json b/src/components/modules/AssessmentModule/AssessedVmListItem/package.json deleted file mode 100644 index 96e6715f..00000000 --- a/src/components/modules/AssessmentModule/AssessedVmListItem/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "AssessedVmListItem", - "version": "0.0.0", - "private": true, - "main": "./AssessedVmListItem.tsx" -} diff --git a/src/components/modules/AssessmentModule/AssessmentDetailsContent/AssessmentDetailsContent.tsx b/src/components/modules/AssessmentModule/AssessmentDetailsContent/AssessmentDetailsContent.tsx deleted file mode 100644 index 3dfde0a3..00000000 --- a/src/components/modules/AssessmentModule/AssessmentDetailsContent/AssessmentDetailsContent.tsx +++ /dev/null @@ -1,618 +0,0 @@ -/* -Copyright (C) 2017 Cloudbase Solutions SRL -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -import { observer } from "mobx-react"; -import React from "react"; -import styled, { css } from "styled-components"; - -import AssessedVmListItem from "@src/components/modules/AssessmentModule/AssessedVmListItem"; -import DetailsNavigation from "@src/components/modules/NavigationModule/DetailsNavigation"; -import { ThemePalette, ThemeProps } from "@src/components/Theme"; -import Button from "@src/components/ui/Button"; -import Checkbox from "@src/components/ui/Checkbox"; -import DropdownFilter from "@src/components/ui/Dropdowns/DropdownFilter"; -import DropdownLink from "@src/components/ui/Dropdowns/DropdownLink"; -import SmallLoading from "@src/components/ui/SmallLoading"; -import StatusImage from "@src/components/ui/StatusComponents/StatusImage"; -import Table from "@src/components/ui/Table"; -import DateUtils from "@src/utils/DateUtils"; - -import arrowImage from "./images/arrow.svg"; -import azureMigrateImage from "./images/logo.svg"; - -import type { Assessment, VmItem, AzureLocation } from "@src/@types/Assessment"; -import type { Endpoint } from "@src/@types/Endpoint"; -import type { Instance, Nic } from "@src/@types/Instance"; -import type { Network, NetworkMap } from "@src/@types/Network"; -const Wrapper = styled.div` - display: flex; - justify-content: center; -`; -const Buttons = styled.div` - margin-top: 46px; - display: flex; - flex-direction: column; - - button:first-child { - margin-bottom: 16px; - } -`; -const DetailsBody = styled.div` - ${ThemeProps.exactWidth(ThemeProps.contentWidth)} - margin-bottom: 32px; -`; -const Columns = styled.div` - display: flex; - margin-left: -32px; -`; -const Column = styled.div` - width: 50%; - margin-left: 32px; -`; -const Row = styled.div` - margin-bottom: 32px; -`; -const Field = styled.div` - display: flex; - flex-direction: column; -`; -const Label = styled.div` - font-size: 10px; - color: ${ThemePalette.grayscale[3]}; - font-weight: ${ThemeProps.fontWeights.medium}; - text-transform: uppercase; -`; -const Value = styled.div` - display: ${props => (props.flex ? "flex" : "inline-table")}; - margin-top: 3px; - ${props => (props.capitalize ? "text-transform: capitalize;" : "")} -`; -const AzureMigrateLogo = styled.div` - width: 208px; - height: 32px; - background: url("${azureMigrateImage}") center no-repeat; -`; -const LoadingWrapper = styled.div` - display: flex; - flex-direction: column; - align-items: center; - margin: 32px 0; -`; -const LoadingText = styled.div` - font-size: 18px; - margin-top: 32px; -`; -const SmallLoadingWrapper = styled.div` - display: flex; - align-items: center; - justify-content: center; -`; -const SmallLoadingText = styled.div` - font-size: 14px; - margin-left: 16px; -`; -const TableStyled = styled(Table)` - margin-top: 62px; - ${props => - props.addWidthPadding - ? css` - margin-left: -24px; - &:after { - margin-left: 24px; - } - ` - : ""} -`; -const TableHeaderStyle = css` - margin-left: 24px; -`; -const TableBodyStyle = css` - padding-left: 24px; -`; -const NetworkItem = styled.div` - display: flex; - width: 100%; -`; -const column = () => css` - padding-right: 32px; - width: 100%; - max-width: 25%; -`; -const NetworkName = styled.div` - ${column()} -`; -const Arrow = styled.div` - width: 32px; - height: 16px; - position: absolute; - right: 0; - background: url("${arrowImage}") no-repeat; - background-position-y: center; -`; -const ColumnStub = styled.div` - ${column()} - position: relative; - &:last-child { - padding-right: 0; - } -`; -const VmHeaderItem = styled.div` - display: flex; - font-size: 14px; -`; -const VmHeaderItemLabel = styled.div` - font-size: 10px; - margin-left: 8px; -`; - -const NavigationItems = [ - { - label: "Details", - value: "", - }, -]; - -type Props = { - item: Assessment | null; - detailsLoading: boolean; - instancesDetailsLoading: boolean; - instancesLoading: boolean; - networksLoading: boolean; - instancesDetailsProgress: number | null; - targetEndpoint: Endpoint; - targetEndpoints: Endpoint[]; - onTargetEndpointChange: (endpoint: Endpoint) => void; - targetEndpointsLoading: boolean; - sourceEndpoints: Endpoint[]; - sourceEndpoint: Endpoint | null; - sourceEndpointsLoading: boolean; - locations: AzureLocation[]; - selectedLocation: string | null; - onLocationChange: (locationName: string) => void; - selectedResourceGroup: string; - resourceGroups: string[]; - onResourceGroupChange: (resourceGroupName: string) => void; - targetOptionsLoading: boolean; - assessedVmsCount: number; - filteredAssessedVms: VmItem[]; - selectedVms: string[]; - instancesDetails: Instance[]; - instances: Instance[]; - loadingVmSizes: boolean; - vmSizes: string[]; - onVmSizeChange: (vmId: string, size: string) => void; - onGetSelectedVmSize: (vm: VmItem) => string | null; - networks: Network[]; - page: string; - onSourceEndpointChange: (endpoint: Endpoint) => void; - onVmSearchValueChange: (value: string) => void; - vmSearchValue: string; - onVmSelectedChange: (vm: VmItem, selected: boolean) => void; - onNetworkChange: (sourceNic: Nic, targetNetwork: Network) => void; - onRefresh: () => void; - onMigrateClick: () => void; - selectedNetworks: NetworkMap[]; - selectAllVmsChecked: boolean; - onSelectAllVmsChange: (selected: boolean) => void; -}; -@observer -class AssessmentDetailsContent extends React.Component { - static defaultProps = { - page: "", - }; - - doesVmMatchSource(vm: VmItem) { - if ( - !this.props.sourceEndpoint || - !this.props.sourceEndpoint.connection_info - ) { - return false; - } - - if ( - this.props.instances.length > 0 && - !this.props.instances.find( - i => - i.name === vm.properties.displayName || - i.instance_name === vm.properties.displayName - ) - ) { - return false; - } - - return ( - this.props.sourceEndpoint.connection_info.host === - vm.properties.datacenterManagementServerName - ); - } - - renderMainDetails() { - if (this.props.page !== "" || !this.props.item || !this.props.item.id) { - return null; - } - - const status = this.props.item - ? this.props.item.properties.status === "Completed" - ? "Ready for Migration" - : this.props.item.properties.status - : ""; - - const locationItem: AzureLocation | undefined = this.props.locations.find( - l => l.id === this.props.selectedLocation - ); - - return ( - - - - - - - - - - {this.props.item - ? DateUtils.getLocalDate( - this.props.item.properties.updatedTimestamp - ).toFormat("yyyy-LL-dd HH:mm:ss") - : "-"} - - - - - - - - {this.props.item ? this.props.item.projectName : ""} - - - - - - - {this.props.item ? this.props.item.groupName : ""} - - - - - - {status} - - - - - - - - - ({ - label: endpoint.name, - value: endpoint.id, - endpoint, - }))} - onChange={item => { - this.props.onSourceEndpointChange(item.endpoint); - }} - selectItemLabel="Select Endpoint" - noItemsLabel={ - this.props.sourceEndpointsLoading - ? "Loading ...." - : "No matching endpoints" - } - /> - - - - - - - - ({ - label: endpoint.name, - value: endpoint.id, - endpoint, - }))} - onChange={item => { - this.props.onTargetEndpointChange(item.endpoint); - }} - selectItemLabel="Select Endpoint" - noItemsLabel={ - this.props.targetEndpointsLoading - ? "Loading ...." - : "No Azure endpoints" - } - /> - - - - - - - - ({ - label: group, - value: group, - }))} - onChange={item => { - this.props.onResourceGroupChange(item.value); - }} - noItemsLabel={ - this.props.targetOptionsLoading - ? "Loading ...." - : "No Resource Groups found" - } - /> - - - - - - - - ({ - label: location.name, - value: location.id, - }))} - onChange={item => { - this.props.onLocationChange(item.value); - }} - noItemsLabel={ - this.props.targetOptionsLoading - ? "Loading ...." - : "No Locations found" - } - /> - - - - - - ); - } - - renderVmsTable() { - const loading = this.props.instancesLoading; - - const items = this.props.filteredAssessedVms.map(vm => ( - m === vm.properties.displayName) - .length > 0 - } - onSelectedChange={(selectedVm, selected) => { - this.props.onVmSelectedChange(selectedVm, selected); - }} - disabled={!this.doesVmMatchSource(vm)} - loadingVmSizes={this.props.loadingVmSizes} - recommendedVmSize={vm.properties.recommendedSize} - vmSizes={this.props.vmSizes} - selectedVmSize={this.props.onGetSelectedVmSize(vm)} - onVmSizeChange={size => { - this.props.onVmSizeChange(vm.properties.displayName, size); - }} - /> - )); - - const vmCountLabel = `(${ - this.props.filteredAssessedVms.length === this.props.assessedVmsCount - ? this.props.assessedVmsCount - : `${this.props.filteredAssessedVms.length} OUT OF ${this.props.assessedVmsCount}` - })`; - const vmHeaderItem = ( - - {loading ? null : ( - { - this.props.onSelectAllVmsChange(checked); - }} - /> - )} - Virtual Machine {vmCountLabel} - { - this.props.onVmSearchValueChange(value); - }} - /> - - ); - - return ( - - ); - } - - renderNetworkTable() { - const loading = - this.props.networksLoading || this.props.instancesDetailsLoading; - - if (loading) { - return ( - - ); - } - - const nics: Nic[] = []; - this.props.instancesDetails.forEach(instance => { - if (!instance.devices || !instance.devices.nics) { - return; - } - instance.devices.nics.forEach(nic => { - if (nics.find(n => n.network_name === nic.network_name)) { - return; - } - nics.push(nic); - }); - }); - - if (nics.length === 0) { - return null; - } - - const items = nics.map(nic => { - let selectedNetworkName: string | undefined; - const selectedNetwork = - this.props.selectedNetworks && - this.props.selectedNetworks.find( - n => n.sourceNic.network_name === nic.network_name - ); - if (selectedNetwork) { - selectedNetworkName = selectedNetwork.targetNetwork?.name; - } - - return ( - - {nic.network_name} - - - - - - { - this.props.onNetworkChange(nic, item.network); - }} - items={this.props.networks.map(network => ({ - value: network.name || "", - label: network.name || "", - network, - }))} - /> - - - ); - }); - return ( - - ); - } - - renderNetworksLoading() { - let loadingProgress = -1; - if (this.props.instancesDetailsLoading) { - if (this.props.instancesDetailsProgress != null) { - loadingProgress = Math.round(this.props.instancesDetailsProgress * 100); - } - } - - return ( - - - Loading networks, please wait ... - - ); - } - - renderButtons() { - return ( - - - - - ); - } - - renderLoading(message: string) { - return ( - - - {message} - - ); - } - - render() { - return ( - - "#"} - /> - - {this.props.detailsLoading ? null : this.renderMainDetails()} - {this.props.detailsLoading - ? this.renderLoading("Loading assessment...") - : null} - {this.props.detailsLoading ? null : this.renderVmsTable()} - {this.props.detailsLoading || this.props.instancesLoading - ? null - : this.renderNetworkTable()} - {this.props.detailsLoading ? null : this.renderButtons()} - - - ); - } -} - -export default AssessmentDetailsContent; diff --git a/src/components/modules/AssessmentModule/AssessmentDetailsContent/images/arrow.svg b/src/components/modules/AssessmentModule/AssessmentDetailsContent/images/arrow.svg deleted file mode 100644 index 57678840..00000000 --- a/src/components/modules/AssessmentModule/AssessmentDetailsContent/images/arrow.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - Created with Sketch. - - - - - - - - diff --git a/src/components/modules/AssessmentModule/AssessmentDetailsContent/images/logo.svg b/src/components/modules/AssessmentModule/AssessmentDetailsContent/images/logo.svg deleted file mode 100644 index 893ff1b9..00000000 --- a/src/components/modules/AssessmentModule/AssessmentDetailsContent/images/logo.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Created with Sketch. - - - diff --git a/src/components/modules/AssessmentModule/AssessmentDetailsContent/package.json b/src/components/modules/AssessmentModule/AssessmentDetailsContent/package.json deleted file mode 100644 index 73c83330..00000000 --- a/src/components/modules/AssessmentModule/AssessmentDetailsContent/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "AssessmentDetailsContent", - "version": "0.0.0", - "private": true, - "main": "./AssessmentDetailsContent.tsx" -} diff --git a/src/components/modules/AssessmentModule/AssessmentListItem/AssessmentListItem.tsx b/src/components/modules/AssessmentModule/AssessmentListItem/AssessmentListItem.tsx deleted file mode 100644 index 2584a4f5..00000000 --- a/src/components/modules/AssessmentModule/AssessmentListItem/AssessmentListItem.tsx +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright (C) 2017 Cloudbase Solutions SRL -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -import React from "react"; -import { observer } from "mobx-react"; -import styled from "styled-components"; - -import StatusPill from "@src/components/ui/StatusComponents/StatusPill"; - -import type { Assessment } from "@src/@types/Assessment"; - -import { ThemePalette, ThemeProps } from "@src/components/Theme"; -import assessmentImage from "./images/assessment.svg"; -import azureMigrateImage from "./images/azure-migrate.svg"; - -const Content = styled.div` - display: flex; - align-items: center; - border-top: 1px solid ${ThemePalette.grayscale[1]}; - padding: 8px 16px; - cursor: pointer; - flex-grow: 1; - transition: all ${ThemeProps.animations.swift}; - min-width: 785px; - - &:hover { - background: ${ThemePalette.grayscale[1]}; - } -`; -const Wrapper = styled.div` - display: flex; - align-items: center; - - &:last-child ${Content} { - border-bottom: 1px solid ${ThemePalette.grayscale[1]}; - } -`; -const Image = styled.div` - min-width: 48px; - height: 48px; - background: url("${(props: any) => props.image}") no-repeat center; - margin-right: 16px; -`; -const Title = styled.div` - flex-grow: 1; - overflow: hidden; - margin-right: 48px; - min-width: 100px; -`; -const TitleLabel = styled.div` - font-size: 16px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -`; -const AssessmentType = styled.div` - display: flex; - justify-content: center; - align-items: center; - margin-right: 46px; - ${ThemeProps.exactWidth("180px")} -`; -const AssessmentImage = styled.div` - width: 48px; - height: 32px; - background: url("${azureMigrateImage}") center no-repeat; - margin-right: 12px; -`; -const AssessmentLabel = styled.div` - font-size: 15px; - color: ${ThemePalette.grayscale[4]}; - width: 64px; -`; -const TotalVms = styled.div` - ${ThemeProps.exactWidth("96px")} - margin-right: 48px; -`; -const Project = styled.div` - ${ThemeProps.exactWidth("175px")} - margin-right: 48px; -`; -const ItemLabel = styled.div` - color: ${ThemePalette.grayscale[4]}; -`; -const ItemValue = styled.div` - color: ${ThemePalette.primary}; -`; - -type Props = { - item: Assessment; - onClick: () => void; -}; -@observer -class AssessmentListItem extends React.Component { - render() { - let status = this.props.item.properties.status.toUpperCase(); - let label = status; - if (status === "CREATED" || status === "RUNNING") { - status = "RUNNING"; - label = "CREATING"; - } else if (status === "COMPLETED") { - label = "READY"; - } - - return ( - - - - - <TitleLabel>{this.props.item.name}</TitleLabel> - <StatusPill status={status} label={label} /> - - - - Azure Migrate - - - Project - {this.props.item.project.name} - - - Instances - {this.props.item.properties.numberOfMachines} - - - - ); - } -} - -export default AssessmentListItem; diff --git a/src/components/modules/AssessmentModule/AssessmentListItem/images/assessment.svg b/src/components/modules/AssessmentModule/AssessmentListItem/images/assessment.svg deleted file mode 100644 index 96f44f1d..00000000 --- a/src/components/modules/AssessmentModule/AssessmentListItem/images/assessment.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Created with Sketch. - - - - - - - - - - - - - - - diff --git a/src/components/modules/AssessmentModule/AssessmentListItem/images/azure-migrate.svg b/src/components/modules/AssessmentModule/AssessmentListItem/images/azure-migrate.svg deleted file mode 100644 index 5c6b717c..00000000 --- a/src/components/modules/AssessmentModule/AssessmentListItem/images/azure-migrate.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Created with Sketch. - - - - - - - - - - - - - - - diff --git a/src/components/modules/AssessmentModule/AssessmentListItem/package.json b/src/components/modules/AssessmentModule/AssessmentListItem/package.json deleted file mode 100644 index 643b8af5..00000000 --- a/src/components/modules/AssessmentModule/AssessmentListItem/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "AssessmentListItem", - "version": "0.0.0", - "private": true, - "main": "./AssessmentListItem.tsx" -} diff --git a/src/components/modules/AssessmentModule/AssessmentMigrationOptions/AssessmentMigrationOptions.tsx b/src/components/modules/AssessmentModule/AssessmentMigrationOptions/AssessmentMigrationOptions.tsx deleted file mode 100644 index 5e7da9c3..00000000 --- a/src/components/modules/AssessmentModule/AssessmentMigrationOptions/AssessmentMigrationOptions.tsx +++ /dev/null @@ -1,321 +0,0 @@ -/* -Copyright (C) 2017 Cloudbase Solutions SRL -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as -published by the Free Software Foundation, either version 3 of the -License, or (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . -*/ - -import * as React from "react"; -import { observer } from "mobx-react"; -import styled from "styled-components"; - -import Button from "@src/components/ui/Button"; -import FieldInput from "@src/components/ui/FieldInput"; -import ToggleButtonBar from "@src/components/ui/ToggleButtonBar"; - -import type { Field } from "@src/@types/Field"; - -import { ThemeProps } from "@src/components/Theme"; - -import LabelDictionary from "@src/utils/LabelDictionary"; - -import assessmentImage from "./images/assessment.svg"; - -const Wrapper = styled.div` - padding: 48px 32px 32px 32px; - display: flex; - flex-direction: column; - align-items: center; - min-height: 0; -`; -const Image = styled.div` - width: 96px; - height: 96px; - background: url("${assessmentImage}") center no-repeat; -`; -const ToggleButtonBarStyled = styled(ToggleButtonBar)` - margin-top: 48px; -`; -const Fields = styled.div` - display: flex; - margin-top: 32px; - flex-direction: column; - overflow: auto; - width: 100%; - min-height: 0; -`; -const FieldStyled = styled(FieldInput)` - ${ThemeProps.exactWidth(`${ThemeProps.inputSizes.large.width}px`)} - margin-bottom: 16px; -`; -const Row = styled.div` - display: flex; - flex-shrink: 0; - justify-content: space-between; -`; - -const Buttons = styled.div` - display: flex; - justify-content: space-between; - width: 100%; - margin-top: 32px; -`; - -const generalFields = [ - { - name: "use_replica", - type: "boolean", - }, - { - name: "separate_vm", - type: "boolean", - }, -]; -const replicaFields = [ - { - name: "shutdown_instances", - type: "boolean", - }, -]; -const migrationFields = [ - { - name: "skip_os_morphing", - type: "boolean", - }, -]; - -type Props = { - onCancelClick: () => void; - onExecuteClick: (fieldValues: { [prop: string]: any }) => void; - executeButtonDisabled: boolean; - replicaSchema: Field[]; - migrationSchema: Field[]; - onResizeUpdate?: (scrollableRef: HTMLElement, scrollOffset?: number) => void; -}; -type State = { - fieldValues: { [prop: string]: any }; - showAdvancedOptions: boolean; -}; -@observer -class AssessmentMigrationOptions extends React.Component { - state: State = { - fieldValues: { - separate_vm: true, - use_replica: false, - shutdown_instances: false, - skip_os_morphing: false, - }, - showAdvancedOptions: false, - }; - - // scrollableRef: HTMLElement | undefined | null - - getFieldValue(fieldName: string) { - if (this.state.fieldValues[fieldName] != null) { - return this.state.fieldValues[fieldName]; - } - return null; - } - - getObjectFieldValue(fieldName: string, propName: string) { - return ( - this.state.fieldValues[fieldName] && - this.state.fieldValues[fieldName][propName] - ); - } - - handleValueChange(fieldName: string, value: any) { - this.setState(prevState => { - const fieldValues = { ...prevState.fieldValues }; - if (value != null) { - fieldValues[fieldName] = value; - } else { - delete fieldValues[fieldName]; - } - return { fieldValues }; - }); - } - - // UNSAFE_componentDidUpdate(_: Props, prevState: State) { - // if (prevState.showAdvancedOptions !== this.state.showAdvancedOptions - // && this.props.onResizeUpdate && this.scrollableRef) { - // this.props.onResizeUpdate(this.scrollableRef) - // } - // } - - handleObjectValueChange(fieldName: string, propName: string, value: any) { - this.setState(prevState => { - const fieldValues = { ...prevState.fieldValues }; - if (!fieldValues[fieldName]) { - fieldValues[fieldName] = {}; - } - fieldValues[fieldName][propName] = value; - return { fieldValues }; - }); - } - - renderFields() { - let fields: any = generalFields; - const useReplica = this.getFieldValue("use_replica"); - const skipFields = [ - "location", - "resource_group", - "network_map", - "storage_map", - "vm_size", - "worker_size", - ]; - // eslint-disable-next-line no-shadow - const cleanup = (cleanupFields: any[]) => - cleanupFields - .filter((f: { name: string }) => !skipFields.find(n => n === f.name)) - .map((f: { type: string; nullableBoolean: boolean }) => { - if (f.type === "boolean") { - // eslint-disable-next-line no-param-reassign - f.nullableBoolean = true; - } - return { ...f }; - }); - - if (useReplica) { - fields = [...fields, ...replicaFields]; - if (this.state.showAdvancedOptions) { - fields = [...fields, ...cleanup(this.props.replicaSchema)]; - } - } else { - fields = [...fields, ...migrationFields]; - if (this.state.showAdvancedOptions) { - fields = [...fields, ...cleanup(this.props.migrationSchema)]; - } - } - - const sortPriority: any = { - boolean: 1, - string: 2, - object: 3, - }; - fields.sort((a: any, b: any) => { - if (sortPriority[a.type] && sortPriority[b.type]) { - return sortPriority[a.type] - sortPriority[b.type]; - } - if (sortPriority[a.type]) { - return -1; - } - if (sortPriority[b.type]) { - return 1; - } - return a.name.localeCompare(b.name); - }); - - const rows: JSX.Element[] = []; - let lastField: JSX.Element; - fields.forEach((field: any, index: number) => { - let additionalProps; - if (field.type === "object" && field.properties) { - additionalProps = { - valueCallback: (callbackField: { name: string }) => - this.getObjectFieldValue(field.name, callbackField.name), - onChange: (value: any, callbackField: { name: string }) => { - const propName = callbackField.name.substr( - callbackField.name.lastIndexOf("/") + 1 - ); - this.handleObjectValueChange(field.name, propName, value); - }, - properties: field.properties.map((p: any) => ({ - ...p, - required: false, - })), - }; - } else { - const value = this.getFieldValue(field.name); - additionalProps = { - value, - // eslint-disable-next-line no-shadow - onChange: (changeValue: any) => { - this.handleValueChange(field.name, changeValue); - }, - type: field.type, - }; - } - - const currentField = ( - - ); - const pushRow = (field1: React.ReactNode, field2?: React.ReactNode) => { - rows.push( - - {field1} - {field2} - - ); - }; - if (index === fields.length - 1 && index % 2 === 0) { - pushRow(currentField); - } else if (index % 2 !== 0) { - pushRow(lastField, currentField); - } else { - lastField = currentField; - } - }); - - return ( - // { this.scrollableRef = ref }}> - {rows} - ); - } - - render() { - return ( - - - { - this.setState({ showAdvancedOptions: item.value === "advanced" }); - }} - /> - {this.renderFields()} - - - - - - ); - } -} - -export default AssessmentMigrationOptions; diff --git a/src/components/modules/AssessmentModule/AssessmentMigrationOptions/images/assessment.svg b/src/components/modules/AssessmentModule/AssessmentMigrationOptions/images/assessment.svg deleted file mode 100644 index 20d28601..00000000 --- a/src/components/modules/AssessmentModule/AssessmentMigrationOptions/images/assessment.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Created with Sketch. - - - - - - - - - - - - diff --git a/src/components/modules/AssessmentModule/AssessmentMigrationOptions/package.json b/src/components/modules/AssessmentModule/AssessmentMigrationOptions/package.json deleted file mode 100644 index e0811528..00000000 --- a/src/components/modules/AssessmentModule/AssessmentMigrationOptions/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "AssessmentMigrationOptions", - "version": "0.0.0", - "private": true, - "main": "./AssessmentMigrationOptions.tsx" -} diff --git a/src/components/modules/DashboardModule/DashboardActivity/DashboardActivity.tsx b/src/components/modules/DashboardModule/DashboardActivity/DashboardActivity.tsx index 4572a1c2..e50b638a 100644 --- a/src/components/modules/DashboardModule/DashboardActivity/DashboardActivity.tsx +++ b/src/components/modules/DashboardModule/DashboardActivity/DashboardActivity.tsx @@ -23,7 +23,7 @@ import Button from "@src/components/ui/Button"; import { InfoColumn, MainItemInfo, - ItemReplicaBadge, + ItemTransferBadge, ItemTitle, ItemDescription, } from "@src/components/ui/Dropdowns/NotificationDropdown"; @@ -31,7 +31,7 @@ import { import type { NotificationItemData } from "@src/@types/NotificationItem"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; -import replicaImage from "./images/replica.svg"; +import transferImage from "./images/transfer.svg"; const Wrapper = styled.div` flex-grow: 1; @@ -80,9 +80,9 @@ const NoItems = styled.div` align-items: center; width: 100%; `; -const ReplicaImage = styled.div` +const TransferImage = styled.div` ${ThemeProps.exactSize("148px")} - background: url('${replicaImage}') center no-repeat; + background: url('${transferImage}') center no-repeat; `; const Message = styled.div` text-align: center; @@ -104,11 +104,15 @@ class DashboardActivity extends React.Component { {this.props.notificationItems .filter((_, i) => i < (this.props.large ? 10 : 5)) .map((item, i) => { + const actionHref = + item.type === "transfer" + ? "transfers" : "deployments" + const executionsHref = item.status === "RUNNING" - ? item.type === "replica" + ? item.type === "transfer" ? "/executions" - : item.type === "migration" + : item.type === "deployment" ? "/tasks" : "" : ""; @@ -116,7 +120,7 @@ class DashboardActivity extends React.Component { return ( { - - {item.type === "replica" ? "RE" : "MI"} - + + {item.type === "transfer" ? "TR" : "DE"} + {item.name} {item.description} @@ -142,14 +146,14 @@ class DashboardActivity extends React.Component { renderNoItems() { return ( - + There is no recent activity
in this project.
); diff --git a/src/components/modules/DashboardModule/DashboardActivity/images/replica.svg b/src/components/modules/DashboardModule/DashboardActivity/images/transfer.svg similarity index 100% rename from src/components/modules/DashboardModule/DashboardActivity/images/replica.svg rename to src/components/modules/DashboardModule/DashboardActivity/images/transfer.svg diff --git a/src/components/modules/DashboardModule/DashboardContent/DashboardContent.spec.tsx b/src/components/modules/DashboardModule/DashboardContent/DashboardContent.spec.tsx index 5d0cee24..2af5e887 100644 --- a/src/components/modules/DashboardModule/DashboardContent/DashboardContent.spec.tsx +++ b/src/components/modules/DashboardModule/DashboardContent/DashboardContent.spec.tsx @@ -35,11 +35,11 @@ describe("DashboardContent", () => { beforeEach(() => { defaultProps = { - replicas: [], + transfers: [], migrations: [], endpoints: [], projects: [], - replicasLoading: false, + transfersLoading: false, migrationsLoading: false, endpointsLoading: false, usersLoading: false, @@ -52,7 +52,7 @@ describe("DashboardContent", () => { licenceError: null, notificationItems: [], isAdmin: false, - onNewReplicaClick: jest.fn(), + onNewTransferClick: jest.fn(), onNewEndpointClick: jest.fn(), onAddLicenceClick: jest.fn(), }; diff --git a/src/components/modules/DashboardModule/DashboardContent/DashboardContent.tsx b/src/components/modules/DashboardModule/DashboardContent/DashboardContent.tsx index 72f60743..506edb33 100644 --- a/src/components/modules/DashboardModule/DashboardContent/DashboardContent.tsx +++ b/src/components/modules/DashboardModule/DashboardContent/DashboardContent.tsx @@ -30,7 +30,7 @@ import type { Project } from "@src/@types/Project"; import type { User } from "@src/@types/User"; import type { Licence, LicenceServerStatus } from "@src/@types/Licence"; import type { NotificationItemData } from "@src/@types/NotificationItem"; -import { ReplicaItem, MigrationItem } from "@src/@types/MainItem"; +import { TransferItem, DeploymentItem } from "@src/@types/MainItem"; const MIDDLE_WIDTHS = ["264px", "264px", "264px"]; @@ -52,12 +52,12 @@ const MiddleMobileLayout = styled.div` `; type Props = { - replicas: ReplicaItem[]; - migrations: MigrationItem[]; + transfers: TransferItem[]; + deployments: DeploymentItem[]; endpoints: Endpoint[]; projects: Project[]; - replicasLoading: boolean; - migrationsLoading: boolean; + transfersLoading: boolean; + deploymentsLoading: boolean; endpointsLoading: boolean; usersLoading: boolean; projectsLoading: boolean; @@ -69,7 +69,7 @@ type Props = { licenceError: string | null; notificationItems: NotificationItemData[]; isAdmin: boolean; - onNewReplicaClick: () => void; + onNewTransferClick: () => void; onNewEndpointClick: () => void; onAddLicenceClick: () => void; }; @@ -122,16 +122,15 @@ class DashboardContent extends React.Component { width: MIDDLE_WIDTHS[0], } } - onNewClick={this.props.onNewReplicaClick} + onNewClick={this.props.onNewTransferClick} />, { ); } + getReplicas() { + return this.props.transfers.filter( + (r: TransferItem) => r.scenario === "replica"); + } + + getLiveMigrations() { + return this.props.transfers.filter( + (r: TransferItem) => r.scenario === "live_migration"); + } + render() { let infoCountData = [ { label: "Replicas", - value: this.props.replicas.length, + value: this.getReplicas().length, color: ThemePalette.alert, - link: "/replicas", - loading: this.props.replicasLoading, + link: "/transfers", + loading: this.props.transfersLoading, }, { label: "Migrations", - value: this.props.migrations.length, - color: ThemePalette.primary, - link: "/migrations", - loading: this.props.migrationsLoading, + value: this.getLiveMigrations().length, + link: "/transfers", + loading: this.props.transfersLoading, }, { label: "Endpoints", @@ -224,9 +232,9 @@ class DashboardContent extends React.Component { {this.renderMiddleModules()} ); diff --git a/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.spec.tsx b/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.spec.tsx index ee2d869e..2ea33c1f 100644 --- a/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.spec.tsx +++ b/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.spec.tsx @@ -15,7 +15,7 @@ along with this program. If not, see . import { DateTime } from "luxon"; import React from "react"; -import { MigrationItem, ReplicaItem } from "@src/@types/MainItem"; +import { MigrationItem, TransferItem } from "@src/@types/MainItem"; import { render } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import TestUtils from "@tests/TestUtils"; @@ -23,7 +23,7 @@ import TestUtils from "@tests/TestUtils"; import DashboardExecutions from "./DashboardExecutions"; type BuildType = T extends "replica" - ? ReplicaItem + ? TransferItem : MigrationItem; const buildItem = ( diff --git a/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.tsx b/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.tsx index 353bd500..b1b864fe 100644 --- a/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.tsx +++ b/src/components/modules/DashboardModule/DashboardExecutions/DashboardExecutions.tsx @@ -17,7 +17,7 @@ import { observer } from "mobx-react"; import * as React from "react"; import styled from "styled-components"; -import { MigrationItem, ReplicaItem, TransferItem } from "@src/@types/MainItem"; +import { TransferItem, ActionItem } from "@src/@types/MainItem"; import DashboardBarChart from "@src/components/modules/DashboardModule/DashboardBarChart"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import DropdownLink from "@src/components/ui/Dropdowns/DropdownLink"; @@ -129,14 +129,14 @@ const EmptyBackgroundImage = styled.div` type Props = { // eslint-disable-next-line react/no-unused-prop-types - replicas: ReplicaItem[]; - migrations: MigrationItem[]; + replicas: TransferItem[]; + migrations: TransferItem[]; loading: boolean; }; type GroupedData = { label: string; values: number[]; - data?: string; + data?: string }; type TooltipData = { title: string; @@ -202,9 +202,9 @@ class DashboardExecutions extends React.Component { if (!periods[period]) { periods[period] = { replicas: 0, migrations: 0 }; } - if (item.type === "replica") { + if (item.scenario === "replica") { periods[period].replicas += 1; - } else if (item.type === "migration") { + } else if (item.scenario === "live_migration") { periods[period].migrations += 1; } }); diff --git a/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.spec.tsx b/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.spec.tsx index d48aa2c3..5e4cdedf 100644 --- a/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.spec.tsx +++ b/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.spec.tsx @@ -68,14 +68,14 @@ describe("DashboardLicence", () => { expect( TestUtils.selectAll("DashboardLicence__ChartHeaderCurrent-")[0] .textContent - ).toBe("5 Used Replicas "); + ).toBe("5 Fulfilled Replicas "); expect( TestUtils.selectAll("DashboardLicence__ChartHeaderTotal-")[0].textContent ).toBe("Total 10"); expect( TestUtils.selectAll("DashboardLicence__ChartHeaderCurrent-")[1] .textContent - ).toBe("3 Used Migrations "); + ).toBe("3 Fulfilled Migrations "); expect( TestUtils.selectAll("DashboardLicence__ChartHeaderTotal-")[1].textContent ).toBe("Total 5"); @@ -176,6 +176,6 @@ describe("DashboardLicence", () => { expect( TestUtils.selectAll("DashboardLicence__ChartHeaderCurrent-")[0] .textContent - ).toBe("1 Used Replica "); + ).toBe("1 Fulfilled Replica "); }); }); diff --git a/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.tsx b/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.tsx index 8be0c700..9f1882ad 100644 --- a/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.tsx +++ b/src/components/modules/DashboardModule/DashboardLicence/DashboardLicence.tsx @@ -202,7 +202,7 @@ class DashboardLicence extends React.Component { current: info.currentPerformedReplicas, total: info.currentAvailableReplicas, label: "Used Replica", - info: `The number of replicas consumed over the number of replicas available in + info: `The number of replicas fulfilled over the number of replicas available in all currently active licences (including non-activated floating licences)`, }, ], @@ -212,7 +212,7 @@ class DashboardLicence extends React.Component { current: info.currentPerformedMigrations, total: info.currentAvailableMigrations, label: "Used Migration", - info: `The number of migrations consumed over the number of migrations available in + info: `The number of migrations fulfilled over the number of migrations available in all currently active licences (including non-activated floating licences)`, }, ], @@ -277,7 +277,7 @@ class DashboardLicence extends React.Component { return (

- Please contact Cloudbase Solutions with your Appliance ID in order to + Please contact your Coriolis representative with the Appliance ID in order to obtain a Coriolis® licence.

diff --git a/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.spec.tsx b/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.spec.tsx index d12c8032..33715081 100644 --- a/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.spec.tsx +++ b/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.spec.tsx @@ -15,7 +15,7 @@ along with this program. If not, see . import React from "react"; import { Endpoint } from "@src/@types/Endpoint"; -import { MigrationItem, ReplicaItem } from "@src/@types/MainItem"; +import { MigrationItem, TransferItem } from "@src/@types/MainItem"; import { fireEvent, render } from "@testing-library/react"; import TestUtils from "@tests/TestUtils"; @@ -24,7 +24,7 @@ import DashboardTopEndpoints from "./DashboardTopEndpoints"; jest.mock("react-router-dom", () => ({ Link: "a" })); type BuildType = T extends "replica" - ? ReplicaItem + ? TransferItem : MigrationItem; const buildItem = ( @@ -64,7 +64,7 @@ const buildEndpoint = (id: string): Endpoint => ({ connection_info: {}, }); -const replicas: DashboardTopEndpoints["props"]["replicas"] = [ +const replicas: DashboardTopEndpoints["props"]["transfers"] = [ buildItem("replica", "a", "b"), buildItem("replica", "a", "b"), buildItem("replica", "c", "d"), @@ -86,7 +86,7 @@ const endpoints: DashboardTopEndpoints["props"]["endpoints"] = [ describe("DashboardTopEndpoints", () => { const defaultProps: DashboardTopEndpoints["props"] = { - replicas, + transfers: replicas, migrations, endpoints, style: {}, @@ -98,7 +98,7 @@ describe("DashboardTopEndpoints", () => { render( { render( @@ -125,7 +125,7 @@ describe("DashboardTopEndpoints", () => { diff --git a/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.tsx b/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.tsx index 2d1d20b3..bf3d35b6 100644 --- a/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.tsx +++ b/src/components/modules/DashboardModule/DashboardTopEndpoints/DashboardTopEndpoints.tsx @@ -26,7 +26,7 @@ import { ThemePalette, ThemeProps } from "@src/components/Theme"; import type { Endpoint } from "@src/@types/Endpoint"; -import { ReplicaItem, MigrationItem, TransferItem } from "@src/@types/MainItem"; +import { TransferItem } from "@src/@types/MainItem"; import endpointImage from "./images/endpoint.svg"; const Wrapper = styled.div` @@ -136,9 +136,7 @@ type GroupedEndpoint = { }; type Props = { // eslint-disable-next-line react/no-unused-prop-types - replicas: ReplicaItem[]; - // eslint-disable-next-line react/no-unused-prop-types - migrations: MigrationItem[]; + transfers: TransferItem[]; // eslint-disable-next-line react/no-unused-prop-types endpoints: Endpoint[]; style: React.CSSProperties; @@ -178,20 +176,21 @@ class DashboardTopEndpoints extends React.Component { calculateGroupedEndpoints(props: Props) { const groupedEndpoints: GroupedEndpoint[] = []; - const count = (mainItems: TransferItem[], endpointId: string) => + const count = (mainItems: TransferItem[], endpointId: string, scenario: string) => mainItems.filter( r => - r.destination_endpoint_id === endpointId || - r.origin_endpoint_id === endpointId + r.scenario === scenario && ( + r.destination_endpoint_id === endpointId || + r.origin_endpoint_id === endpointId) ).length; props.endpoints.forEach(endpoint => { - const replicasCount = count(props.replicas, endpoint.id); - const migrationsCount = count(props.migrations, endpoint.id); + const replicasCount = count(props.transfers, endpoint.id, "replica"); + const migrationsCount = count(props.transfers, endpoint.id, "live_migration"); groupedEndpoints.push({ endpoint, - replicasCount, - migrationsCount, + replicasCount: replicasCount, + migrationsCount: migrationsCount, value: replicasCount + migrationsCount, }); }); diff --git a/src/components/modules/EndpointModule/EndpointDetailsContent/EndpointDetailsContent.tsx b/src/components/modules/EndpointModule/EndpointDetailsContent/EndpointDetailsContent.tsx index cb9508b2..3b10ee8f 100644 --- a/src/components/modules/EndpointModule/EndpointDetailsContent/EndpointDetailsContent.tsx +++ b/src/components/modules/EndpointModule/EndpointDetailsContent/EndpointDetailsContent.tsx @@ -20,8 +20,6 @@ import styled from "styled-components"; import { Field as FieldType } from "@src/@types/Field"; import { getTransferItemTitle, - MigrationItem, - ReplicaItem, TransferItem, } from "@src/@types/MainItem"; import { Region } from "@src/@types/Region"; @@ -102,7 +100,7 @@ type Props = { regions: Region[]; connectionInfo: Endpoint["connection_info"] | null; loading: boolean; - usage: { migrations: MigrationItem[]; replicas: ReplicaItem[] }; + transfers: TransferItem[], connectionInfoSchema: FieldType[]; onDeleteClick: () => void; onValidateClick: () => void; @@ -232,7 +230,7 @@ class EndpointDetailsContent extends React.Component { {items.map(item => ( - + {getTransferItemTitle(item)} @@ -250,9 +248,6 @@ class EndpointDetailsContent extends React.Component { created_at: createdAt, id, } = this.props.item || {}; - const usage: TransferItem[] = this.props.usage.replicas.concat( - this.props.usage.migrations as any[] - ); return ( @@ -293,8 +288,8 @@ class EndpointDetailsContent extends React.Component { )} - - {usage.length > 0 ? this.renderUsage(usage) : -} + + {this.props.transfers.length > 0 ? this.renderUsage(this.props.transfers) : -} {!this.props.connectionInfo ? this.renderConnectionInfoLoading() diff --git a/src/components/modules/LicenceModule/LicenceModule.tsx b/src/components/modules/LicenceModule/LicenceModule.tsx index 0078077d..a6e659a5 100644 --- a/src/components/modules/LicenceModule/LicenceModule.tsx +++ b/src/components/modules/LicenceModule/LicenceModule.tsx @@ -299,7 +299,7 @@ class LicenceModule extends React.Component { if ( new Date(info.earliestLicenceExpiryDate).getTime() < new Date().getTime() ) { - return "Please contact Cloudbase Solutions with your Appliance ID in order to obtain a Coriolis® licence"; + return "Please contact your Coriolis representative with the Appliance ID in order to obtain a Coriolis® licence"; } return ( @@ -346,7 +346,7 @@ class LicenceModule extends React.Component { - Read Coriolis© EULA + Read the Coriolis© EULA { defaultProps = { item: MINION_POOL_DETAILS_MOCK, itemId: "minion-pool-id", - replicas: [REPLICA_MOCK], + transfers: [REPLICA_MOCK], migrations: [], endpoints: [OPENSTACK_ENDPOINT_MOCK], schema: [ diff --git a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolDetailsContent.tsx b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolDetailsContent.tsx index c1deea95..36d9c096 100644 --- a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolDetailsContent.tsx +++ b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolDetailsContent.tsx @@ -20,7 +20,7 @@ import Button from "@src/components/ui/Button"; import DetailsNavigation from "@src/components/modules/NavigationModule/DetailsNavigation"; import type { Endpoint } from "@src/@types/Endpoint"; import type { Field } from "@src/@types/Field"; -import { ReplicaItem, MigrationItem } from "@src/@types/MainItem"; +import { TransferItem, DeploymentItem } from "@src/@types/MainItem"; import { MinionPoolDetails } from "@src/@types/MinionPool"; import StatusImage from "@src/components/ui/StatusComponents/StatusImage"; import { ThemeProps } from "@src/components/Theme"; @@ -75,8 +75,8 @@ const NavigationItems = [ type Props = { item?: MinionPoolDetails | null; itemId: string; - replicas: ReplicaItem[]; - migrations: MigrationItem[]; + transfers: TransferItem[]; + deployments: DeploymentItem[]; endpoints: Endpoint[]; schema: Field[]; schemaLoading: boolean; @@ -144,8 +144,8 @@ class MinionPoolDetailsContent extends React.Component { return ( ); } @@ -166,8 +166,8 @@ class MinionPoolDetailsContent extends React.Component { return ( { beforeEach(() => { defaultProps = { item: MINION_POOL_MOCK, - replicas: [REPLICA_MOCK], + transfers: [REPLICA_MOCK], migrations: [MIGRATION_MOCK], }; }); diff --git a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMachines.tsx b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMachines.tsx index adff097e..54234f0d 100644 --- a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMachines.tsx +++ b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMachines.tsx @@ -17,12 +17,12 @@ import { Collapse } from "react-collapse"; import { Link } from "react-router-dom"; import styled, { createGlobalStyle, css } from "styled-components"; -import { MigrationItem, ReplicaItem, TransferItem } from "@src/@types/MainItem"; +import { DeploymentItem, TransferItem, ActionItem } from "@src/@types/MainItem"; import { MinionMachine, MinionPool } from "@src/@types/MinionPool"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import Arrow from "@src/components/ui/Arrow"; import DropdownLink from "@src/components/ui/Dropdowns/DropdownLink"; -import { ItemReplicaBadge } from "@src/components/ui/Dropdowns/NotificationDropdown"; +import { ItemTransferBadge } from "@src/components/ui/Dropdowns/NotificationDropdown"; import StatusPill from "@src/components/ui/StatusComponents/StatusPill"; import DateUtils from "@src/utils/DateUtils"; @@ -144,8 +144,8 @@ const ValueLink = styled(Link)` type FilterType = "all" | "allocated" | "not-allocated"; type Props = { item?: MinionPool | null; - replicas: ReplicaItem[]; - migrations: MigrationItem[]; + transfers: TransferItem[]; + deployments: DeploymentItem[]; }; type State = { filterStatus: FilterType; @@ -278,11 +278,11 @@ class MinionPoolMachines extends React.Component { return ( {this.filteredMachines.map(machine => { - const findTransferItem = (transferItems: TransferItem[]) => + const findTransferItem = (transferItems: ActionItem[]) => transferItems.find(i => i.id === machine.allocated_action); const allocatedAction = machine.allocated_action - ? findTransferItem(this.props.replicas) || - findTransferItem(this.props.migrations) + ? findTransferItem(this.props.transfers) || + findTransferItem(this.props.deployments) : null; return ( @@ -329,11 +329,11 @@ class MinionPoolMachines extends React.Component { Allocated Action: {allocatedAction ? ( <> - - {allocatedAction.type === "replica" ? "RE" : "MI"} - + + {allocatedAction.type === "transfer" ? "TR" : "DE"} + {allocatedAction.instances[0]} diff --git a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.spec.tsx b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.spec.tsx index 9b71a09e..260f33f3 100644 --- a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.spec.tsx +++ b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.spec.tsx @@ -35,7 +35,7 @@ describe("MinionPoolMainDetails", () => { beforeEach(() => { defaultProps = { item: MINION_POOL_MOCK, - replicas: [REPLICA_MOCK], + transfers: [REPLICA_MOCK], migrations: [MIGRATION_MOCK], schema: [], schemaLoading: false, diff --git a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.tsx b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.tsx index 83658201..1d658e7c 100644 --- a/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.tsx +++ b/src/components/modules/MinionModule/MinionPoolDetailsContent/MinionPoolMainDetails.tsx @@ -18,7 +18,7 @@ import { Link } from "react-router-dom"; import styled, { css } from "styled-components"; import fieldHelper from "@src/@types/Field"; -import { MigrationItem, ReplicaItem, TransferItem } from "@src/@types/MainItem"; +import { DeploymentItem, TransferItem, ActionItem } from "@src/@types/MainItem"; import { MinionPool } from "@src/@types/MinionPool"; import EndpointLogos from "@src/components/modules/EndpointModule/EndpointLogos"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; @@ -101,8 +101,8 @@ const PropertyValue = styled.div` type Props = { item?: MinionPool | null; - replicas: ReplicaItem[]; - migrations: MigrationItem[]; + transfers: TransferItem[]; + deployments: DeploymentItem[]; schema: FieldType[]; schemaLoading: boolean; endpoints: Endpoint[]; @@ -178,8 +178,8 @@ class MinionPoolMainDetails extends React.Component { let properties: any[] = []; const plugin = endpoint && OptionsSchemaPlugin.for(endpoint.type); - const migrationImageMapFieldName = - plugin && plugin.migrationImageMapFieldName; + const deploymentImageMapFieldName = + plugin && plugin.deploymentImageMapFieldName; let dictionaryKey = ""; if (endpoint) { dictionaryKey = `${endpoint.type}-minion-pool`; @@ -202,8 +202,8 @@ class MinionPoolMainDetails extends React.Component { } let fieldName = pn; if ( - migrationImageMapFieldName && - fieldName === migrationImageMapFieldName + deploymentImageMapFieldName && + fieldName === deploymentImageMapFieldName ) { fieldName = p; } @@ -235,14 +235,18 @@ class MinionPoolMainDetails extends React.Component { ); } - renderUsage(items: TransferItem[]) { - return items.map(item => ( -
- + renderUsage(items: ActionItem[]) { + return items.map(item => { + const actionHref = + item.type === "transfer" + ? "transfers" : "deployments" + + return (
+ {item.instances[0]} -
- )); +
); + }); } renderTable() { @@ -263,8 +267,8 @@ class MinionPoolMainDetails extends React.Component { : []; }; - const usage: TransferItem[] = this.props.replicas.concat( - this.props.migrations as any[] + const usage: ActionItem[] = this.props.transfers.concat( + this.props.deployments as any[] ); return ( @@ -329,7 +333,7 @@ class MinionPoolMainDetails extends React.Component { ) : null} - + {usage.length > 0 ? this.renderUsage(usage) : -} diff --git a/src/components/modules/NavigationModule/Navigation/Navigation.tsx b/src/components/modules/NavigationModule/Navigation/Navigation.tsx index dc85271c..ca23a271 100644 --- a/src/components/modules/NavigationModule/Navigation/Navigation.tsx +++ b/src/components/modules/NavigationModule/Navigation/Navigation.tsx @@ -29,7 +29,7 @@ import cbsImage from "./images/cbsl-logo.svg"; import cbsImageSmall from "./images/cbsl-logo-small.svg"; import tinyLogo from "./images/logo-small.svg"; -import replicaImage from "./images/replica-menu.svg"; +import transferImage from "./images/transfer-menu.svg"; import endpointImage from "./images/endpoint-menu.svg"; import planningImage from "./images/planning-menu.svg"; import projectImage from "./images/project-menu.svg"; @@ -179,7 +179,7 @@ const SmallMenuItemBullet = styled.div` border-radius: 50%; position: absolute; left: -12px; - background: ${props => (props.bullet === "replica" ? "#E62565" : "#0044CA")}; + background: ${props => (props.bullet === "transfer" ? "#E62565" : "#0044CA")}; `; const MenuImage = styled.div` @@ -406,13 +406,13 @@ class Navigation extends React.Component { menuImage = dashboardImage; style = { width: "19px", height: "19px" }; break; - case "replicas": - bullet = "replica"; - menuImage = replicaImage; + case "transfers": + bullet = "transfer"; + menuImage = transferImage; break; - case "migrations": - bullet = "migration"; - menuImage = replicaImage; + case "deployments": + bullet = "deployment"; + menuImage = transferImage; break; case "endpoints": menuImage = endpointImage; diff --git a/src/components/modules/NavigationModule/Navigation/images/replica-menu.svg b/src/components/modules/NavigationModule/Navigation/images/deployments-menu.svg similarity index 100% rename from src/components/modules/NavigationModule/Navigation/images/replica-menu.svg rename to src/components/modules/NavigationModule/Navigation/images/deployments-menu.svg diff --git a/src/components/modules/NavigationModule/Navigation/images/transfer-menu.svg b/src/components/modules/NavigationModule/Navigation/images/transfer-menu.svg new file mode 100644 index 00000000..c5d049d3 --- /dev/null +++ b/src/components/modules/NavigationModule/Navigation/images/transfer-menu.svg @@ -0,0 +1,17 @@ + + + + + Created with Sketch. + + + + + + + + + + + + diff --git a/src/components/modules/TransferModule/DeleteReplicaModal/package.json b/src/components/modules/TransferModule/DeleteReplicaModal/package.json deleted file mode 100644 index e9ade791..00000000 --- a/src/components/modules/TransferModule/DeleteReplicaModal/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "DeleteReplicaModal", - "version": "0.0.0", - "private": true, - "main": "./DeleteReplicaModal.tsx" -} diff --git a/src/components/modules/TransferModule/DeleteReplicaModal/DeleteReplicaModal.spec.tsx b/src/components/modules/TransferModule/DeleteTransferModal/DeleteReplicaModal.spec.tsx similarity index 78% rename from src/components/modules/TransferModule/DeleteReplicaModal/DeleteReplicaModal.spec.tsx rename to src/components/modules/TransferModule/DeleteTransferModal/DeleteReplicaModal.spec.tsx index eb5348de..1c4ef29e 100644 --- a/src/components/modules/TransferModule/DeleteReplicaModal/DeleteReplicaModal.spec.tsx +++ b/src/components/modules/TransferModule/DeleteTransferModal/DeleteReplicaModal.spec.tsx @@ -17,27 +17,27 @@ import React from "react"; import { render } from "@testing-library/react"; import TestUtils from "@tests/TestUtils"; -import DeleteReplicaModal from "./"; +import DeleteTransferModal from "./DeleteTransferModal"; describe("DeleteReplicaModal", () => { - let defaultProps: DeleteReplicaModal["props"]; + let defaultProps: DeleteTransferModal["props"]; beforeEach(() => { defaultProps = { hasDisks: false, - onDeleteReplica: jest.fn(), + onDeleteTransfer: jest.fn(), onDeleteDisks: jest.fn(), onRequestClose: jest.fn(), }; }); it("renders without crashing", () => { - const { getByText } = render(); + const { getByText } = render(); expect(getByText("Delete Replica")).toBeTruthy(); }); it("renders with disks", () => { - render(); + render(); expect( TestUtils.select("DeleteReplicaModal__ExtraMessage")?.textContent ).toContain("has been executed at least once"); @@ -45,7 +45,7 @@ describe("DeleteReplicaModal", () => { it("is multiple replica selection with disks", () => { render( - + ); expect( TestUtils.select("DeleteReplicaModal__ExtraMessage")?.textContent @@ -53,7 +53,7 @@ describe("DeleteReplicaModal", () => { }); it("renders loading", () => { - render(); + render(); expect(TestUtils.select("DeleteReplicaModal__Loading")).toBeTruthy(); }); }); diff --git a/src/components/modules/TransferModule/DeleteReplicaModal/DeleteReplicaModal.tsx b/src/components/modules/TransferModule/DeleteTransferModal/DeleteTransferModal.tsx similarity index 74% rename from src/components/modules/TransferModule/DeleteReplicaModal/DeleteReplicaModal.tsx rename to src/components/modules/TransferModule/DeleteTransferModal/DeleteTransferModal.tsx index fa085c0b..e59068e0 100644 --- a/src/components/modules/TransferModule/DeleteReplicaModal/DeleteReplicaModal.tsx +++ b/src/components/modules/TransferModule/DeleteTransferModal/DeleteTransferModal.tsx @@ -71,43 +71,43 @@ const LoadingSubtitle = styled.div` type Props = { hasDisks: boolean; - isMultiReplicaSelection?: boolean; + isMultiTransferSelection?: boolean; loading?: boolean; - onDeleteReplica: () => void; + onDeleteTransfer: () => void; onDeleteDisks: () => void; onRequestClose: () => void; }; @observer -class DeleteReplicaModal extends React.Component { +class DeleteTransferModal extends React.Component { renderExtraMessage() { if (this.props.hasDisks) { - if (this.props.isMultiReplicaSelection) { + if (this.props.isMultiTransferSelection) { return ( - Some of the selected Replicas have been executed at least once and + Some of the selected Transfer have been executed at least once and thus may have disks created on the destination platform. If those - Replicas are to be deleted now, the disks on the destination will - persist. If this is not desired, please use the "Delete Replica + Transfers are to be deleted now, the disks on the destination will + persist. If this is not desired, please use the "Delete Transfer Disks" option to delete those disks before deleting the - Replicas themselves. + Transfers themselves. ); } return ( - This Replica has been executed at least once and thus may have disks - created on the destination platform. If the Replica is to be deleted + This Transfer has been executed at least once and thus may have disks + created on the destination platform. If the Transfer is to be deleted now, the disks on the destination will persist. If this is not - desired, please use the "Delete Replica Disks" option to - delete the disks before deleting the Replica itself. + desired, please use the "Delete Transfer Disks" option to + delete the disks before deleting the Transfer itself. ); } return ( - Deleting a Coriolis Replica is permanent! + Deleting a Coriolis Transfer is permanent! ); } @@ -116,7 +116,7 @@ class DeleteReplicaModal extends React.Component { - Validating Replicas Details + Validating Transfer Details Please wait ... @@ -124,9 +124,9 @@ class DeleteReplicaModal extends React.Component { } renderContent() { - const message = this.props.isMultiReplicaSelection - ? "Are you sure you want to delete the selected replicas?" - : "Are you sure you want to delete this replica?"; + const message = this.props.isMultiTransferSelection + ? "Are you sure you want to delete the selected transfers?" + : "Are you sure you want to delete this transfer?"; return ( @@ -145,11 +145,11 @@ class DeleteReplicaModal extends React.Component { style={{ marginBottom: "16px" }} alert > - Delete Replica Disks + Delete Transfer Disks ) : null} - @@ -158,9 +158,9 @@ class DeleteReplicaModal extends React.Component { } render() { - const title = this.props.isMultiReplicaSelection - ? "Delete Selected Replicas?" - : "Delete Replica?"; + const title = this.props.isMultiTransferSelection + ? "Delete Selected Transfers?" + : "Delete Transfer?"; return ( {this.props.loading ? this.renderLoading() : this.renderContent()} @@ -169,4 +169,4 @@ class DeleteReplicaModal extends React.Component { } } -export default DeleteReplicaModal; +export default DeleteTransferModal; diff --git a/src/components/modules/TransferModule/DeleteTransferModal/package.json b/src/components/modules/TransferModule/DeleteTransferModal/package.json new file mode 100644 index 00000000..4a59dc88 --- /dev/null +++ b/src/components/modules/TransferModule/DeleteTransferModal/package.json @@ -0,0 +1,6 @@ +{ + "name": "DeleteTransferModal", + "version": "0.0.0", + "private": true, + "main": "./DeleteTransferModal.tsx" +} diff --git a/src/components/modules/TransferModule/MigrationDetailsContent/MigrationDetailsContent.spec.tsx b/src/components/modules/TransferModule/DeploymentDetailsContent/DeploymentDetailsContent.spec.tsx similarity index 74% rename from src/components/modules/TransferModule/MigrationDetailsContent/MigrationDetailsContent.spec.tsx rename to src/components/modules/TransferModule/DeploymentDetailsContent/DeploymentDetailsContent.spec.tsx index c2e4bc9a..ef501fa3 100644 --- a/src/components/modules/TransferModule/MigrationDetailsContent/MigrationDetailsContent.spec.tsx +++ b/src/components/modules/TransferModule/DeploymentDetailsContent/DeploymentDetailsContent.spec.tsx @@ -1,5 +1,5 @@ /* -Copyright (C) 2023 Cloudbase Solutions SRL +Copyright (C) 2024 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the @@ -16,8 +16,8 @@ import React from "react"; import { render } from "@testing-library/react"; -import MigrationDetailsContent from "."; -import { MIGRATION_ITEM_DETAILS_MOCK } from "@tests/mocks/TransferMock"; +import DeploymentDetailsContent from "."; +import { DEPLOYMENT_ITEM_DETAILS_MOCK } from "@tests/mocks/TransferMock"; import { MINION_POOL_MOCK } from "@tests/mocks/MinionPoolMock"; import { STORAGE_BACKEND_MOCK } from "@tests/mocks/StoragesMock"; import { INSTANCE_MOCK } from "@tests/mocks/InstancesMock"; @@ -33,13 +33,13 @@ jest.mock("@src/components/modules/EndpointModule/EndpointLogos", () => ({ })); jest.mock("react-router-dom", () => ({ Link: "a" })); -describe("MigrationDetailsContent", () => { - let defaultProps: MigrationDetailsContent["props"]; +describe("DeploymentDetailsContent", () => { + let defaultProps: DeploymentDetailsContent["props"]; beforeEach(() => { defaultProps = { - item: MIGRATION_ITEM_DETAILS_MOCK, - itemId: MIGRATION_ITEM_DETAILS_MOCK.id, + item: DEPLOYMENT_ITEM_DETAILS_MOCK, + itemId: DEPLOYMENT_ITEM_DETAILS_MOCK.id, minionPools: [MINION_POOL_MOCK], detailsLoading: false, storageBackends: [STORAGE_BACKEND_MOCK], @@ -52,22 +52,22 @@ describe("MigrationDetailsContent", () => { destinationSchemaLoading: false, endpoints: [OPENSTACK_ENDPOINT_MOCK, VMWARE_ENDPOINT_MOCK], page: "", - onDeleteMigrationClick: jest.fn(), + onDeleteDeploymentClick: jest.fn(), }; }); it("renders without crashing", () => { - const { getByText } = render(); - expect(getByText(MIGRATION_ITEM_DETAILS_MOCK.id)).toBeTruthy(); + const { getByText } = render(); + expect(getByText(DEPLOYMENT_ITEM_DETAILS_MOCK.id)).toBeTruthy(); }); it("renders tasks page", () => { const { getByText } = render( - + ); expect( getByText( - MIGRATION_ITEM_DETAILS_MOCK.tasks[0].task_type.replace("_", " ") + DEPLOYMENT_ITEM_DETAILS_MOCK.tasks[0].task_type.replace("_", " ") ) ).toBeTruthy(); }); diff --git a/src/components/modules/TransferModule/MigrationDetailsContent/MigrationDetailsContent.tsx b/src/components/modules/TransferModule/DeploymentDetailsContent/DeploymentDetailsContent.tsx similarity index 90% rename from src/components/modules/TransferModule/MigrationDetailsContent/MigrationDetailsContent.tsx rename to src/components/modules/TransferModule/DeploymentDetailsContent/DeploymentDetailsContent.tsx index 27cb7711..ed316a0f 100644 --- a/src/components/modules/TransferModule/MigrationDetailsContent/MigrationDetailsContent.tsx +++ b/src/components/modules/TransferModule/DeploymentDetailsContent/DeploymentDetailsContent.tsx @@ -16,7 +16,7 @@ import { observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; -import { MigrationItemDetails } from "@src/@types/MainItem"; +import { DeploymentItemDetails } from "@src/@types/MainItem"; import { MinionPool } from "@src/@types/MinionPool"; import { Network } from "@src/@types/Network"; import DetailsNavigation from "@src/components/modules/NavigationModule/DetailsNavigation"; @@ -45,7 +45,7 @@ const DetailsBody = styled.div` const NavigationItems = [ { - label: "Migration", + label: "Deployment", value: "", }, { @@ -55,7 +55,7 @@ const NavigationItems = [ ]; type Props = { - item: MigrationItemDetails | null; + item: DeploymentItemDetails | null; itemId: string; minionPools: MinionPool[]; detailsLoading: boolean; @@ -69,15 +69,15 @@ type Props = { destinationSchemaLoading: boolean; endpoints: Endpoint[]; page: string; - onDeleteMigrationClick: () => void; + onDeleteDeploymentClick: () => void; }; @observer -class MigrationDetailsContent extends React.Component { +class DeploymentDetailsContent extends React.Component { renderBottomControls() { return ( - ); @@ -128,7 +128,7 @@ class MigrationDetailsContent extends React.Component { items={NavigationItems} selectedValue={this.props.page} itemId={this.props.itemId} - itemType="migration" + itemType="deployment" /> {this.renderMainDetails()} @@ -139,4 +139,4 @@ class MigrationDetailsContent extends React.Component { } } -export default MigrationDetailsContent; +export default DeploymentDetailsContent; diff --git a/src/components/modules/TransferModule/DeploymentDetailsContent/package.json b/src/components/modules/TransferModule/DeploymentDetailsContent/package.json new file mode 100644 index 00000000..fc28403a --- /dev/null +++ b/src/components/modules/TransferModule/DeploymentDetailsContent/package.json @@ -0,0 +1,6 @@ +{ + "name": "DeploymentDetailsContent", + "version": "0.0.0", + "private": true, + "main": "./DeploymentDetailsContent.tsx" +} diff --git a/src/components/modules/TransferModule/MigrationDetailsContent/story.tsx b/src/components/modules/TransferModule/DeploymentDetailsContent/story.tsx similarity index 90% rename from src/components/modules/TransferModule/MigrationDetailsContent/story.tsx rename to src/components/modules/TransferModule/DeploymentDetailsContent/story.tsx index 99a6e7f6..286605f1 100644 --- a/src/components/modules/TransferModule/MigrationDetailsContent/story.tsx +++ b/src/components/modules/TransferModule/DeploymentDetailsContent/story.tsx @@ -1,5 +1,5 @@ /* -Copyright (C) 2017 Cloudbase Solutions SRL +Copyright (C) 2024 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the @@ -16,7 +16,7 @@ along with this program. If not, see . import React from "react"; import { storiesOf } from "@storybook/react"; -import MigrationDetailsContent from "."; +import DeploymentDetailsContent from "."; const tasks: any = [ { @@ -64,12 +64,12 @@ const item: any = { map_1: "Mapping 1", }, }, - type: "Migration", + type: "Deployment", }; const props: any = {}; -storiesOf("MigrationDetailsContent", module) +storiesOf("DeploymentDetailsContent", module) .add("default", () => ( - )) .add("details loading", () => ( - )) .add("tasks", () => ( - . import { Field } from "@src/@types/Field"; -const replicaMigrationFields: Field[] = [ +const deploymentFields: Field[] = [ { name: "clone_disks", type: "boolean", @@ -30,4 +30,4 @@ const replicaMigrationFields: Field[] = [ }, ]; -export default replicaMigrationFields; +export default deploymentFields; diff --git a/src/components/modules/TransferModule/ReplicaMigrationOptions/ReplicaMigrationOptions.tsx b/src/components/modules/TransferModule/DeploymentOptions/DeploymentOptions.tsx similarity index 91% rename from src/components/modules/TransferModule/ReplicaMigrationOptions/ReplicaMigrationOptions.tsx rename to src/components/modules/TransferModule/DeploymentOptions/DeploymentOptions.tsx index 0dce1170..aca05ae0 100644 --- a/src/components/modules/TransferModule/ReplicaMigrationOptions/ReplicaMigrationOptions.tsx +++ b/src/components/modules/TransferModule/DeploymentOptions/DeploymentOptions.tsx @@ -1,5 +1,5 @@ /* -Copyright (C) 2017 Cloudbase Solutions SRL +Copyright (C) 2024 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the @@ -16,7 +16,7 @@ import { observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; -import { TransferItemDetails } from "@src/@types/MainItem"; +import { ActionItemDetails } from "@src/@types/MainItem"; import { MinionPool } from "@src/@types/MinionPool"; import { INSTANCE_OSMORPHING_MINION_POOL_MAPPINGS } from "@src/components/modules/WizardModule/WizardOptions"; import WizardScripts from "@src/components/modules/WizardModule/WizardScripts"; @@ -28,8 +28,8 @@ import ToggleButtonBar from "@src/components/ui/ToggleButtonBar"; import KeyboardManager from "@src/utils/KeyboardManager"; import LabelDictionary from "@src/utils/LabelDictionary"; -import replicaMigrationImage from "./images/replica-migration.svg"; -import replicaMigrationFields from "./replicaMigrationFields"; +import deploymentImage from "./images/deployment.svg"; +import deploymentFields from "./DeploymentFields"; import type { Field } from "@src/@types/Field"; import type { Instance, InstanceScript } from "@src/@types/Instance"; @@ -43,7 +43,7 @@ const Wrapper = styled.div` const Image = styled.div` ${ThemeProps.exactWidth("288px")} ${ThemeProps.exactHeight("96px")} - background: url('${replicaMigrationImage}') center no-repeat; + background: url('${deploymentImage}') center no-repeat; margin: 80px 0; `; const OptionsBody = styled.div` @@ -78,13 +78,13 @@ const FieldInputStyled = styled(FieldInput)` type Props = { instances: Instance[]; - transferItem: TransferItemDetails | null; + transferItem: ActionItemDetails | null; minionPools: MinionPool[]; loadingInstances: boolean; defaultSkipOsMorphing?: boolean | null; - migrating?: boolean; + deploying?: boolean; onCancelClick: () => void; - onMigrateClick: (opts: { + onDeployClick: (opts: { fields: Field[]; uploadedUserScripts: InstanceScript[]; removedUserScripts: InstanceScript[]; @@ -101,7 +101,7 @@ type State = { }; @observer -class ReplicaMigrationOptions extends React.Component { +class DeploymentOptions extends React.Component { state: State = { fields: [], selectedBarButton: "options", @@ -117,7 +117,7 @@ class ReplicaMigrationOptions extends React.Component { this.props.transferItem?.instance_osmorphing_minion_pool_mappings || {}; this.setState({ - fields: replicaMigrationFields.map(f => + fields: deploymentFields.map(f => f.name === "skip_os_morphing" ? { ...f, value: this.props.defaultSkipOsMorphing || null } : f @@ -128,9 +128,9 @@ class ReplicaMigrationOptions extends React.Component { componentDidMount() { KeyboardManager.onEnter( - "migration-options", + "deployment-options", () => { - this.migrate(); + this.deploy(); }, 2 ); @@ -145,11 +145,11 @@ class ReplicaMigrationOptions extends React.Component { } componentWillUnmount() { - KeyboardManager.removeKeyDown("migration-options"); + KeyboardManager.removeKeyDown("deployment-options"); } - migrate() { - this.props.onMigrateClick({ + deploy() { + this.props.onDeployClick({ fields: this.state.fields, uploadedUserScripts: this.state.uploadedScripts, removedUserScripts: this.state.removedScripts, @@ -323,15 +323,15 @@ class ReplicaMigrationOptions extends React.Component { - {this.props.migrating ? ( - Migrating ... + {this.props.deploying ? ( + Deploying ... ) : ( )} @@ -340,4 +340,4 @@ class ReplicaMigrationOptions extends React.Component { } } -export default ReplicaMigrationOptions; +export default DeploymentOptions; diff --git a/src/components/modules/TransferModule/ReplicaMigrationOptions/ReplicaMigrationOptions.spec.tsx b/src/components/modules/TransferModule/DeploymentOptions/ReplicaDeploymentOptions.spec.tsx similarity index 81% rename from src/components/modules/TransferModule/ReplicaMigrationOptions/ReplicaMigrationOptions.spec.tsx rename to src/components/modules/TransferModule/DeploymentOptions/ReplicaDeploymentOptions.spec.tsx index f78f5728..0ef9f3ec 100644 --- a/src/components/modules/TransferModule/ReplicaMigrationOptions/ReplicaMigrationOptions.spec.tsx +++ b/src/components/modules/TransferModule/DeploymentOptions/ReplicaDeploymentOptions.spec.tsx @@ -1,5 +1,5 @@ /* -Copyright (C) 2023 Cloudbase Solutions SRL +Copyright (C) 2024 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the @@ -21,7 +21,7 @@ import { MINION_POOL_MOCK } from "@tests/mocks/MinionPoolMock"; import { REPLICA_ITEM_DETAILS_MOCK } from "@tests/mocks/TransferMock"; import TestUtils from "@tests/TestUtils"; -import ReplicaMigrationOptions from "./"; +import ReplicaDeploymentOptions from "."; jest.mock("@src/plugins/default/ContentPlugin", () => jest.fn(() => null)); jest.mock("@src/components/modules/WizardModule/WizardScripts", () => ({ @@ -62,8 +62,8 @@ jest.mock("@src/components/modules/WizardModule/WizardScripts", () => ({ ), })); -describe("ReplicaMigrationOptions", () => { - let defaultProps: ReplicaMigrationOptions["props"]; +describe("ReplicaDeploymentOptions", () => { + let defaultProps: ReplicaDeploymentOptions["props"]; beforeEach(() => { defaultProps = { @@ -75,30 +75,30 @@ describe("ReplicaMigrationOptions", () => { ], loadingInstances: false, onCancelClick: jest.fn(), - onMigrateClick: jest.fn(), + onDeployClick: jest.fn(), onResizeUpdate: jest.fn(), }; }); it("renders without crashing", () => { - const { getByText } = render(); - expect(getByText("Migrate")).toBeTruthy(); + const { getByText } = render(); + expect(getByText("Deploy")).toBeTruthy(); }); it("executes on Enter", () => { - render(); + render(); fireEvent.keyDown(document.body, { key: "Enter" }); - expect(defaultProps.onMigrateClick).toHaveBeenCalled(); + expect(defaultProps.onDeployClick).toHaveBeenCalled(); }); it("calls onResizeUpdate on selectedBarButton state change", () => { - render(); + render(); fireEvent.click(TestUtils.selectAll("ToggleButtonBar__Item-")[1]); expect(defaultProps.onResizeUpdate).toHaveBeenCalled(); }); it("handles value change", () => { - render(); + render(); expect(TestUtils.select("Switch__Wrapper")?.textContent).toBe("Yes"); fireEvent.click(TestUtils.select("Switch__InputWrapper")!); expect(TestUtils.select("Switch__Wrapper")?.textContent).toBe("No"); @@ -106,7 +106,7 @@ describe("ReplicaMigrationOptions", () => { it("handles script operations", () => { const { getByTestId } = render( - + ); fireEvent.click(TestUtils.selectAll("ToggleButtonBar__Item-")[1]); fireEvent.click(getByTestId("ScriptsUpload")); @@ -128,15 +128,15 @@ describe("ReplicaMigrationOptions", () => { }); it("doesn't render minion pool mappings", () => { - const { rerender } = render(); + const { rerender } = render(); expect(document.body.textContent).toContain("Minion Pool Mappings"); - rerender(); + rerender(); expect(document.body.textContent).not.toContain("Minion Pool Mappings"); }); it("changes minion pool mappings value", () => { - render(); + render(); fireEvent.click(TestUtils.select("DropdownButton__Wrapper-")!); const dropdownItem = TestUtils.selectAll("Dropdown__ListItem-")[2]; expect(dropdownItem.textContent).toBe("Pool2"); @@ -147,8 +147,8 @@ describe("ReplicaMigrationOptions", () => { }); it("handles migrate click", () => { - const { getByText } = render(); - fireEvent.click(getByText("Migrate")); - expect(defaultProps.onMigrateClick).toHaveBeenCalled(); + const { getByText } = render(); + fireEvent.click(getByText("Deploy")); + expect(defaultProps.onDeployClick).toHaveBeenCalled(); }); }); diff --git a/src/components/modules/TransferModule/ReplicaMigrationOptions/images/replica-migration.svg b/src/components/modules/TransferModule/DeploymentOptions/images/deployment.svg similarity index 100% rename from src/components/modules/TransferModule/ReplicaMigrationOptions/images/replica-migration.svg rename to src/components/modules/TransferModule/DeploymentOptions/images/deployment.svg diff --git a/src/components/modules/TransferModule/DeploymentOptions/package.json b/src/components/modules/TransferModule/DeploymentOptions/package.json new file mode 100644 index 00000000..054fb709 --- /dev/null +++ b/src/components/modules/TransferModule/DeploymentOptions/package.json @@ -0,0 +1,6 @@ +{ + "name": "DeploymentOptions", + "version": "0.0.0", + "private": true, + "main": "./DeploymentOptions.tsx" +} diff --git a/src/components/modules/TransferModule/ReplicaMigrationOptions/story.tsx b/src/components/modules/TransferModule/DeploymentOptions/story.tsx similarity index 80% rename from src/components/modules/TransferModule/ReplicaMigrationOptions/story.tsx rename to src/components/modules/TransferModule/DeploymentOptions/story.tsx index 1eea2ca6..87e3cebb 100644 --- a/src/components/modules/TransferModule/ReplicaMigrationOptions/story.tsx +++ b/src/components/modules/TransferModule/DeploymentOptions/story.tsx @@ -1,5 +1,5 @@ /* -Copyright (C) 2017 Cloudbase Solutions SRL +Copyright (C) 2024 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the @@ -14,12 +14,12 @@ along with this program. If not, see . import React from "react"; import { storiesOf } from "@storybook/react"; -import ReplicaMigrationOptions from "."; +import ReplicaDeploymentOptions from "."; const props: any = {}; -storiesOf("ReplicaMigrationOptions", module).add("default", () => ( +storiesOf("ReplicaDeploymentOptions", module).add("default", () => ( // eslint-disable-next-line react/jsx-props-no-spreading
- +
)); diff --git a/src/components/modules/TransferModule/Executions/Executions.tsx b/src/components/modules/TransferModule/Executions/Executions.tsx index 9583a64a..231f7902 100644 --- a/src/components/modules/TransferModule/Executions/Executions.tsx +++ b/src/components/modules/TransferModule/Executions/Executions.tsx @@ -412,10 +412,10 @@ class Executions extends React.Component { - It looks like there are no executions in this replica. + It looks like there are no executions in this tranfer. - This replica has not been executed yet. + This tranfer has not been executed yet. diff --git a/src/components/modules/TransferModule/MainDetails/MainDetails.tsx b/src/components/modules/TransferModule/MainDetails/MainDetails.tsx index 3d476639..1932266d 100644 --- a/src/components/modules/TransferModule/MainDetails/MainDetails.tsx +++ b/src/components/modules/TransferModule/MainDetails/MainDetails.tsx @@ -18,7 +18,7 @@ import { Link } from "react-router-dom"; import styled, { css } from "styled-components"; import fieldHelper from "@src/@types/Field"; -import { TransferItem } from "@src/@types/MainItem"; +import { ActionItem } from "@src/@types/MainItem"; import { MinionPool } from "@src/@types/MinionPool"; import EndpointLogos from "@src/components/modules/EndpointModule/EndpointLogos"; import TransferDetailsTable from "@src/components/modules/TransferModule/TransferDetailsTable"; @@ -128,7 +128,7 @@ const PropertyValue = styled.div` `; type Props = { - item?: TransferItem | null; + item?: ActionItem | null; minionPools: MinionPool[]; storageBackends: StorageBackend[]; destinationSchema: FieldType[]; @@ -423,13 +423,13 @@ class MainDetails extends React.Component { ) : null} - {this.props.item?.type === "migration" && - this.props.item.replica_id ? ( + {this.props.item?.type === "deployment" && + this.props.item.transfer_id ? ( - - - {this.props.item.replica_id} + + + {this.props.item.transfer_id} diff --git a/src/components/modules/TransferModule/MigrationDetailsContent/package.json b/src/components/modules/TransferModule/MigrationDetailsContent/package.json deleted file mode 100644 index 3f60d51d..00000000 --- a/src/components/modules/TransferModule/MigrationDetailsContent/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "MigrationDetailsContent", - "version": "0.0.0", - "private": true, - "main": "./MigrationDetailsContent.tsx" -} diff --git a/src/components/modules/TransferModule/ReplicaDetailsContent/package.json b/src/components/modules/TransferModule/ReplicaDetailsContent/package.json deleted file mode 100644 index 340a812a..00000000 --- a/src/components/modules/TransferModule/ReplicaDetailsContent/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "ReplicaDetailsContent", - "version": "0.0.0", - "private": true, - "main": "./ReplicaDetailsContent.tsx" -} diff --git a/src/components/modules/TransferModule/ReplicaExecutionOptions/package.json b/src/components/modules/TransferModule/ReplicaExecutionOptions/package.json deleted file mode 100644 index 94805486..00000000 --- a/src/components/modules/TransferModule/ReplicaExecutionOptions/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "ReplicaExecutionOptions", - "version": "0.0.0", - "private": true, - "main": "./ReplicaExecutionOptions.tsx" -} diff --git a/src/components/modules/TransferModule/ReplicaMigrationOptions/package.json b/src/components/modules/TransferModule/ReplicaMigrationOptions/package.json deleted file mode 100644 index 5f158d0c..00000000 --- a/src/components/modules/TransferModule/ReplicaMigrationOptions/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "ReplicaMigrationOptions", - "version": "0.0.0", - "private": true, - "main": "./ReplicaMigrationOptions.tsx" -} diff --git a/src/components/modules/TransferModule/Schedule/Schedule.tsx b/src/components/modules/TransferModule/Schedule/Schedule.tsx index c95edd99..522a6b21 100644 --- a/src/components/modules/TransferModule/Schedule/Schedule.tsx +++ b/src/components/modules/TransferModule/Schedule/Schedule.tsx @@ -17,7 +17,7 @@ import { observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; -import ReplicaExecutionOptions from "@src/components/modules/TransferModule/ReplicaExecutionOptions"; +import TransferExecutionOptions from "@src/components/modules/TransferModule/TransferExecutionOptions"; import ScheduleItem from "@src/components/modules/TransferModule/ScheduleItem"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import AlertModal from "@src/components/ui/AlertModal"; @@ -318,13 +318,13 @@ class Schedule extends React.Component { {this.props.secondaryEmpty - ? "Schedule this Replica" - : "This Replica has no Schedules."} + ? "Schedule this Transfer" + : "This Transfer has no Schedules."} {this.props.secondaryEmpty - ? "You can schedule this replica so that it executes automatically." - : "Add a new schedule so that the Replica executes automatically."} + ? "You can schedule this Transfer so that it executes automatically." + : "Add a new schedule so that the Transfer executes automatically."} {this.props.adding ? ( Adding ... @@ -407,7 +407,7 @@ class Schedule extends React.Component { this.handleCloseOptionsModal(); }} > - { diff --git a/src/components/modules/TransferModule/ReplicaDetailsContent/ReplicaDetailsContent.spec.tsx b/src/components/modules/TransferModule/TransferDetailsContent/ReplicaDetailsContent.spec.tsx similarity index 98% rename from src/components/modules/TransferModule/ReplicaDetailsContent/ReplicaDetailsContent.spec.tsx rename to src/components/modules/TransferModule/TransferDetailsContent/ReplicaDetailsContent.spec.tsx index 12728dd4..0624df7f 100644 --- a/src/components/modules/TransferModule/ReplicaDetailsContent/ReplicaDetailsContent.spec.tsx +++ b/src/components/modules/TransferModule/TransferDetailsContent/ReplicaDetailsContent.spec.tsx @@ -31,7 +31,7 @@ import { NETWORK_MOCK } from "@tests/mocks/NetworksMock"; import { STORAGE_BACKEND_MOCK } from "@tests/mocks/StoragesMock"; import { REPLICA_ITEM_DETAILS_MOCK } from "@tests/mocks/TransferMock"; -import ReplicaDetailsContent from "./"; +import ReplicaDetailsContent from "."; const scheduleStoreMock = jest.createMockFromModule( "@src/stores/ScheduleStore" @@ -92,7 +92,7 @@ describe("ReplicaDetailsContent", () => { onCancelExecutionClick: jest.fn(), onDeleteExecutionClick: jest.fn(), onExecuteClick: jest.fn(), - onCreateMigrationClick: jest.fn(), + onCreateDeploymentClick: jest.fn(), onDeleteReplicaClick: jest.fn(), onAddScheduleClick: jest.fn(), onScheduleChange: jest.fn(), diff --git a/src/components/modules/TransferModule/ReplicaDetailsContent/ReplicaDetailsContent.tsx b/src/components/modules/TransferModule/TransferDetailsContent/TransferDetailsContent.tsx similarity index 93% rename from src/components/modules/TransferModule/ReplicaDetailsContent/ReplicaDetailsContent.tsx rename to src/components/modules/TransferModule/TransferDetailsContent/TransferDetailsContent.tsx index 013e295f..4cf1cf89 100644 --- a/src/components/modules/TransferModule/ReplicaDetailsContent/ReplicaDetailsContent.tsx +++ b/src/components/modules/TransferModule/TransferDetailsContent/TransferDetailsContent.tsx @@ -16,7 +16,7 @@ import { observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; -import { ReplicaItemDetails } from "@src/@types/MainItem"; +import { TransferItemDetails } from "@src/@types/MainItem"; import { MinionPool } from "@src/@types/MinionPool"; import DetailsNavigation from "@src/components/modules/NavigationModule/DetailsNavigation"; import Executions from "@src/components/modules/TransferModule/Executions"; @@ -59,7 +59,7 @@ const DetailsBody = styled.div` const NavigationItems = [ { - label: "Replica", + label: "Transfer", value: "", }, { @@ -74,7 +74,7 @@ const NavigationItems = [ type TimezoneValue = "utc" | "local"; type Props = { - item?: ReplicaItemDetails | null; + item?: TransferItemDetails | null; itemId: string; endpoints: Endpoint[]; sourceSchema: Field[]; @@ -100,8 +100,8 @@ type Props = { ) => void; onDeleteExecutionClick: (execution: Execution | null) => void; onExecuteClick: () => void; - onCreateMigrationClick: () => void; - onDeleteReplicaClick: () => void; + onCreateDeploymentClick: () => void; + onDeleteTransferClick: () => void; onAddScheduleClick: (schedule: ScheduleType) => void; onScheduleChange: ( scheduleId: string | null, @@ -115,7 +115,7 @@ type State = { timezone: TimezoneValue; }; @observer -class ReplicaDetailsContent extends React.Component { +class TransferDetailsContent extends React.Component { state: State = { timezone: "local", }; @@ -153,19 +153,19 @@ class ReplicaDetailsContent extends React.Component { disabled={this.getStatus() === "RUNNING"} onClick={this.props.onExecuteClick} > - Execute Replica + Execute - @@ -256,7 +256,7 @@ class ReplicaDetailsContent extends React.Component { items={NavigationItems} selectedValue={this.props.page} itemId={this.props.itemId} - itemType="replica" + itemType="transfer" /> {this.renderMainDetails()} @@ -268,4 +268,4 @@ class ReplicaDetailsContent extends React.Component { } } -export default ReplicaDetailsContent; +export default TransferDetailsContent; diff --git a/src/components/modules/TransferModule/TransferDetailsContent/package.json b/src/components/modules/TransferModule/TransferDetailsContent/package.json new file mode 100644 index 00000000..17f2b80d --- /dev/null +++ b/src/components/modules/TransferModule/TransferDetailsContent/package.json @@ -0,0 +1,6 @@ +{ + "name": "TransferDetailsContent", + "version": "0.0.0", + "private": true, + "main": "./TransferDetailsContent.tsx" +} diff --git a/src/components/modules/TransferModule/ReplicaDetailsContent/story.tsx b/src/components/modules/TransferModule/TransferDetailsContent/story.tsx similarity index 100% rename from src/components/modules/TransferModule/ReplicaDetailsContent/story.tsx rename to src/components/modules/TransferModule/TransferDetailsContent/story.tsx diff --git a/src/components/modules/TransferModule/TransferDetailsTable/TransferDetailsTable.tsx b/src/components/modules/TransferModule/TransferDetailsTable/TransferDetailsTable.tsx index 9f1ca9f7..ef2c51a8 100644 --- a/src/components/modules/TransferModule/TransferDetailsTable/TransferDetailsTable.tsx +++ b/src/components/modules/TransferModule/TransferDetailsTable/TransferDetailsTable.tsx @@ -20,7 +20,7 @@ import { EndpointUtils, StorageBackend } from "@src/@types/Endpoint"; import { isNetworkMapSecurityGroups, isNetworkMapSourceDest, - TransferItem, + ActionItem, TransferNetworkMap, } from "@src/@types/MainItem"; import { MinionPool } from "@src/@types/MinionPool"; @@ -156,7 +156,7 @@ export const ArrowIcon = styled.div` `; export type Props = { - item?: TransferItem | null; + item?: ActionItem | null; instancesDetails: Instance[]; networks?: Network[]; minionPools: MinionPool[]; @@ -338,7 +338,7 @@ class TransferDetailsTable extends React.Component { destinationBody = destinationBody.concat(getBody(transferDisk)); } } else if ( - this.props.item?.type === "migration" && + this.props.item?.type === "deployment" && (this.props.item.last_execution_status === "RUNNING" || this.props.item.last_execution_status === "AWAITING_MINION_ALLOCATIONS") @@ -446,7 +446,7 @@ class TransferDetailsTable extends React.Component { destinationBody = getBody(destinationNic); } } else if ( - this.props.item?.type === "migration" && + this.props.item?.type === "deployment" && (this.props.item.last_execution_status === "RUNNING" || this.props.item.last_execution_status === "AWAITING_MINION_ALLOCATIONS") @@ -501,7 +501,7 @@ class TransferDetailsTable extends React.Component { destinationName = transferResult.instance_name || transferResult.name; destinationBody = getBody(transferResult); } else if ( - this.props.item?.type === "migration" && + this.props.item?.type === "deployment" && (this.props.item.last_execution_status === "RUNNING" || this.props.item.last_execution_status === "AWAITING_MINION_ALLOCATIONS") ) { diff --git a/src/components/modules/TransferModule/ReplicaExecutionOptions/ReplicaExecutionOptions.spec.tsx b/src/components/modules/TransferModule/TransferExecutionOptions/ReplicaExecutionOptions.spec.tsx similarity index 98% rename from src/components/modules/TransferModule/ReplicaExecutionOptions/ReplicaExecutionOptions.spec.tsx rename to src/components/modules/TransferModule/TransferExecutionOptions/ReplicaExecutionOptions.spec.tsx index 40e11391..729a1b8a 100644 --- a/src/components/modules/TransferModule/ReplicaExecutionOptions/ReplicaExecutionOptions.spec.tsx +++ b/src/components/modules/TransferModule/TransferExecutionOptions/ReplicaExecutionOptions.spec.tsx @@ -17,7 +17,7 @@ import React from "react"; import { fireEvent, render } from "@testing-library/react"; import TestUtils from "@tests/TestUtils"; -import ReplicaExecutionOptions from "./"; +import ReplicaExecutionOptions from "."; jest.mock("@src/plugins/default/ContentPlugin", () => jest.fn(() => null)); diff --git a/src/components/modules/TransferModule/ReplicaExecutionOptions/ReplicaExecutionOptions.tsx b/src/components/modules/TransferModule/TransferExecutionOptions/TransferExecutionOptions.tsx similarity index 86% rename from src/components/modules/TransferModule/ReplicaExecutionOptions/ReplicaExecutionOptions.tsx rename to src/components/modules/TransferModule/TransferExecutionOptions/TransferExecutionOptions.tsx index d59f5a89..f8332dbf 100644 --- a/src/components/modules/TransferModule/ReplicaExecutionOptions/ReplicaExecutionOptions.tsx +++ b/src/components/modules/TransferModule/TransferExecutionOptions/TransferExecutionOptions.tsx @@ -25,6 +25,7 @@ import { executionOptions } from "@src/constants"; import type { Field } from "@src/@types/Field"; import executionImage from "./images/execution.svg"; +import LoadingButton from "@src/components/ui/LoadingButton/LoadingButton"; const Wrapper = styled.div` display: flex; @@ -56,6 +57,7 @@ type Props = { disableExecutionOptions: boolean; onChange?: (fieldName: string, fieldValue: string) => void; executionLabel: string; + executing?: boolean; onCancelClick: () => void; onExecuteClick: (options: Field[]) => void; }; @@ -63,9 +65,10 @@ type State = { fields: Field[]; }; @observer -class ReplicaExecutionOptions extends React.Component { +class TransferExecutionOptions extends React.Component { static defaultProps = { executionLabel: "Execute", + executing: false, }; state: State = { @@ -128,7 +131,7 @@ class ReplicaExecutionOptions extends React.Component { description={ this.props.disableExecutionOptions ? "The execution options are disabled for the source provider" - : "" + : LabelDictionary.getDescription(field.name) } /> ))} @@ -137,17 +140,21 @@ class ReplicaExecutionOptions extends React.Component { - + {this.props.executing ? ( + Executing ... + ) : ( + + )}
); } } -export default ReplicaExecutionOptions; +export default TransferExecutionOptions; diff --git a/src/components/modules/TransferModule/ReplicaExecutionOptions/images/execution.svg b/src/components/modules/TransferModule/TransferExecutionOptions/images/execution.svg similarity index 100% rename from src/components/modules/TransferModule/ReplicaExecutionOptions/images/execution.svg rename to src/components/modules/TransferModule/TransferExecutionOptions/images/execution.svg diff --git a/src/components/modules/TransferModule/TransferExecutionOptions/package.json b/src/components/modules/TransferModule/TransferExecutionOptions/package.json new file mode 100644 index 00000000..d3a07135 --- /dev/null +++ b/src/components/modules/TransferModule/TransferExecutionOptions/package.json @@ -0,0 +1,6 @@ +{ + "name": "TransferExecutionOptions", + "version": "0.0.0", + "private": true, + "main": "./TransferExecutionOptions.tsx" +} diff --git a/src/components/modules/TransferModule/ReplicaExecutionOptions/story.tsx b/src/components/modules/TransferModule/TransferExecutionOptions/story.tsx similarity index 100% rename from src/components/modules/TransferModule/ReplicaExecutionOptions/story.tsx rename to src/components/modules/TransferModule/TransferExecutionOptions/story.tsx diff --git a/src/components/modules/TransferModule/TransferItemModal/TransferItemModal.tsx b/src/components/modules/TransferModule/TransferItemModal/TransferItemModal.tsx index 7923e53b..ce9c4837 100644 --- a/src/components/modules/TransferModule/TransferItemModal/TransferItemModal.tsx +++ b/src/components/modules/TransferModule/TransferItemModal/TransferItemModal.tsx @@ -19,8 +19,7 @@ import styled from "styled-components"; import providerStore, { getFieldChangeOptions, } from "@src/stores/ProviderStore"; -import replicaStore from "@src/stores/ReplicaStore"; -import migrationStore from "@src/stores/MigrationStore"; +import transferStore from "@src/stores/TransferStore"; import endpointStore from "@src/stores/EndpointStore"; import { OptionsSchemaPlugin } from "@src/plugins"; @@ -39,8 +38,8 @@ import WizardStorage from "@src/components/modules/WizardModule/WizardStorage"; import type { UpdateData, - TransferItemDetails, - MigrationItemDetails, + ActionItemDetails, + DeploymentItemDetails, } from "@src/@types/MainItem"; import { Endpoint, @@ -57,7 +56,7 @@ import { SecurityGroup, } from "@src/@types/Network"; -import { providerTypes, migrationFields } from "@src/constants"; +import { providerTypes } from "@src/constants"; import configLoader from "@src/utils/Config"; import LoadingButton from "@src/components/ui/LoadingButton"; import minionPoolStore from "@src/stores/MinionPoolStore"; @@ -105,11 +104,11 @@ const Buttons = styled.div` type Width = "normal" | "wide"; type Props = { - type?: "replica" | "migration"; + type?: "transfer" | "deployment"; isOpen: boolean; onRequestClose: () => void; onUpdateComplete: (redirectTo: string) => void; - replica: TransferItemDetails; + transfer: ActionItemDetails; destinationEndpoint: Endpoint; sourceEndpoint: Endpoint; instancesDetails: Instance[]; @@ -187,7 +186,7 @@ class TransferItemModal extends React.Component { getStorageMap(storageBackends: StorageBackend[]): StorageMap[] { const storageMap: StorageMap[] = []; - const currentStorage = this.props.replica.storage_mappings; + const currentStorage = this.props.transfer.storage_mappings; const buildStorageMap = ( type: "backend" | "disk", mapping: any @@ -246,7 +245,7 @@ class TransferItemModal extends React.Component { getSelectedNetworks(): NetworkMap[] { const selectedNetworks: NetworkMap[] = []; - const networkMap: any = this.props.replica.network_map; + const networkMap: any = this.props.transfer.network_map; if (networkMap) { Object.keys(networkMap).forEach(sourceNetworkName => { @@ -334,8 +333,8 @@ class TransferItemModal extends React.Component { return defaultStorage; }; - if (this.props.replica.storage_mappings?.default) { - return buildDefaultStorage(this.props.replica.storage_mappings.default); + if (this.props.transfer.storage_mappings?.default) { + return buildDefaultStorage(this.props.transfer.storage_mappings.default); } if (endpointStore.storageConfigDefault) { @@ -354,8 +353,8 @@ class TransferItemModal extends React.Component { const currentData = type === "source" ? this.state.sourceData : this.state.destinationData; - const replicaMinionMappings = - this.props.replica[INSTANCE_OSMORPHING_MINION_POOL_MAPPINGS]; + const transferMinionMappings = + this.props.transfer[INSTANCE_OSMORPHING_MINION_POOL_MAPPINGS]; if (parentFieldName) { if ( @@ -366,10 +365,10 @@ class TransferItemModal extends React.Component { } if ( parentFieldName === INSTANCE_OSMORPHING_MINION_POOL_MAPPINGS && - replicaMinionMappings && - replicaMinionMappings[fieldName] !== undefined + transferMinionMappings && + transferMinionMappings[fieldName] !== undefined ) { - return replicaMinionMappings[fieldName]; + return transferMinionMappings[fieldName]; } } @@ -378,8 +377,8 @@ class TransferItemModal extends React.Component { } if (fieldName === "title") { - if (this.props.replica.notes) { - return this.props.replica.notes; + if (this.props.transfer.notes) { + return this.props.transfer.notes; } let title = this.props.instancesDetails?.[0]?.name; if ( @@ -393,22 +392,22 @@ class TransferItemModal extends React.Component { if (fieldName === "minion_pool_id") { return type === "source" - ? this.props.replica.origin_minion_pool_id - : this.props.replica.destination_minion_pool_id; + ? this.props.transfer.origin_minion_pool_id + : this.props.transfer.destination_minion_pool_id; } - const replicaData: any = + const transferData: any = type === "source" - ? this.props.replica.source_environment - : this.props.replica.destination_environment; + ? this.props.transfer.source_environment + : this.props.transfer.destination_environment; if (parentFieldName) { - if (replicaData[parentFieldName]?.[fieldName] !== undefined) { - return replicaData[parentFieldName][fieldName]; + if (transferData[parentFieldName]?.[fieldName] !== undefined) { + return transferData[parentFieldName][fieldName]; } } - if (replicaData[fieldName] !== undefined) { - return replicaData[fieldName]; + if (transferData[fieldName] !== undefined) { + return transferData[fieldName]; } const endpoint = type === "source" @@ -419,16 +418,10 @@ class TransferItemModal extends React.Component { const osMapping = /^(windows|linux)/.exec(fieldName); if (osMapping) { const osData = - replicaData[`${plugin.migrationImageMapFieldName}/${osMapping[0]}`]; + transferData[`${plugin.migrationImageMapFieldName}/${osMapping[0]}`]; return osData; } - const anyData = this.props.replica as any; - if (migrationFields.find(f => f.name === fieldName) && anyData[fieldName]) { - return anyData[fieldName]; - } - if (fieldName === "skip_os_morphing" && this.props.type === "migration") { - return migrationStore.getDefaultSkipOsMorphing(anyData); - } + return defaultValue; } @@ -474,11 +467,9 @@ class TransferItemModal extends React.Component { useCache, }); } catch (err) { - if (optionsType === "destination" || this.props.type === "migration") { + if (optionsType === "destination") { const destinationFailedMessage = - this.props.type === "replica" - ? "An error has occurred during the loading of the Replica's options for editing. There could be connection issues with the destination platform. Please retry the operation." - : "An error has occurred during loading of the source or destination platforms' environment options for editing of the Migration's parameters. You may still recreate the Migration with the same parameters as the original one by clicking \"Create\"."; + "An error has occurred during the loading of the Transfer's options for editing. There could be connection issues with the destination platform. Please retry the operation."; this.setState({ destinationFailedMessage }); } throw err; @@ -505,8 +496,8 @@ class TransferItemModal extends React.Component { : this.props.destinationEndpoint; const env = ObjectUtils.clone( type === "source" - ? this.props.replica.source_environment - : this.props.replica.destination_environment + ? this.props.transfer.source_environment + : this.props.transfer.destination_environment ); const stateEnv = type === "source" ? this.state.sourceData : this.state.destinationData; @@ -555,7 +546,7 @@ class TransferItemModal extends React.Component { isUpdateDisabled() { const isDestFailed = - this.props.type === "replica" && this.state.destinationFailedMessage; + this.props.type === "transfer" && this.state.destinationFailedMessage; return this.state.updateDisabled || isDestFailed; } @@ -593,8 +584,8 @@ class TransferItemModal extends React.Component { validateOptions(type: "source" | "destination") { const env = ObjectUtils.clone( type === "source" - ? this.props.replica.source_environment - : this.props.replica.destination_environment + ? this.props.transfer.source_environment + : this.props.transfer.destination_environment ); const data = @@ -632,13 +623,13 @@ class TransferItemModal extends React.Component { ? { ...this.state.sourceData } : { ...this.state.destinationData }; - const replicaData: any = + const transferData: any = type === "source" - ? this.props.replica.source_environment - : this.props.replica.destination_environment; + ? this.props.transfer.source_environment + : this.props.transfer.destination_environment; if (field.type === "array") { const currentValues: string[] = data[field.name] || []; - const oldValues: string[] = replicaData[field.name] || []; + const oldValues: string[] = transferData[field.name] || []; let values: string[] = currentValues; if (!currentValues.length) { values = [...oldValues]; @@ -658,7 +649,7 @@ class TransferItemModal extends React.Component { // existing fields from Object options from the previous Migration/Replica, // we always re-merge all the values on an object field update. data[parentFieldName] = - data[parentFieldName] || replicaData[parentFieldName] || {}; + data[parentFieldName] || transferData[parentFieldName] || {}; data[parentFieldName][field.name] = value; } else { data[field.name] = value; @@ -706,51 +697,21 @@ class TransferItemModal extends React.Component { uploadedScripts: this.state.uploadedScripts, removedScripts: this.state.removedScripts, }; - if (this.props.type === "replica") { - try { - await replicaStore.update({ - replica: this.props.replica as any, - sourceEndpoint: this.props.sourceEndpoint, - destinationEndpoint: this.props.destinationEndpoint, - updateData, - defaultStorage: this.getDefaultStorage(), - storageConfigDefault: endpointStore.storageConfigDefault, - }); - this.props.onRequestClose(); - this.props.onUpdateComplete( - `/replicas/${this.props.replica.id}/executions` - ); - } catch (err) { - this.setState({ updating: false }); - } - } else { - try { - const defaultStorage = EndpointUtils.getBusTypeStorageId( - endpointStore.storageBackends, - this.props.replica.storage_mappings?.default || null - ); - const replicaDefaultStorage: { - value: string | null; - busType?: string | null; - } = { - value: defaultStorage.id, - busType: defaultStorage.busType, - }; - const migration: MigrationItemDetails = await migrationStore.recreate({ - migration: this.props.replica as any, - sourceEndpoint: this.props.sourceEndpoint, - destEndpoint: this.props.destinationEndpoint, - updateData, - defaultStorage: replicaDefaultStorage, - updatedDefaultStorage: this.state.defaultStorage, - replicationCount: this.props.replica.replication_count, - }); - migrationStore.clearDetails(); - this.props.onRequestClose(); - this.props.onUpdateComplete(`/migrations/${migration.id}/tasks`); - } catch (err) { - this.setState({ updating: false }); - } + try { + await transferStore.update({ + transfer: this.props.transfer as any, + sourceEndpoint: this.props.sourceEndpoint, + destinationEndpoint: this.props.destinationEndpoint, + updateData, + defaultStorage: this.getDefaultStorage(), + storageConfigDefault: endpointStore.storageConfigDefault, + }); + this.props.onRequestClose(); + this.props.onUpdateComplete( + `/transfers/${this.props.transfer.id}/executions` + ); + } catch (err) { + this.setState({ updating: false }); } } @@ -842,7 +803,7 @@ class TransferItemModal extends React.Component { ? providerStore.sourceSchema : providerStore.destinationSchema; const fields = - this.props.type === "replica" ? schema.filter(f => !f.readOnly) : schema; + this.props.type === "transfer" ? schema.filter(f => !f.readOnly) : schema; const extraOptionsConfig = configLoader.config.extraOptionsApiCalls.find( o => { const provider = @@ -870,7 +831,7 @@ class TransferItemModal extends React.Component { return ( this.getFieldValue({ type, @@ -918,7 +879,6 @@ class TransferItemModal extends React.Component { "description", "execute_now", "execute_now_options", - ...migrationFields.map(f => f.name), ]} dictionaryKey={dictionaryKey} executeNowOptionsDisabled={ @@ -989,7 +949,7 @@ class TransferItemModal extends React.Component { }} uploadedScripts={this.state.uploadedScripts} removedScripts={this.state.removedScripts} - userScriptData={this.props.replica?.user_scripts} + userScriptData={this.props.transfer?.user_scripts} scrollableRef={(r: HTMLElement) => { this.scrollableRef = r; }} @@ -1030,7 +990,7 @@ class TransferItemModal extends React.Component { Loading ... ) : this.state.updating ? ( - {this.props.type === "replica" ? "Updating" : "Creating"} ... + {this.props.type === "transfer" ? "Updating" : "Creating"} ... ) : ( )} @@ -1098,9 +1058,7 @@ class TransferItemModal extends React.Component { return ( this.scrollableRef} @@ -1117,11 +1075,7 @@ class TransferItemModal extends React.Component { onReloadClick={() => { this.handleReload(); }} - reloadLabel={ - this.props.type === "replica" - ? "Reload All Replica Options" - : "Reload All Migration Options" - } + reloadLabel="Reload All Options" /> ); diff --git a/src/components/modules/TransferModule/TransferListItem/TransferListItem.tsx b/src/components/modules/TransferModule/TransferListItem/TransferListItem.tsx index 4ad6ee16..c9c35a98 100644 --- a/src/components/modules/TransferModule/TransferListItem/TransferListItem.tsx +++ b/src/components/modules/TransferModule/TransferListItem/TransferListItem.tsx @@ -16,7 +16,7 @@ import { observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; -import { getTransferItemTitle, TransferItem } from "@src/@types/MainItem"; +import { getTransferItemTitle, ActionItem } from "@src/@types/MainItem"; import EndpointLogos from "@src/components/modules/EndpointModule/EndpointLogos"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import Checkbox from "@src/components/ui/Checkbox"; @@ -106,10 +106,10 @@ const Column = styled.div` `; type Props = { - item: TransferItem; + item: ActionItem; onClick: () => void; selected: boolean; - image: string; + getListItemImage: (item: ActionItem) => string; showScheduleIcon?: boolean; endpointType: (endpointId: string) => string; getUserName: (userId: string) => string | undefined; @@ -122,6 +122,20 @@ class TransferListItem extends React.Component { return this.props.item.last_execution_status; } + getTransferScenarioType() { + let scenario = ""; + switch(this.props.item.type) { + case "transfer": + scenario = this.props.item.scenario; + break; + case "deployment": + scenario = this.props.item.transfer_scenario; + break; + default: + } + return scenario; + } + renderCreationDate() { return ( { onChange={this.props.onSelectedChange} /> - + <TitleLabel>{getTransferItemTitle(this.props.item)}</TitleLabel> <StatusWrapper> @@ -204,7 +218,7 @@ class TransferListItem extends React.Component<Props> { <StatusPill status={status} style={{ marginRight: "8px" }} /> ) : null} {this.props.showScheduleIcon ? ( - <ScheduleImage data-tip="The Replica has scheduling enabled and will execute automatically" /> + <ScheduleImage data-tip="The Transfer has scheduling enabled and will execute automatically" /> ) : null} </StatusWrapper> diff --git a/src/components/modules/WizardModule/WizardOptions/WizardOptions.tsx b/src/components/modules/WizardModule/WizardOptions/WizardOptions.tsx index 56069435..8e5752a2 100644 --- a/src/components/modules/WizardModule/WizardOptions/WizardOptions.tsx +++ b/src/components/modules/WizardModule/WizardOptions/WizardOptions.tsx @@ -24,7 +24,7 @@ import { ThemePalette, ThemeProps } from "@src/components/Theme"; import FieldInput from "@src/components/ui/FieldInput"; import StatusImage from "@src/components/ui/StatusComponents/StatusImage"; import ToggleButtonBar from "@src/components/ui/ToggleButtonBar"; -import { executionOptions, migrationFields } from "@src/constants"; +import { executionOptions } from "@src/constants"; import { MinionPoolStoreUtils } from "@src/stores/MinionPoolStore"; import configLoader from "@src/utils/Config"; import LabelDictionary from "@src/utils/LabelDictionary"; @@ -297,10 +297,7 @@ class WizardOptions extends React.Component { }); } - if ( - this.props.wizardType === "migration" || - this.props.wizardType === "migration-destination-options-edit" - ) { + if (this.props.wizardType === "migration-destination-options-edit") { fieldsSchema.push({ name: "skip_os_morphing", type: "boolean", @@ -331,7 +328,7 @@ class WizardOptions extends React.Component { fieldsSchema.push(titleFieldSchema); } - if (this.props.wizardType === "replica") { + if (this.props.wizardType === "replica" || this.props.wizardType === "migration") { fieldsSchema.push({ name: "execute_now", type: "boolean", @@ -350,23 +347,6 @@ class WizardOptions extends React.Component { ? "Enable 'Execute Now' to set 'Execute Now Options'" : `Set the options for ${this.props.wizardType} execution`, }); - } else if ( - this.props.wizardType === "migration" || - this.props.wizardType === "migration-destination-options-edit" - ) { - const shutdownInstanceField = migrationFields.find( - f => f.name === "shutdown_instances" - )!; - shutdownInstanceField.disabled = this.props.executeNowOptionsDisabled; - shutdownInstanceField.description = this.props.executeNowOptionsDisabled - ? "The 'Shutdown Instances' option is disabled for the source provider" - : shutdownInstanceField.description; - fieldsSchema = [ - ...fieldsSchema, - ...migrationFields.map(f => - f.name === "shutdown_instances" ? shutdownInstanceField : f - ), - ]; } return fieldsSchema; diff --git a/src/components/modules/WizardModule/WizardPageContent/WizardPageContent.tsx b/src/components/modules/WizardModule/WizardPageContent/WizardPageContent.tsx index 7601ef48..bdad4437 100644 --- a/src/components/modules/WizardModule/WizardPageContent/WizardPageContent.tsx +++ b/src/components/modules/WizardModule/WizardPageContent/WizardPageContent.tsx @@ -35,7 +35,7 @@ import { ThemePalette, ThemeProps } from "@src/components/Theme"; import Button from "@src/components/ui/Button"; import InfoIcon from "@src/components/ui/InfoIcon"; import LoadingButton from "@src/components/ui/LoadingButton"; -import { migrationFields, providerTypes, wizardPages } from "@src/constants"; +import { providerTypes, wizardPages } from "@src/constants"; import endpointStore from "@src/stores/EndpointStore"; import instanceStore from "@src/stores/InstanceStore"; import minionPoolStore from "@src/stores/MinionPoolStore"; @@ -197,8 +197,8 @@ class WizardPageContent extends React.Component { getProvidersType(type: string) { return type === "source" - ? providerTypes.SOURCE_REPLICA - : providerTypes.TARGET_REPLICA; + ? providerTypes.SOURCE_TRANSFER + : providerTypes.TARGET_TRANSFER; } getProviders(direction: string): ProviderTypes[] { @@ -524,7 +524,6 @@ class WizardPageContent extends React.Component { "title", "execute_now", "execute_now_options", - ...migrationFields.map(f => f.name), ]} selectedInstances={this.props.wizardData.selectedInstances} showSeparatePerVm={Boolean( diff --git a/src/components/modules/WizardModule/WizardSummary/WizardSummary.tsx b/src/components/modules/WizardModule/WizardSummary/WizardSummary.tsx index 7582d34f..41ad90aa 100644 --- a/src/components/modules/WizardModule/WizardSummary/WizardSummary.tsx +++ b/src/components/modules/WizardModule/WizardSummary/WizardSummary.tsx @@ -24,7 +24,6 @@ import { INSTANCE_OSMORPHING_MINION_POOL_MAPPINGS } from "@src/components/module import { getDisks } from "@src/components/modules/WizardModule/WizardStorage"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import StatusPill from "@src/components/ui/StatusComponents/StatusPill"; -import { migrationFields } from "@src/constants"; import configLoader from "@src/utils/Config"; import DateUtils from "@src/utils/DateUtils"; import LabelDictionary from "@src/utils/LabelDictionary"; @@ -448,25 +447,6 @@ class WizardSummary extends React.Component { ); - const migrationOptions = [ - , - , - ]; - const renderDefaultStorageOption = () => (