changes secret value to text area with password font & fixes copy and paste for logs (#687)

This commit is contained in:
Dan Wilson 2023-10-18 15:28:29 +00:00 committed by Harness
parent 1a07ee90d2
commit d2b971c49a
12 changed files with 204 additions and 120 deletions

View File

@ -37,3 +37,10 @@
}
}
}
@font-face {
font-family: 'password';
font-style: normal;
font-weight: 400;
src: local('password'), url('./assets/fonts/password.ttf') format('truetype');
}

Binary file not shown.

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { FlexExpander, Layout, Text } from '@harnessio/uicore'
import { FlexExpander, Layout } from '@harnessio/uicore'
import React, { FC } from 'react'
import type { LivelogLine } from 'services/code'
import css from './ConsoleLogs.module.scss'
@ -57,10 +57,10 @@ const ConsoleLogs: FC<ConsoleLogsProps> = ({ logs }) => {
{logs.map((log, index) => {
return (
<Layout.Horizontal key={index} spacing={'small'} className={css.logLayout}>
{typeof log.pos === 'number' && <Text className={css.lineNumber}>{log.pos + 1}</Text>}
<Text className={css.log}>{log.out}</Text>
{typeof log.pos === 'number' && <span className={css.lineNumber}>{log.pos + 1}</span>}
<span className={css.log}>{log.out}</span>
<FlexExpander />
<Text className={css.time}>{log.time}s</Text>
<span className={css.time}>{log.time}s</span>
</Layout.Horizontal>
)
})}

View File

@ -0,0 +1,6 @@
.textArea textarea {
font-family: 'password' !important;
width: 250px;
font-weight: normal;
font-style: normal;
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2023 Harness, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable */
// This is an auto-generated file
export declare const textArea: string

View File

@ -37,17 +37,20 @@ import { useModalHook } from 'hooks/useModalHook'
import { useStrings } from 'framework/strings'
import type { OpenapiCreateSecretRequest, TypesSecret } from 'services/code'
import { getErrorMessage } from 'utils/Utils'
import css from './NewSecretModalButton.module.scss'
export interface SecretFormData {
value: string
description: string
name: string
showValue: boolean
}
const formInitialValues: SecretFormData = {
value: '',
description: '',
name: ''
name: '',
showValue: false
}
export interface NewSecretModalButtonProps extends Omit<ButtonProps, 'onClick' | 'onSubmit'> {
@ -122,6 +125,7 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
validateOnChange
validateOnBlur
onSubmit={handleSubmit}>
{formik => (
<FormikForm>
<Container>
<FormInput.Text
@ -133,14 +137,21 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
}}
inputGroup={{ autoFocus: true }}
/>
<FormInput.Text
<FormInput.TextArea
name="value"
label={getString('value')}
placeholder={getString('secrets.value')}
tooltipProps={{
dataTooltipId: 'secretDescriptionTextField'
}}
inputGroup={{ type: 'password', autoComplete: 'new-password' }}
autoComplete="off"
className={formik.values.showValue ? '' : css.textArea}
/>
<FormInput.CheckBox
name="showValue"
label={getString('secrets.showValue')}
tooltipProps={{
dataTooltipId: 'secretDescriptionTextField'
}}
/>
<FormInput.Text
name="description"
@ -173,6 +184,7 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
</Layout.Horizontal>
</FormikForm>
)}
</Formik>
</Container>
</Layout.Vertical>

View File

@ -58,33 +58,28 @@ const useRunPipelineModal = () => {
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}/executions`
})
const runPipeline = (formData: FormData): void => {
const runPipeline = async (formData: FormData): Promise<void> => {
const { branch } = formData
try {
startExecution(
const response = await startExecution(
{},
{
pathParams: { path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}/executions` },
queryParams: { branch } as CreateExecutionQueryParams
}
)
.then(response => {
clearToaster()
showSuccess(getString('pipelines.executionStarted'))
if (response?.number && !isNaN(response.number)) {
history.push(routes.toCODEExecution({ repoPath, pipeline, execution: response.number.toString() }))
}
hideModal()
})
.catch(error => {
} catch (error) {
const errorMssg = getErrorMessage(error)
const pipelineDoesNotExistOnGit = errorMssg === getString('pipelines.failedToFindPath')
pipelineDoesNotExistOnGit
? showError(`${getString('pipelines.executionCouldNotStart')}, ${errorMssg}.`)
: showError(getErrorMessage(error), 0, 'pipelines.executionCouldNotStart')
})
} catch (exception) {
showError(getErrorMessage(exception), 0, 'pipelines.executionCouldNotStart')
}
}

