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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { FlexExpander, Layout, Text } from '@harnessio/uicore'
|
import { FlexExpander, Layout } from '@harnessio/uicore'
|
||||||
import React, { FC } from 'react'
|
import React, { FC } from 'react'
|
||||||
import type { LivelogLine } from 'services/code'
|
import type { LivelogLine } from 'services/code'
|
||||||
import css from './ConsoleLogs.module.scss'
|
import css from './ConsoleLogs.module.scss'
|
||||||
@ -57,10 +57,10 @@ const ConsoleLogs: FC<ConsoleLogsProps> = ({ logs }) => {
|
|||||||
{logs.map((log, index) => {
|
{logs.map((log, index) => {
|
||||||
return (
|
return (
|
||||||
<Layout.Horizontal key={index} spacing={'small'} className={css.logLayout}>
|
<Layout.Horizontal key={index} spacing={'small'} className={css.logLayout}>
|
||||||
{typeof log.pos === 'number' && <Text className={css.lineNumber}>{log.pos + 1}</Text>}
|
{typeof log.pos === 'number' && <span className={css.lineNumber}>{log.pos + 1}</span>}
|
||||||
<Text className={css.log}>{log.out}</Text>
|
<span className={css.log}>{log.out}</span>
|
||||||
<FlexExpander />
|
<FlexExpander />
|
||||||
<Text className={css.time}>{log.time}s</Text>
|
<span className={css.time}>{log.time}s</span>
|
||||||
</Layout.Horizontal>
|
</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 { useStrings } from 'framework/strings'
|
||||||
import type { OpenapiCreateSecretRequest, TypesSecret } from 'services/code'
|
import type { OpenapiCreateSecretRequest, TypesSecret } from 'services/code'
|
||||||
import { getErrorMessage } from 'utils/Utils'
|
import { getErrorMessage } from 'utils/Utils'
|
||||||
|
import css from './NewSecretModalButton.module.scss'
|
||||||
|
|
||||||
export interface SecretFormData {
|
export interface SecretFormData {
|
||||||
value: string
|
value: string
|
||||||
description: string
|
description: string
|
||||||
name: string
|
name: string
|
||||||
|
showValue: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const formInitialValues: SecretFormData = {
|
const formInitialValues: SecretFormData = {
|
||||||
value: '',
|
value: '',
|
||||||
description: '',
|
description: '',
|
||||||
name: ''
|
name: '',
|
||||||
|
showValue: false
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NewSecretModalButtonProps extends Omit<ButtonProps, 'onClick' | 'onSubmit'> {
|
export interface NewSecretModalButtonProps extends Omit<ButtonProps, 'onClick' | 'onSubmit'> {
|
||||||
@ -122,57 +125,66 @@ export const NewSecretModalButton: React.FC<NewSecretModalButtonProps> = ({
|
|||||||
validateOnChange
|
validateOnChange
|
||||||
validateOnBlur
|
validateOnBlur
|
||||||
onSubmit={handleSubmit}>
|
onSubmit={handleSubmit}>
|
||||||
<FormikForm>
|
{formik => (
|
||||||
<Container>
|
<FormikForm>
|
||||||
<FormInput.Text
|
<Container>
|
||||||
name="name"
|
<FormInput.Text
|
||||||
label={getString('name')}
|
name="name"
|
||||||
placeholder={getString('secrets.enterSecretName')}
|
label={getString('name')}
|
||||||
tooltipProps={{
|
placeholder={getString('secrets.enterSecretName')}
|
||||||
dataTooltipId: 'secretNameTextField'
|
tooltipProps={{
|
||||||
}}
|
dataTooltipId: 'secretNameTextField'
|
||||||
inputGroup={{ autoFocus: true }}
|
}}
|
||||||
/>
|
inputGroup={{ autoFocus: true }}
|
||||||
<FormInput.Text
|
/>
|
||||||
name="value"
|
<FormInput.TextArea
|
||||||
label={getString('value')}
|
name="value"
|
||||||
placeholder={getString('secrets.value')}
|
label={getString('value')}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
dataTooltipId: 'secretDescriptionTextField'
|
dataTooltipId: 'secretDescriptionTextField'
|
||||||
}}
|
}}
|
||||||
inputGroup={{ type: 'password', autoComplete: 'new-password' }}
|
autoComplete="off"
|
||||||
/>
|
className={formik.values.showValue ? '' : css.textArea}
|
||||||
<FormInput.Text
|
/>
|
||||||
name="description"
|
<FormInput.CheckBox
|
||||||
label={getString('description')}
|
name="showValue"
|
||||||
placeholder={getString('enterDescription')}
|
label={getString('secrets.showValue')}
|
||||||
tooltipProps={{
|
tooltipProps={{
|
||||||
dataTooltipId: 'secretDescriptionTextField'
|
dataTooltipId: 'secretDescriptionTextField'
|
||||||
}}
|
}}
|
||||||
isOptional
|
/>
|
||||||
/>
|
<FormInput.Text
|
||||||
</Container>
|
name="description"
|
||||||
|
label={getString('description')}
|
||||||
|
placeholder={getString('enterDescription')}
|
||||||
|
tooltipProps={{
|
||||||
|
dataTooltipId: 'secretDescriptionTextField'
|
||||||
|
}}
|
||||||
|
isOptional
|
||||||
|
/>
|
||||||
|
</Container>
|
||||||
|
|
||||||
<Layout.Horizontal
|
<Layout.Horizontal
|
||||||
spacing="small"
|
spacing="small"
|
||||||
padding={{ right: 'xxlarge', top: 'xxxlarge' }}
|
padding={{ right: 'xxlarge', top: 'xxxlarge' }}
|
||||||
style={{ alignItems: 'center' }}>
|
style={{ alignItems: 'center' }}>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
text={getString('secrets.createSecret')}
|
text={getString('secrets.createSecret')}
|
||||||
variation={ButtonVariation.PRIMARY}
|
variation={ButtonVariation.PRIMARY}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
text={cancelButtonTitle || getString('cancel')}
|
text={cancelButtonTitle || getString('cancel')}
|
||||||
minimal
|
minimal
|
||||||
onClick={hideModal}
|
onClick={hideModal}
|
||||||
variation={ButtonVariation.SECONDARY}
|
variation={ButtonVariation.SECONDARY}
|
||||||
/>
|
/>
|
||||||
<FlexExpander />
|
<FlexExpander />
|
||||||
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
|
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
</FormikForm>
|
</FormikForm>
|
||||||
|
)}
|
||||||
</Formik>
|
</Formik>
|
||||||
</Container>
|
</Container>
|
||||||
</Layout.Vertical>
|
</Layout.Vertical>
|
||||||
|
@ -58,33 +58,28 @@ const useRunPipelineModal = () => {
|
|||||||
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}/executions`
|
path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}/executions`
|
||||||
})
|
})
|
||||||
|
|
||||||
const runPipeline = (formData: FormData): void => {
|
const runPipeline = async (formData: FormData): Promise<void> => {
|
||||||
const { branch } = formData
|
const { branch } = formData
|
||||||
try {
|
try {
|
||||||
startExecution(
|
const response = await startExecution(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
pathParams: { path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}/executions` },
|
pathParams: { path: `/api/v1/repos/${repoPath}/+/pipelines/${pipeline}/executions` },
|
||||||
queryParams: { branch } as CreateExecutionQueryParams
|
queryParams: { branch } as CreateExecutionQueryParams
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(response => {
|
clearToaster()
|
||||||
clearToaster()
|
showSuccess(getString('pipelines.executionStarted'))
|
||||||
showSuccess(getString('pipelines.executionStarted'))
|
if (response?.number && !isNaN(response.number)) {
|
||||||
if (response?.number && !isNaN(response.number)) {
|
history.push(routes.toCODEExecution({ repoPath, pipeline, execution: response.number.toString() }))
|
||||||
history.push(routes.toCODEExecution({ repoPath, pipeline, execution: response.number.toString() }))
|
}
|
||||||
}
|
hideModal()
|
||||||
hideModal()
|
} catch (error) {
|
||||||
})
|
const errorMssg = getErrorMessage(error)
|
||||||
.catch(error => {
|
const pipelineDoesNotExistOnGit = errorMssg === getString('pipelines.failedToFindPath')
|
||||||
const errorMssg = getErrorMessage(error)
|
pipelineDoesNotExistOnGit
|
||||||
const pipelineDoesNotExistOnGit = errorMssg === getString('pipelines.failedToFindPath')
|
? showError(`${getString('pipelines.executionCouldNotStart')}, ${errorMssg}.`)
|
||||||
pipelineDoesNotExistOnGit
|
: showError(getErrorMessage(error), 0, 'pipelines.executionCouldNotStart')
|
||||||
? showError(`${getString('pipelines.executionCouldNotStart')}, ${errorMssg}.`)
|
|
||||||
: showError(getErrorMessage(error), 0, 'pipelines.executionCouldNotStart')
|
|
||||||
})
|
|
||||||
} catch (exception) {
|
|
||||||
showError(getErrorMessage(exception), 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 { OpenapiUpdateSecretRequest, TypesSecret } from 'services/code'
|
||||||
import type { SecretFormData } from 'components/NewSecretModalButton/NewSecretModalButton'
|
import type { SecretFormData } from 'components/NewSecretModalButton/NewSecretModalButton'
|
||||||
import { getErrorMessage, truncateString } from 'utils/Utils'
|
import { getErrorMessage, truncateString } from 'utils/Utils'
|
||||||
|
import css from './UpdateSecretModal.module.scss'
|
||||||
|
|
||||||
const useUpdateSecretModal = () => {
|
const useUpdateSecretModal = () => {
|
||||||
const { getString } = useStrings()
|
const { getString } = useStrings()
|
||||||
@ -94,7 +95,12 @@ const useUpdateSecretModal = () => {
|
|||||||
<Layout.Vertical style={{ height: '100%' }} data-testid="add-secret-modal">
|
<Layout.Vertical style={{ height: '100%' }} data-testid="add-secret-modal">
|
||||||
<Container>
|
<Container>
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{ name: secret?.uid || '', description: secret?.description || '', value: '' }}
|
initialValues={{
|
||||||
|
name: secret?.uid || '',
|
||||||
|
description: secret?.description || '',
|
||||||
|
value: '',
|
||||||
|
showValue: false
|
||||||
|
}}
|
||||||
formName="addSecret"
|
formName="addSecret"
|
||||||
enableReinitialize={true}
|
enableReinitialize={true}
|
||||||
validationSchema={yup.object().shape({
|
validationSchema={yup.object().shape({
|
||||||
@ -110,50 +116,64 @@ const useUpdateSecretModal = () => {
|
|||||||
validateOnChange
|
validateOnChange
|
||||||
validateOnBlur
|
validateOnBlur
|
||||||
onSubmit={handleSubmit}>
|
onSubmit={handleSubmit}>
|
||||||
<FormikForm>
|
{formik => (
|
||||||
<FormInput.Text
|
<FormikForm>
|
||||||
name="name"
|
<FormInput.Text
|
||||||
label={getString('name')}
|
name="name"
|
||||||
placeholder={getString('secrets.enterSecretName')}
|
label={getString('name')}
|
||||||
tooltipProps={{
|
placeholder={getString('secrets.enterSecretName')}
|
||||||
dataTooltipId: 'secretNameTextField'
|
tooltipProps={{
|
||||||
}}
|
dataTooltipId: 'secretNameTextField'
|
||||||
inputGroup={{ autoFocus: true }}
|
}}
|
||||||
/>
|
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}
|
|
||||||
/>
|
/>
|
||||||
<Button text={getString('cancel')} minimal variation={ButtonVariation.SECONDARY} onClick={onClose} />
|
<FormInput.TextArea
|
||||||
<FlexExpander />
|
name="value"
|
||||||
{loading && <Icon intent={Intent.PRIMARY} name="steps-spinner" size={16} />}
|
label={getString('value')}
|
||||||
</Layout.Horizontal>
|
tooltipProps={{
|
||||||
</FormikForm>
|
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>
|
</Formik>
|
||||||
</Container>
|
</Container>
|
||||||
</Layout.Vertical>
|
</Layout.Vertical>
|
||||||
|
@ -618,8 +618,8 @@ export interface StringsMap {
|
|||||||
'secrets.noData': string
|
'secrets.noData': string
|
||||||
'secrets.secretDeleted': string
|
'secrets.secretDeleted': string
|
||||||
'secrets.secretUpdated': string
|
'secrets.secretUpdated': string
|
||||||
|
'secrets.showValue': string
|
||||||
'secrets.updateSecret': string
|
'secrets.updateSecret': string
|
||||||
'secrets.value': string
|
|
||||||
selectBranchPlaceHolder: string
|
selectBranchPlaceHolder: string
|
||||||
selectRange: string
|
selectRange: string
|
||||||
selectSpace: string
|
selectSpace: string
|
||||||
|
@ -694,7 +694,6 @@ secrets:
|
|||||||
name: Secret Name
|
name: Secret Name
|
||||||
failedToCreate: Failed to create Secret. Please try again.
|
failedToCreate: Failed to create Secret. Please try again.
|
||||||
enterSecretName: Enter Secret name
|
enterSecretName: Enter Secret name
|
||||||
value: Secret Value
|
|
||||||
createSecret: Create Secret
|
createSecret: Create Secret
|
||||||
createSuccess: Secret created successfully
|
createSuccess: Secret created successfully
|
||||||
secretDeleted: Secret {uid} deleted.
|
secretDeleted: Secret {uid} deleted.
|
||||||
@ -704,6 +703,7 @@ secrets:
|
|||||||
failedToUpdateSecret: Failed to update Secret. Please try again.
|
failedToUpdateSecret: Failed to update Secret. Please try again.
|
||||||
deleteSecret: Delete secret
|
deleteSecret: Delete secret
|
||||||
updateSecret: Update secret
|
updateSecret: Update secret
|
||||||
|
showValue: Show Value?
|
||||||
userUpdateSuccess: 'User updated successfully'
|
userUpdateSuccess: 'User updated successfully'
|
||||||
viewFile: View File
|
viewFile: View File
|
||||||
searchResult: 'Search Result {count}'
|
searchResult: 'Search Result {count}'
|
||||||
|
Loading…
Reference in New Issue
Block a user