ApiKeysForm.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React, { ChangeEvent, FC, FormEvent, useEffect, useState } from 'react';
  2. import { rangeUtil, SelectableValue } from '@grafana/data';
  3. import { EventsWithValidation, LegacyForms, ValidationEvents, Button, Select, InlineField } from '@grafana/ui';
  4. import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
  5. import { SlideDown } from '../../core/components/Animations/SlideDown';
  6. import { NewApiKey, OrgRole } from '../../types';
  7. const { Input } = LegacyForms;
  8. const ROLE_OPTIONS: Array<SelectableValue<OrgRole>> = Object.keys(OrgRole).map((role) => ({
  9. label: role,
  10. value: role as OrgRole,
  11. }));
  12. interface Props {
  13. show: boolean;
  14. onClose: () => void;
  15. onKeyAdded: (apiKey: NewApiKey) => void;
  16. disabled: boolean;
  17. }
  18. function isValidInterval(value: string): boolean {
  19. if (!value) {
  20. return true;
  21. }
  22. try {
  23. rangeUtil.intervalToSeconds(value);
  24. return true;
  25. } catch {}
  26. return false;
  27. }
  28. const timeRangeValidationEvents: ValidationEvents = {
  29. [EventsWithValidation.onBlur]: [
  30. {
  31. rule: isValidInterval,
  32. errorMessage: 'Not a valid duration',
  33. },
  34. ],
  35. };
  36. const tooltipText =
  37. 'The API key life duration. For example, 1d if your key is going to last for one day. Supported units are: s,m,h,d,w,M,y';
  38. export const ApiKeysForm: FC<Props> = ({ show, onClose, onKeyAdded, disabled }) => {
  39. const [name, setName] = useState<string>('');
  40. const [role, setRole] = useState<OrgRole>(OrgRole.Viewer);
  41. const [secondsToLive, setSecondsToLive] = useState<string>('');
  42. useEffect(() => {
  43. setName('');
  44. setRole(OrgRole.Viewer);
  45. setSecondsToLive('');
  46. }, [show]);
  47. const onSubmit = (event: FormEvent) => {
  48. event.preventDefault();
  49. if (isValidInterval(secondsToLive)) {
  50. onKeyAdded({ name, role, secondsToLive });
  51. onClose();
  52. }
  53. };
  54. const onNameChange = (event: ChangeEvent<HTMLInputElement>) => {
  55. setName(event.currentTarget.value);
  56. };
  57. const onRoleChange = (role: SelectableValue<OrgRole>) => {
  58. setRole(role.value!);
  59. };
  60. const onSecondsToLiveChange = (event: ChangeEvent<HTMLInputElement>) => {
  61. setSecondsToLive(event.currentTarget.value);
  62. };
  63. return (
  64. <SlideDown in={show}>
  65. <div className="gf-form-inline cta-form">
  66. <CloseButton onClick={onClose} />
  67. <form className="gf-form-group" onSubmit={onSubmit}>
  68. <h5>Add API Key</h5>
  69. <div className="gf-form-inline">
  70. <div className="gf-form max-width-21">
  71. <span className="gf-form-label">Key name</span>
  72. <Input type="text" className="gf-form-input" value={name} placeholder="Name" onChange={onNameChange} />
  73. </div>
  74. <div className="gf-form">
  75. <InlineField label="Role">
  76. <Select inputId="role-select" value={role} onChange={onRoleChange} options={ROLE_OPTIONS} />
  77. </InlineField>
  78. </div>
  79. <div className="gf-form max-width-21">
  80. <InlineField tooltip={tooltipText} label="Time to live">
  81. <Input
  82. id="time-to-live-input"
  83. type="text"
  84. placeholder="1d"
  85. validationEvents={timeRangeValidationEvents}
  86. value={secondsToLive}
  87. onChange={onSecondsToLiveChange}
  88. />
  89. </InlineField>
  90. </div>
  91. <div className="gf-form">
  92. <Button type="submit" disabled={disabled}>
  93. Add
  94. </Button>
  95. </div>
  96. </div>
  97. </form>
  98. </div>
  99. </SlideDown>
  100. );
  101. };