View File

@ -0,0 +1,6 @@
.textArea textarea {
font-family: 'password' !important;
width: 250px;
font-weight: normal;
font-style: normal;
}

View File

@ -0,0 +1,19 @@
/*
* Copyright 2023 Harness, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable */
// This is an auto-generated file
export declare const textArea: string

View File

@ -39,6 +39,7 @@ import { useGetSpaceParam } from 'hooks/useGetSpaceParam'
import type { OpenapiUpdateSecretRequest, TypesSecret } from 'services/code'
import type { SecretFormData } from 'components/NewSecretModalButton/NewSecretModalButton'
import { getErrorMessage, truncateString } from 'utils/Utils'
import css from './UpdateSecretModal.module.scss'
const useUpdateSecretModal = () => {
const { getString } = useStrings()
@ -94,7 +95,12 @@ const useUpdateSecretModal = () => {
<Layout.Vertical style={{ height: '100%' }} data-testid="add-secret-modal">
<Container>
<Formik
initialValues={{ name: secret?.uid || '', description: secret?.description || '', value: '' }}
initialValues={{
name: secret?.uid || '',
description: secret?.description || '',
value: '',
showValue: false
}}
formName="addSecret"
enableReinitialize={true}
validationSchema={yup.object().shape({
@ -110,6 +116,7 @@ const useUpdateSecretModal = () => {
validateOnChange
validateOnBlur
onSubmit={handleSubmit}>
{formik => (
<FormikForm>
<FormInput.Text
name="name"
@ -120,14 +127,21 @@ const useUpdateSecretModal = () => {
}}
inputGroup={{ autoFocus: true }}
/>
<FormInput.Text
<FormInput.TextArea
name="value"
label={getString('value')}
placeholder={getString('secrets.value')}
tooltipProps={{
dataTooltipId: 'secretDescriptionTextField'
}}
inputGroup={{ type: 'password', autoComplete: 'new-password' }}
autoComplete="off"
className={formik.values.showValue ? '' : css.textArea}
/>
<FormInput.CheckBox
name="showValue"
label={getString('secrets.showValue')}
tooltipProps={{
dataTooltipId: 'secretDescriptionTextField'
}}
/>
<FormInput.Text
name="description"
@ -149,11 +163,17 @@ const useUpdateSecretModal = () => {
variation={ButtonVariation.PRIMARY}
disabled={loading}
/>
<Button text={getString('cancel')} minimal variation={ButtonVariation.SECONDARY} onClick={onClose} />
<Button
text={getString('cancel')}
minimal
variation={ButtonVariation.SECONDARY}
onClick={onClose}
/>
<FlexExpander />
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
</Layout.Horizontal>
</FormikForm>
)}
</Formik>
</Container>
</Layout.Vertical>

View File

@ -618,8 +618,8 @@ export interface StringsMap {
'secrets.noData': string
'secrets.secretDeleted': string
'secrets.secretUpdated': string
'secrets.showValue': string
'secrets.updateSecret': string
'secrets.value': string
selectBranchPlaceHolder: string
selectRange: string
selectSpace: string

View File

@ -694,7 +694,6 @@ secrets:
name: Secret Name
failedToCreate: Failed to create Secret. Please try again.
enterSecretName: Enter Secret name
value: Secret Value
createSecret: Create Secret
createSuccess: Secret created successfully
secretDeleted: Secret {uid} deleted.
@ -704,6 +703,7 @@ secrets:
failedToUpdateSecret: Failed to update Secret. Please try again.
deleteSecret: Delete secret
updateSecret: Update secret
showValue: Show Value?
userUpdateSuccess: 'User updated successfully'
viewFile: View File
searchResult: 'Search Result {count}'