diff --git a/webapp/component/HyokCryptoRoleAdd.ts b/webapp/component/HyokCryptoRoleAdd.ts new file mode 100644 index 0000000..d0d9418 --- /dev/null +++ b/webapp/component/HyokCryptoRoleAdd.ts @@ -0,0 +1,317 @@ +import { AWScertificates, AWSAccessDetails } from 'kms/common/Types'; +import { showErrorMessage } from 'kms/common/Helpers'; +import { AxiosError } from 'axios'; +import BaseController from 'kms/controller/BaseController'; +import DetailPanel from 'kms/controller/keyConfigs/detail/DetailPanel.controller'; +import Api from 'kms/services/Api.service'; +import Dialog from 'sap/m/Dialog'; +import MessageBox from 'sap/m/MessageBox'; +import Fragment from 'sap/ui/core/Fragment'; +import JSONModel from 'sap/ui/model/json/JSONModel'; +import { Button$PressEvent } from 'sap/m/Button'; + +interface AddCryptoCertsParams { + keyId: string + keyConfigId: string + existingCrypto: Record | undefined +} + +type OnSaveCallbackFn = () => Promise; + +interface HYOKAWScertificates { + tenantDefault: { + count: number + value: AWScertificates[] + } + crypto: { + count: number + value: AWScertificates[] + } +} + +interface CommittedCertEntry { + selectedCertName: string + trustAnchorCryptoARN: string + roleCryptoARN: string + rootCryptoCA: string +} + +export default class HyokCryptoRoleAdd extends BaseController { + private readonly addCryptoModel = new JSONModel({ + allCryptoCerts: [] as AWScertificates[], + availableCryptoCertsSelectionList: [] as AWScertificates[], + newCryptoCertGroups: [] as CommittedCertEntry[], + allowAddMoreCryptoCert: false, + hasCommittedCerts: false, + showAllCertsAssignedMessage: false, + certSelected: false, + currentSelectedCertKey: '', + currentCert: null as AWScertificates | null, + currentTrustAnchorARN: '', + currentRoleARN: '', + currentProfileARN: '' + }); + + private api: Api; + private dialog: Dialog | undefined; + private parentController: DetailPanel; + private keyId: string; + private keyConfigId: string; + private existingCrypto: Record | undefined; + private onSaveCallback: OnSaveCallbackFn; + + public openAddCryptoCertsDialog(params: AddCryptoCertsParams, parentController: DetailPanel, api: Api, onSaveCallback: OnSaveCallbackFn): void { + this.keyId = params.keyId; + this.keyConfigId = params.keyConfigId; + this.existingCrypto = params.existingCrypto; + this.api = api; + this.parentController = parentController; + this.onSaveCallback = onSaveCallback; + this.loadDialog(); + } + + private loadDialog(): void { + const fragmentName = 'kms.resources.fragments.common.HYOKAddCryptoCertsDialog'; + const loadFragment = async (): Promise => { + this.dialog = await Fragment.load({ + id: 'addCryptoCertsDialog', + name: fragmentName, + controller: this + }) as Dialog; + this.parentController?.getView()?.addDependent(this.dialog); + this.dialog.addStyleClass('sapUiSizeCompact'); + this.dialog.setModel(this.addCryptoModel, 'addCryptoModel'); + this.dialog.open(); + this.resetModel(); + }; + + if (!this.dialog) { + loadFragment().catch((err: unknown) => { + console.error('Error loading add crypto certs dialog fragment:', err); + showErrorMessage(err as AxiosError, this.parentController.getText('errorLoadingAddCryptoCertsDialog')); + this.dialog?.destroy(); + this.dialog = undefined; + }); + } + else { + this.dialog?.destroy(); + loadFragment().catch((err: unknown) => { + console.error('Error loading add crypto certs dialog fragment:', err); + showErrorMessage(err as AxiosError, this.parentController.getText('errorLoadingAddCryptoCertsDialog')); + this.dialog?.destroy(); + this.dialog = undefined; + }); + } + } + + private resetModel(): void { + this.dialog?.setBusy(true); + this.fetchAvailableCryptoCerts().then((allCryptoCerts: AWScertificates[]) => { + const existingCryptoKeys = Object.keys(this.existingCrypto || {}); + const availableCerts = allCryptoCerts.filter(cert => !existingCryptoKeys.includes(cert.name)); + + this.addCryptoModel.setData({ + allCryptoCerts: allCryptoCerts, + availableCryptoCertsSelectionList: availableCerts, + newCryptoCertGroups: [], + allowAddMoreCryptoCert: availableCerts.length > 0, + hasCommittedCerts: false, + showAllCertsAssignedMessage: false, + certSelected: false, + currentSelectedCertKey: '', + currentCert: null, + currentTrustAnchorARN: '', + currentRoleARN: '', + currentProfileARN: '' + }); + }).catch((err: unknown) => { + showErrorMessage(err as AxiosError, this.parentController.getText('errorFetchingHYOKCertificates')); + this.closeDialog(); + console.error('Error fetching HYOK AWS certificates:', err); + }).finally(() => { + this.dialog?.setBusy(false); + }); + } + + private async fetchAvailableCryptoCerts(): Promise { + const hyokAWScertificates = await this.api.get(`keyConfigurations/${this.keyConfigId}/certificates`); + return hyokAWScertificates?.crypto?.value ?? []; + } + + public onAddCryptoCertsDialogCancelPress(): void { + MessageBox.warning(this.parentController.getText('confirmCancelAddCryptoCerts'), { + styleClass: 'sapUiSizeCompact', + emphasizedAction: MessageBox.Action.NO, + actions: [MessageBox.Action.YES, MessageBox.Action.NO], + onClose: (action: unknown) => { + if (action === MessageBox.Action.YES) { + this.closeDialog(); + } + } + }); + } + + /** + * Called when user selects a certificate from the Select dropdown. + * Transitions to Step 2: shows cert details + ARN input fields. + */ + public onCryptoCertSelected(): void { + const selectedKey = this.addCryptoModel.getProperty('/currentSelectedCertKey') as string; + if (!selectedKey) { + return; + } + const allCryptoCerts = this.addCryptoModel.getProperty('/allCryptoCerts') as AWScertificates[]; + const selectedCert = allCryptoCerts.find(cert => cert.name === selectedKey); + + if (!selectedCert) { + return; + } + + this.addCryptoModel.setProperty('/currentCert', selectedCert); + this.addCryptoModel.setProperty('/certSelected', true); + this.addCryptoModel.setProperty('/currentTrustAnchorARN', ''); + this.addCryptoModel.setProperty('/currentRoleARN', ''); + this.addCryptoModel.setProperty('/currentProfileARN', ''); + } + + /** + * Called when user clicks "Add" to commit the current cert + ARNs. + * Adds the entry to newCryptoCertGroups, removes cert from available list, + * and resets to Step 1 for the next cert. + */ + public onCommitCurrentCert(): void { + const currentCert = this.addCryptoModel.getProperty('/currentCert') as AWScertificates; + const trustAnchorARN = this.addCryptoModel.getProperty('/currentTrustAnchorARN') as string; + const roleARN = this.addCryptoModel.getProperty('/currentRoleARN') as string; + const profileARN = this.addCryptoModel.getProperty('/currentProfileARN') as string; + + if (!currentCert) { + return; + } + + const newEntry: CommittedCertEntry = { + selectedCertName: currentCert.name, + trustAnchorCryptoARN: trustAnchorARN, + roleCryptoARN: roleARN, + rootCryptoCA: profileARN + }; + + // Add to committed list + const newCryptoCertGroups = this.addCryptoModel.getProperty('/newCryptoCertGroups') as CommittedCertEntry[]; + this.addCryptoModel.setProperty('/newCryptoCertGroups', [...newCryptoCertGroups, newEntry]); + + // Remove from available list + let availableList = this.addCryptoModel.getProperty('/availableCryptoCertsSelectionList') as AWScertificates[]; + availableList = availableList.filter(cert => cert.name !== currentCert.name); + this.addCryptoModel.setProperty('/availableCryptoCertsSelectionList', availableList); + this.addCryptoModel.setProperty('/allowAddMoreCryptoCert', availableList.length > 0); + + // Update computed flags and reset current selection state back to Step 1 + this.updateComputedFlags(); + this.resetCurrentSelection(); + } + + /** + * Called when user clicks "Cancel" on the current cert ARN entry. + * Goes back to Step 1 without adding the cert. + */ + public onCancelCurrentCertSelection(): void { + this.resetCurrentSelection(); + } + + /** + * Removes a committed cert entry and returns the cert to the available list. + */ + public onRemoveNewCryptoCertGroup(event: Button$PressEvent): void { + const path = event.getSource().getBindingContext('addCryptoModel')?.getPath(); + if (!path) { + console.error('Error removing crypto cert group: Invalid binding context path'); + showErrorMessage(new AxiosError('Invalid binding context path'), this.parentController.getText('errorGeneric')); + return; + } + const segments = path.split('/'); + const lastSegment = segments[segments.length - 1]; + const index = parseInt(lastSegment, 10); + + const newCryptoCertGroups = this.addCryptoModel.getProperty('/newCryptoCertGroups') as CommittedCertEntry[]; + const removedEntry = newCryptoCertGroups[index]; + const newArray = newCryptoCertGroups.filter((_, i) => i !== index); + this.addCryptoModel.setProperty('/newCryptoCertGroups', newArray); + + // Return removed cert to available list + if (removedEntry) { + const allCryptoCerts = this.addCryptoModel.getProperty('/allCryptoCerts') as AWScertificates[]; + const removedCert = allCryptoCerts.find(cert => cert.name === removedEntry.selectedCertName); + if (removedCert) { + const availableList = this.addCryptoModel.getProperty('/availableCryptoCertsSelectionList') as AWScertificates[]; + this.addCryptoModel.setProperty('/availableCryptoCertsSelectionList', [...availableList, removedCert]); + this.addCryptoModel.setProperty('/allowAddMoreCryptoCert', true); + } + } + this.updateComputedFlags(); + } + + public async onAddCryptoCertsSubmitPress(): Promise { + this.dialog?.setBusy(true); + try { + const newCryptoPayload = this.buildCryptoPayload(); + const payload = { + accessDetails: { + crypto: newCryptoPayload + } + }; + await this.api.patch(`keys/${this.keyId}`, payload); + await this.onSaveCallback(); + this.closeDialog(); + } + catch (error) { + console.error('Error adding crypto certs', error); + showErrorMessage(error as AxiosError, this.parentController.getText('errorSavingKeyDetails')); + } + finally { + this.dialog?.setBusy(false); + } + } + + private buildCryptoPayload(): Record { + const cryptoPayload: Record = { ...this.existingCrypto }; + const newCryptoCertGroups = this.addCryptoModel.getProperty('/newCryptoCertGroups') as CommittedCertEntry[]; + + if (!newCryptoCertGroups || newCryptoCertGroups.length === 0) { + return cryptoPayload; + } + + newCryptoCertGroups.forEach((entry: CommittedCertEntry) => { + cryptoPayload[entry.selectedCertName] = { + roleArn: entry.roleCryptoARN, + trustAnchorArn: entry.trustAnchorCryptoARN, + profileArn: entry.rootCryptoCA + }; + }); + + return cryptoPayload; + } + + private updateComputedFlags(): void { + const groups = this.addCryptoModel.getProperty('/newCryptoCertGroups') as CommittedCertEntry[]; + const hasCommitted = groups && groups.length > 0; + const allowMore = this.addCryptoModel.getProperty('/allowAddMoreCryptoCert') as boolean; + this.addCryptoModel.setProperty('/hasCommittedCerts', hasCommitted); + this.addCryptoModel.setProperty('/showAllCertsAssignedMessage', !allowMore && hasCommitted); + } + + private resetCurrentSelection(): void { + this.addCryptoModel.setProperty('/certSelected', false); + this.addCryptoModel.setProperty('/currentSelectedCertKey', ''); + this.addCryptoModel.setProperty('/currentCert', null); + this.addCryptoModel.setProperty('/currentTrustAnchorARN', ''); + this.addCryptoModel.setProperty('/currentRoleARN', ''); + this.addCryptoModel.setProperty('/currentProfileARN', ''); + } + + private closeDialog(): void { + this.dialog?.close(); + this.dialog?.destroy(); + this.dialog = undefined; + } +} diff --git a/webapp/controller/keyConfigs/detail/DetailPanel.controller.ts b/webapp/controller/keyConfigs/detail/DetailPanel.controller.ts index 7729bde..1a17dd8 100644 --- a/webapp/controller/keyConfigs/detail/DetailPanel.controller.ts +++ b/webapp/controller/keyConfigs/detail/DetailPanel.controller.ts @@ -13,6 +13,7 @@ import { ActionTypes, ArtifactTypes, EventChannelIds, EventIDs } from 'kms/commo import { AxiosError } from 'axios'; import MessageBox from 'sap/m/MessageBox'; import Workflow from 'kms/component/Workflow'; +import HyokCryptoRoleAdd from 'kms/component/HyokCryptoRoleAdd'; interface KeyPatchPayload { name: string @@ -46,6 +47,7 @@ export default class DetailPanel extends BaseController { private keyConfigId: string | undefined; private eventBus = EventBus.getInstance(); private workflowComponent: Workflow | undefined; + private addCryptoComponent: HyokCryptoRoleAdd | undefined = new HyokCryptoRoleAdd('hyokCryptoRole'); public onInit(): void { super.onInit(); @@ -380,4 +382,21 @@ export default class DetailPanel extends BaseController { await this.getSystemDetails(); } } + + public onAddHYOKCryptoDetailsPress(): void { + const selectedKey = this.twoWayModel.getProperty('/selectedKey') as Key; + const existingCrypto = selectedKey?.accessDetails?.crypto; + this.addCryptoComponent?.openAddCryptoCertsDialog( + { + keyId: this.id, + keyConfigId: this.keyConfigId ?? '', + existingCrypto: existingCrypto + }, + this, + this.api, + async () => { + await this.getKeyDetails(); + } + ); + } } diff --git a/webapp/resources/fragments/common/HYOKAddCryptoCertsDialog.fragment.xml b/webapp/resources/fragments/common/HYOKAddCryptoCertsDialog.fragment.xml new file mode 100644 index 0000000..0bfbb14 --- /dev/null +++ b/webapp/resources/fragments/common/HYOKAddCryptoCertsDialog.fragment.xml @@ -0,0 +1,413 @@ + + + + + + + + </f:heading> + </f:DynamicPageTitle> + </f:title> + <f:content> + <VBox class="sapUiSmallMargin"> + <!-- Already added cert entries (committed) --> + <Panel headerText="{i18n>addedCryptoCerts}" + visible="{addCryptoModel>/hasCommittedCerts}" + class="sapUiSmallMarginBottom"> + <VBox items="{addCryptoModel>/newCryptoCertGroups}"> + <items> + <HBox class="sapUiSmallMarginBottom"> + <VBox width="100%"> + <HBox alignItems="Center"> + <core:Icon src="sap-icon://accept" + color="#107E3E" + class="sapUiSmallMarginEnd" /> + <Title level="H5" + text="{addCryptoModel>selectedCertName}" /> + </HBox> + <VBox class="sapUiTinyMarginTop"> + <Label text="{i18n>trustAnchorARN}:" /> + <Text text="{addCryptoModel>trustAnchorCryptoARN}" /> + <Label text="{i18n>roleARN}:" + class="sapUiTinyMarginTop" /> + <Text text="{addCryptoModel>roleCryptoARN}" /> + <Label text="{i18n>profileARN}:" + class="sapUiTinyMarginTop" /> + <Text text="{addCryptoModel>rootCryptoCA}" /> + </VBox> + </VBox> + <Button + icon="sap-icon://decline" + type="Transparent" + press="onRemoveNewCryptoCertGroup"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-removeButton" + writeToDom="true" /> + </customData> + </Button> + </HBox> + </items> + </VBox> + </Panel> + + <!-- Current cert selection + ARN input area --> + <Panel headerText="{i18n>addNewCryptoCerts}" + visible="{= !!${addCryptoModel>/allowAddMoreCryptoCert}}"> + + <!-- Step 1: Select a certificate --> + <VBox visible="{= !${addCryptoModel>/certSelected}}" + class="sapUiSmallMarginBottom"> + <Text text="{i18n>selectCryptoCert}" + class="sapUiSmallMarginBottom" /> + <Select + selectedKey="{addCryptoModel>/currentSelectedCertKey}" + change="onCryptoCertSelected" + forceSelection="false" + width="100%" + items="{ + path: 'addCryptoModel>/availableCryptoCertsSelectionList' + }"> + <core:Item + key="{addCryptoModel>name}" + text="{addCryptoModel>name}" /> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-certSelect" + writeToDom="true" /> + </customData> + </Select> + </VBox> + + <!-- Step 2: Show selected cert details + ARN inputs --> + <VBox visible="{= !!${addCryptoModel>/certSelected}}"> + <!-- Selected cert info --> + <HBox alignItems="Center" + class="sapUiSmallMarginBottom"> + <Title level="H5" + text="{addCryptoModel>/currentCert/name}" /> + </HBox> + <VBox class="sapUiSmallMarginBottom"> + <Label text="{i18n>rootCALabel}:" /> + <Text text="{addCryptoModel>/currentCert/rootCA}" + wrapping="true" /> + <Label text="{i18n>subject}:" + class="sapUiTinyMarginTop" /> + <Text text="{addCryptoModel>/currentCert/subject}" + wrapping="true" /> + </VBox> + + <!-- ARN Inputs --> + <VBox class="sapUiSmallMarginBottom"> + <Label text="{i18n>trustAnchorARN}:" + class="sapUiTinyMarginTop" /> + <Input + value="{addCryptoModel>/currentTrustAnchorARN}" + placeholder="{i18n>trustAnchorARN}"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-trustAnchorARN-Input" + writeToDom="true" /> + </customData> + </Input> + <Label text="{i18n>roleARN}:" + class="sapUiTinyMarginTop" /> + <Input + value="{addCryptoModel>/currentRoleARN}" + placeholder="{i18n>roleARN}"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-roleARN-Input" + writeToDom="true" /> + </customData> + </Input> + <Label text="{i18n>profileARN}:" + class="sapUiTinyMarginTop" /> + <Input + value="{addCryptoModel>/currentProfileARN}" + placeholder="{i18n>profileARN}"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-profileARN-Input" + writeToDom="true" /> + </customData> + </Input> + </VBox> + + <!-- Add + Cancel buttons for current cert --> + <HBox justifyContent="End" + class="sapUiSmallMarginTop"> + <Button text="{i18n>add}" + type="Emphasized" + press="onCommitCurrentCert" + class="sapUiSmallMarginEnd"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-addCertButton" + writeToDom="true" /> + </customData> + </Button> + <Button text="{i18n>cancel}" + type="Transparent" + press="onCancelCurrentCertSelection"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-cancelCertButton" + writeToDom="true" /> + </customData> + </Button> + </HBox> + </VBox> + </Panel> + + <!-- No more certs available message --> + <MessageStrip + visible="{addCryptoModel>/showAllCertsAssignedMessage}" + text="{i18n>allCryptoCertsAssigned}" + type="Information" + showIcon="true" + class="sapUiSmallMarginTop" /> + </VBox> + </f:content> + <f:footer> + <OverflowToolbar> + <ToolbarSpacer /> + <Button text="{i18n>save}" type="Emphasized" + enabled="{addCryptoModel>/hasCommittedCerts}" + press="onAddCryptoCertsSubmitPress"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-saveButton" + writeToDom="true" /> + </customData> + </Button> + <Button text="{i18n>cancel}" type="Transparent" + press="onAddCryptoCertsDialogCancelPress"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-cancelButton" + writeToDom="true" /> + </customData> + </Button> + </OverflowToolbar> + </f:footer> + </f:DynamicPage> + </Dialog> + + + <Dialog + escapeHandler=".onAddCryptoCertsDialogCancelPress" + showHeader="false" + verticalScrolling="true" + contentHeight="80%" + contentWidth="40%"> + <f:DynamicPage + stickySubheaderProvider="cryptoAddWizard" + toggleHeaderOnTitleClick="false" + class="sapUiNoContentPadding" + showFooter="true"> + <f:title> + <f:DynamicPageTitle> + <f:heading> + <Title text="{i18n>HYOKKeyCreationWizard}" /> + </f:heading> + </f:DynamicPageTitle> + </f:title> + <f:content> + <f:content> + <VBox class="sapUiSmallMargin"> + <!-- Already added cert entries (committed) --> + <Panel headerText="{i18n>addedCryptoCerts}" + visible="{addCryptoModel>/hasCommittedCerts}" + class="sapUiSmallMarginBottom"> + <VBox items="{addCryptoModel>/newCryptoCertGroups}"> + <items> + <HBox class="sapUiSmallMarginBottom"> + <VBox width="100%"> + <HBox alignItems="Center"> + <core:Icon src="sap-icon://accept" + color="#107E3E" + class="sapUiSmallMarginEnd" /> + <Title level="H5" + text="{addCryptoModel>selectedCertName}" /> + </HBox> + <VBox class="sapUiTinyMarginTop"> + <Label text="{i18n>trustAnchorARN}:" /> + <Text text="{addCryptoModel>trustAnchorCryptoARN}" /> + <Label text="{i18n>roleARN}:" + class="sapUiTinyMarginTop" /> + <Text text="{addCryptoModel>roleCryptoARN}" /> + <Label text="{i18n>profileARN}:" + class="sapUiTinyMarginTop" /> + <Text text="{addCryptoModel>rootCryptoCA}" /> + </VBox> + </VBox> + <Button + icon="sap-icon://decline" + type="Transparent" + press="onRemoveNewCryptoCertGroup"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-removeButton" + writeToDom="true" /> + </customData> + </Button> + </HBox> + </items> + </VBox> + </Panel> + + <!-- Current cert selection + ARN input area --> + <Panel headerText="{i18n>addNewCryptoCerts}" + visible="{= !!${addCryptoModel>/allowAddMoreCryptoCert}}"> + + <!-- Step 1: Select a certificate --> + <VBox visible="{= !${addCryptoModel>/certSelected}}" + class="sapUiSmallMarginBottom"> + <Text text="{i18n>selectCryptoCert}" + class="sapUiSmallMarginBottom" /> + <Select + selectedKey="{addCryptoModel>/currentSelectedCertKey}" + change="onCryptoCertSelected" + forceSelection="false" + width="100%" + items="{ + path: 'addCryptoModel>/availableCryptoCertsSelectionList' + }"> + <core:Item + key="{addCryptoModel>name}" + text="{addCryptoModel>name}" /> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-certSelect" + writeToDom="true" /> + </customData> + </Select> + </VBox> + + <!-- Step 2: Show selected cert details + ARN inputs --> + <VBox visible="{= !!${addCryptoModel>/certSelected}}"> + <!-- Selected cert info --> + <HBox alignItems="Center" + class="sapUiSmallMarginBottom"> + <Title level="H5" + text="{addCryptoModel>/currentCert/name}" /> + </HBox> + <VBox class="sapUiSmallMarginBottom"> + <Label text="{i18n>rootCALabel}:" /> + <Text text="{addCryptoModel>/currentCert/rootCA}" + wrapping="true" /> + <Label text="{i18n>subject}:" + class="sapUiTinyMarginTop" /> + <Text text="{addCryptoModel>/currentCert/subject}" + wrapping="true" /> + </VBox> + + <!-- ARN Inputs --> + <VBox class="sapUiSmallMarginBottom"> + <Label text="{i18n>trustAnchorARN}:" + class="sapUiTinyMarginTop" /> + <Input + value="{addCryptoModel>/currentTrustAnchorARN}" + placeholder="{i18n>trustAnchorARN}"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-trustAnchorARN-Input" + writeToDom="true" /> + </customData> + </Input> + <Label text="{i18n>roleARN}:" + class="sapUiTinyMarginTop" /> + <Input + value="{addCryptoModel>/currentRoleARN}" + placeholder="{i18n>roleARN}"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-roleARN-Input" + writeToDom="true" /> + </customData> + </Input> + <Label text="{i18n>profileARN}:" + class="sapUiTinyMarginTop" /> + <Input + value="{addCryptoModel>/currentProfileARN}" + placeholder="{i18n>profileARN}"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-profileARN-Input" + writeToDom="true" /> + </customData> + </Input> + </VBox> + + <!-- Add + Cancel buttons for current cert --> + <HBox justifyContent="End" + class="sapUiSmallMarginTop"> + <Button text="{i18n>add}" + type="Emphasized" + press="onCommitCurrentCert" + class="sapUiSmallMarginEnd"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-addCertButton" + writeToDom="true" /> + </customData> + </Button> + <Button text="{i18n>cancel}" + type="Transparent" + press="onCancelCurrentCertSelection"> + <customData> + <core:CustomData + key="testId" + value="addCryptoCerts-cancelCertButton" + writeToDom="true" /> + </customData> + </Button> + </HBox> + </VBox> + </Panel> + + <!-- No more certs available message --> + <MessageStrip + visible="{addCryptoModel>/showAllCertsAssignedMessage}" + text="{i18n>allCryptoCertsAssigned}" + type="Information" + showIcon="true" + class="sapUiSmallMarginTop" /> + </VBox> + </f:content> + </f:content> + <f:footer> + + </f:footer> + </f:DynamicPage> + </Dialog> +</core:FragmentDefinition> \ No newline at end of file diff --git a/webapp/resources/fragments/common/HYOKKeyCreationWizard.fragment.xml b/webapp/resources/fragments/common/HYOKKeyCreationWizard.fragment.xml index 7525895..aeabd06 100644 --- a/webapp/resources/fragments/common/HYOKKeyCreationWizard.fragment.xml +++ b/webapp/resources/fragments/common/HYOKKeyCreationWizard.fragment.xml @@ -358,7 +358,7 @@ value="hyokAWSManagementCertObj-trustAnchorARN-Input" writeToDom="true" /> </customData> - </Input> + </Input> <Label class="sapUiTinyMarginTop" text="{i18n>roleARN}:" /> @@ -462,7 +462,7 @@ value="hyokKeyCreationWizard-reviewButton" writeToDom="true" /> </customData> - </Button> + </Button> <Button text="{i18n>cancel}" type="Transparent" press="onKeyCreationWizardCancelPress"> <customData> diff --git a/webapp/view/keyConfigs/detail/DetailPanel.view.xml b/webapp/view/keyConfigs/detail/DetailPanel.view.xml index 68caf30..ce1d2b5 100644 --- a/webapp/view/keyConfigs/detail/DetailPanel.view.xml +++ b/webapp/view/keyConfigs/detail/DetailPanel.view.xml @@ -163,48 +163,66 @@ <subSections> <ObjectPageSubSection> <m:VBox> - <m:HBox justifyContent="End" - visible="{parts: ['twoWay>/selectedKey/accessDetails/cryptoARNsArray'], formatter: 'commonFormatter.isCryptoDetailEditable'}"> - <m:HBox visible="{= !${oneWay>/cryptoInEditMode}}"> + <m:HBox> + <m:HBox> <m:Button - icon="sap-icon://edit" + icon="sap-icon://add" type="Ghost" - text="{i18n>edit}" - press="onEditHYOKCryptoDetailsPress"> + text="{i18n>add}" + press="onAddHYOKCryptoDetailsPress"> <m:customData> <core:CustomData key="testId" - value="section-editButton" + value="section-addButton" writeToDom="true" /> </m:customData> </m:Button> </m:HBox> - <m:HBox visible="{= ${oneWay>/cryptoInEditMode}}"> - <m:Button - icon="sap-icon://save" - type="Emphasized" - text="{i18n>save}" - press="onSaveHYOKCryptoDetailsPress" - class="sapUiSmallMarginEnd"> - <m:customData> - <core:CustomData - key="testId" - value="section-editButton" - writeToDom="true" /> - </m:customData> - </m:Button> - <m:Button - icon="sap-icon://cancel" - type="Ghost" - text="{i18n>cancel}" - press="onCancelHYOKCryptoEdit"> - <m:customData> - <core:CustomData - key="testId" - value="section-editButton" - writeToDom="true" /> - </m:customData> - </m:Button> + <m:HBox justifyContent="End" + visible="{parts: ['twoWay>/selectedKey/accessDetails/cryptoARNsArray'], formatter: 'commonFormatter.isCryptoDetailEditable'}"> + + + <m:HBox visible="{= !${oneWay>/cryptoInEditMode}}"> + <m:Button + icon="sap-icon://edit" + type="Ghost" + text="{i18n>edit}" + press="onEditHYOKCryptoDetailsPress"> + <m:customData> + <core:CustomData + key="testId" + value="section-editButton" + writeToDom="true" /> + </m:customData> + </m:Button> + </m:HBox> + <m:HBox visible="{= ${oneWay>/cryptoInEditMode}}"> + <m:Button + icon="sap-icon://save" + type="Emphasized" + text="{i18n>save}" + press="onSaveHYOKCryptoDetailsPress" + class="sapUiSmallMarginEnd"> + <m:customData> + <core:CustomData + key="testId" + value="section-editButton" + writeToDom="true" /> + </m:customData> + </m:Button> + <m:Button + icon="sap-icon://cancel" + type="Ghost" + text="{i18n>cancel}" + press="onCancelHYOKCryptoEdit"> + <m:customData> + <core:CustomData + key="testId" + value="section-editButton" + writeToDom="true" /> + </m:customData> + </m:Button> + </m:HBox> </m:HBox> </m:HBox> <m:VBox items="{twoWay>/selectedKey/accessDetails/cryptoARNsArray}">