mirror of
https://github.com/harness/drone.git
synced 2025-05-20 19:09:59 +08:00
changes secret value to text area with password font & fixes copy and paste for logs (#687)
This commit is contained in:
parent
1a07ee90d2
commit
d2b971c49a
@ -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');
|
||||
}
|
||||
|
BIN
web/src/assets/fonts/password.ttf
Normal file
BIN
web/src/assets/fonts/password.ttf
Normal file
Binary file not shown.
@ -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>
|
||||
)
|
||||
})}
|
||||
|
@ -0,0 +1,6 @@
|
||||
.textArea textarea {
|
||||
font-family: 'password' !important;
|
||||
width: 250px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
19
web/src/components/NewSecretModalButton/NewSecretModalButton.module.scss.d.ts
vendored
Normal file
19
web/src/components/NewSecretModalButton/NewSecretModalButton.module.scss.d.ts
vendored
Normal 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
|
@ -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,57 +125,66 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
||||
validateOnChange
|
||||
validateOnBlur
|
||||
onSubmit={handleSubmit}>
|
||||
<FormikForm>
|
||||
<Container>
|
||||
<FormInput.Text
|
||||
name="name"
|
||||
label={getString('name')}
|
||||
placeholder={getString('secrets.enterSecretName')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretNameTextField'
|
||||
}}
|
||||
inputGroup={{ autoFocus: true }}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="value"
|
||||
label={getString('value')}
|
||||
placeholder={getString('secrets.value')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
inputGroup={{ type: 'password', autoComplete: 'new-password' }}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="description"
|
||||
label={getString('description')}
|
||||
placeholder={getString('enterDescription')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
isOptional
|
||||
/>
|
||||
</Container>
|
||||
{formik => (
|
||||
<FormikForm>
|
||||
<Container>
|
||||
<FormInput.Text
|
||||
name="name"
|
||||
label={getString('name')}
|
||||
placeholder={getString('secrets.enterSecretName')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretNameTextField'
|
||||
}}
|
||||
inputGroup={{ autoFocus: true }}
|
||||
/>
|
||||
<FormInput.TextArea
|
||||
name="value"
|
||||
label={getString('value')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
autoComplete="off"
|
||||
className={formik.values.showValue ? '' : css.textArea}
|
||||
/>
|
||||
<FormInput.CheckBox
|
||||
name="showValue"
|
||||
label={getString('secrets.showValue')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="description"
|
||||
label={getString('description')}
|
||||
placeholder={getString('enterDescription')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
isOptional
|
||||
/>
|
||||
</Container>
|
||||
|
||||
<Layout.Horizontal
|
||||
spacing="small"
|
||||
padding={{ right: 'xxlarge', top: 'xxxlarge' }}
|
||||
style={{ alignItems: 'center' }}>
|
||||
<Button
|
||||
type="submit"
|
||||
text={getString('secrets.createSecret')}
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
disabled={loading}
|
||||
/>
|
||||
<Button
|
||||
text={cancelButtonTitle || getString('cancel')}
|
||||
minimal
|
||||
onClick={hideModal}
|
||||
variation={ButtonVariation.SECONDARY}
|
||||
/>
|
||||
<FlexExpander />
|
||||
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
|
||||
</Layout.Horizontal>
|
||||
</FormikForm>
|
||||
<Layout.Horizontal
|
||||
spacing="small"
|
||||
padding={{ right: 'xxlarge', top: 'xxxlarge' }}
|
||||
style={{ alignItems: 'center' }}>
|
||||
<Button
|
||||
type="submit"
|
||||
text={getString('secrets.createSecret')}
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
disabled={loading}
|
||||
/>
|
||||
<Button
|
||||
text={cancelButtonTitle || getString('cancel')}
|
||||
minimal
|
||||
onClick={hideModal}
|
||||
variation={ButtonVariation.SECONDARY}
|
||||
/>
|
||||
<FlexExpander />
|
||||
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
|
||||
</Layout.Horizontal>
|
||||
</FormikForm>
|
||||
)}
|
||||
</Formik>
|
||||
</Container>
|
||||
</Layout.Vertical>
|
||||
|
@ -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 => {
|
||||
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')
|
||||
clearToaster()
|
||||
showSuccess(getString('pipelines.executionStarted'))
|
||||
if (response?.number && !isNaN(response.number)) {
|
||||
history.push(routes.toCODEExecution({ repoPath, pipeline, execution: response.number.toString() }))
|
||||
}
|
||||
hideModal()
|
||||
} catch (error) {
|
||||
const errorMssg = getErrorMessage(error)
|
||||
const pipelineDoesNotExistOnGit = errorMssg === getString('pipelines.failedToFindPath')
|
||||
pipelineDoesNotExistOnGit
|
||||
? showError(`${getString('pipelines.executionCouldNotStart')}, ${errorMssg}.`)
|
||||
: showError(getErrorMessage(error), 0, 'pipelines.executionCouldNotStart')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
.textArea textarea {
|
||||
font-family: 'password' !important;
|
||||
width: 250px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
19
web/src/components/UpdateSecretModal/UpdateSecretModal.module.scss.d.ts
vendored
Normal file
19
web/src/components/UpdateSecretModal/UpdateSecretModal.module.scss.d.ts
vendored
Normal 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
|
@ -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,50 +116,64 @@ const useUpdateSecretModal = () => {
|
||||
validateOnChange
|
||||
validateOnBlur
|
||||
onSubmit={handleSubmit}>
|
||||
<FormikForm>
|
||||
<FormInput.Text
|
||||
name="name"
|
||||
label={getString('name')}
|
||||
placeholder={getString('secrets.enterSecretName')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretNameTextField'
|
||||
}}
|
||||
inputGroup={{ autoFocus: true }}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="value"
|
||||
label={getString('value')}
|
||||
placeholder={getString('secrets.value')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
inputGroup={{ type: 'password', autoComplete: 'new-password' }}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="description"
|
||||
label={getString('description')}
|
||||
placeholder={getString('enterDescription')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
isOptional
|
||||
/>
|
||||
|
||||
<Layout.Horizontal
|
||||
spacing="small"
|
||||
padding={{ right: 'xxlarge', top: 'xxxlarge' }}
|
||||
style={{ alignItems: 'center' }}>
|
||||
<Button
|
||||
type="submit"
|
||||
text={getString('secrets.updateSecret')}
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
disabled={loading}
|
||||
{formik => (
|
||||
<FormikForm>
|
||||
<FormInput.Text
|
||||
name="name"
|
||||
label={getString('name')}
|
||||
placeholder={getString('secrets.enterSecretName')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretNameTextField'
|
||||
}}
|
||||
inputGroup={{ autoFocus: true }}
|
||||
/>
|
||||
<Button text={getString('cancel')} minimal variation={ButtonVariation.SECONDARY} onClick={onClose} />
|
||||
<FlexExpander />
|
||||
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
|
||||
</Layout.Horizontal>
|
||||
</FormikForm>
|
||||
<FormInput.TextArea
|
||||
name="value"
|
||||
label={getString('value')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
autoComplete="off"
|
||||
className={formik.values.showValue ? '' : css.textArea}
|
||||
/>
|
||||
<FormInput.CheckBox
|
||||
name="showValue"
|
||||
label={getString('secrets.showValue')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name="description"
|
||||
label={getString('description')}
|
||||
placeholder={getString('enterDescription')}
|
||||
tooltipProps={{
|
||||
dataTooltipId: 'secretDescriptionTextField'
|
||||
}}
|
||||
isOptional
|
||||
/>
|
||||
|
||||
<Layout.Horizontal
|
||||
spacing="small"
|
||||
padding={{ right: 'xxlarge', top: 'xxxlarge' }}
|
||||
style={{ alignItems: 'center' }}>
|
||||
<Button
|
||||
type="submit"
|
||||
text={getString('secrets.updateSecret')}
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
disabled={loading}
|
||||
/>
|
||||
<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>
|
||||
|
@ -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
|
||||
|
@ -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}'
|
||||
|
Loading…
Reference in New Issue
Block a user