grafana/public/app/features/serviceaccounts/components/ServiceAccountProfileRow.tsx
Alexander Zobnin 50538d5309
ServiceAccounts: refactor UI (#49508)
* ServiceAccounts: refactor ServiceAccountRoleRow

* Refactor ServiceAccountRoleRow

* Refactor ServiceAccountProfile

* Refactor components

* Change service accounts icon

* Refine service accounts page header

* Improve service accounts filtering

* Change delete button style

* Tweak account id

* Auto focus name field when create service account

* Add disable/enable button

* Enable/disable service accounts

* Optimize updating service account (do not fetch all)

* Remove status column (replace by enable/disable button)

* Add banner with service accounts description

* Add tokens from main page

* Update tokens count when add token from main page

* Fix action buttons column

* Fix tokens count when change role

* Refine table row classes

* Fix buttons

* Simplify working with state

* Show message when service account updated

* Able to filter disabled accounts

* Mark disabled accounts in a table

* Refine disabled account view

* Move non-critical components to separate folder

* Remove confusing focusing

* Fix date picker position when creating new token

* DatePicker: able to set minimum date that can be selected

* Don't allow to select expiration dates prior today

* Set tomorrow as a default token expiration date

* Fix displaying expiration period

* Rename Add token button

* Refine page styles

* Show modal when disabling SA from main page

* Arrange role picker

* Refine SA page styles

* Generate default token name

* More smooth navigation between SA pages

* Stop loading indicator in case of error

* Remove legacy styles usage

* Tweaks after code review

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* Get rid of useDisapatch in favor of mapDispatchToProps

* Tests for ServiceAccountsListPage

* Tests for service account page

* Show new role picker only with license

* Get rid of deprecated css classes

* Apply suggestion from code review

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* Fix service accounts icon

* Tests for service account create page

* Return service account info when update

* Add behaviour tests for ServiceAccountsListPage

* Fix disabled cursor on confirm button

* More behavior tests for service account page

* Temporary disable service account migration banner

* Use safe where condition

Co-authored-by: Jguer <joao.guerreiro@grafana.com>

* Apply review suggestions

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>

* Remove autofocus from search

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Jguer <joao.guerreiro@grafana.com>
2022-06-01 09:35:16 +02:00

107 lines
2.5 KiB
TypeScript

import { css, cx } from '@emotion/css';
import React, { useEffect, useRef, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { ConfirmButton, Input, Label, LegacyInputStatus, useStyles2 } from '@grafana/ui';
interface Props {
label: string;
value?: string;
inputType?: string;
disabled?: boolean;
onChange?: (value: string) => void;
}
export const ServiceAccountProfileRow = ({ label, value, inputType, disabled, onChange }: Props): JSX.Element => {
const inputElem = useRef<HTMLInputElement>(null);
const [inputValue, setInputValue] = useState(value);
const [isEditing, setIsEditing] = useState(false);
const styles = useStyles2(getStyles);
const inputId = `${label}-input`;
useEffect(() => {
if (isEditing) {
focusInput();
}
}, [isEditing]);
const onEditClick = () => {
setIsEditing(true);
};
const onCancelClick = () => {
setIsEditing(false);
setInputValue(value || '');
};
const onInputChange = (event: React.ChangeEvent<HTMLInputElement>, status?: LegacyInputStatus) => {
if (status === LegacyInputStatus.Invalid) {
return;
}
setInputValue(event.target.value);
};
const onInputBlur = (event: React.FocusEvent<HTMLInputElement>, status?: LegacyInputStatus) => {
if (status === LegacyInputStatus.Invalid) {
return;
}
setInputValue(event.target.value);
};
const focusInput = () => {
inputElem?.current?.focus();
};
const onSave = () => {
setIsEditing(false);
if (onChange) {
onChange(inputValue!);
}
};
return (
<tr>
<td>
<Label htmlFor={inputId}>{label}</Label>
</td>
<td className="width-25" colSpan={2}>
{!disabled && isEditing ? (
<Input
id={inputId}
type={inputType}
defaultValue={value}
onBlur={onInputBlur}
onChange={onInputChange}
ref={inputElem}
width={30}
/>
) : (
<span className={cx({ [styles.disabled]: disabled })}>{value}</span>
)}
</td>
<td>
{onChange && (
<ConfirmButton
closeOnConfirm
confirmText="Save"
onConfirm={onSave}
onClick={onEditClick}
onCancel={onCancelClick}
disabled={disabled}
>
Edit
</ConfirmButton>
)}
</td>
</tr>
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
disabled: css`
color: ${theme.colors.text.secondary};
`,
};
};