Skip to content

Commit

Permalink
Alerting: Fix KeyValueMap input bug (grafana#101367)
Browse files Browse the repository at this point in the history
* fix KeyValueMap input bug

* add translations
  • Loading branch information
soniaAguilarPeiron authored Feb 27, 2025
1 parent 980332a commit 98dd977
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 29 deletions.
6 changes: 2 additions & 4 deletions .betterer.results
Original file line number Diff line number Diff line change
Expand Up @@ -1982,10 +1982,8 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"]
],
"public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { css } from '@emotion/css';
import { useEffect, useState } from 'react';
import { useState } from 'react';

import { GrafanaTheme2 } from '@grafana/data';
import { Button, Input, useStyles2 } from '@grafana/ui';
import { Button, Input, Stack, useStyles2 } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';

import { ActionIcon } from '../../../rules/ActionIcon';

Expand All @@ -15,7 +16,7 @@ interface Props {
export const KeyValueMapInput = ({ value, onChange, readOnly = false }: Props) => {
const styles = useStyles2(getStyles);
const [pairs, setPairs] = useState(recordToPairs(value));
useEffect(() => setPairs(recordToPairs(value)), [value]);
const [currentNewPair, setCurrentNewPair] = useState<[string, string] | undefined>(undefined);

const emitChange = (pairs: Array<[string, string]>) => {
onChange(pairsToRecord(pairs));
Expand All @@ -30,15 +31,6 @@ export const KeyValueMapInput = ({ value, onChange, readOnly = false }: Props) =
}
};

const updatePair = (values: [string, string], index: number) => {
const old = pairs[index];
const newPairs = pairs.map((pair, i) => (i === index ? values : pair));
setPairs(newPairs);
if (values[0] || old[0]) {
emitChange(newPairs);
}
};

return (
<div>
{!!pairs.length && (
Expand All @@ -54,39 +46,74 @@ export const KeyValueMapInput = ({ value, onChange, readOnly = false }: Props) =
{pairs.map(([key, value], index) => (
<tr key={index}>
<td>
<Input
readOnly={readOnly}
value={key}
onChange={(e) => updatePair([e.currentTarget.value, value], index)}
/>
<Input readOnly={readOnly} value={key} disabled />
</td>
<td>
<Input
readOnly={readOnly}
value={value}
onChange={(e) => updatePair([key, e.currentTarget.value], index)}
/>
<Input readOnly={readOnly} value={value} disabled />
</td>
{!readOnly && (
<td>
<ActionIcon icon="trash-alt" tooltip="delete" onClick={() => deleteItem(index)} />
<ActionIcon
icon="trash-alt"
tooltip={t('alerting.common.delete', 'Delete')}
onClick={() => deleteItem(index)}
/>
</td>
)}
</tr>
))}
</tbody>
</table>
)}
{currentNewPair && (
<table className={styles.table}>
<tr>
<Stack gap={1}>
<td>
<Input
value={currentNewPair[0]}
onChange={(e) => setCurrentNewPair([e.currentTarget.value, currentNewPair[1]])}
/>
</td>
<td>
<Input
value={currentNewPair[1]}
onChange={(e) => setCurrentNewPair([currentNewPair[0], e.currentTarget.value])}
/>
</td>
<td>
<Stack gap={1}>
<ActionIcon
icon="check"
tooltip={t('alerting.contact-points.key-value-map.confirm-add', 'Confirm to add')}
onClick={() => {
setPairs([...pairs, currentNewPair]);
setCurrentNewPair(undefined);
emitChange([...pairs, currentNewPair]);
}}
/>
<ActionIcon
icon="times"
tooltip={t('alerting.common.cancel', 'Cancel')}
onClick={() => setCurrentNewPair(undefined)}
/>
</Stack>
</td>
</Stack>
</tr>
</table>
)}
{!readOnly && (
<Button
className={styles.addButton}
type="button"
variant="secondary"
icon="plus"
size="sm"
onClick={() => setPairs([...pairs, ['', '']])}
disabled={!!currentNewPair}
onClick={() => setCurrentNewPair(['', ''])}
>
Add
<Trans i18nKey="alerting.contact-points.key-value-map.add">Add</Trans>
</Button>
)}
</div>
Expand Down
4 changes: 4 additions & 0 deletions public/locales/en-US/grafana.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@
"empty-state": {
"title": "You don't have any contact points yet"
},
"key-value-map": {
"add": "Add",
"confirm-add": "Confirm to add"
},
"last-delivery-attempt": "Last delivery attempt",
"last-delivery-failed": "Last delivery attempt failed",
"no-contact-points-found": "No contact points found",
Expand Down
4 changes: 4 additions & 0 deletions public/locales/pseudo-LOCALE/grafana.json
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@
"empty-state": {
"title": "Ÿőū đőʼn'ŧ ĥävę äʼny čőʼnŧäčŧ pőįʼnŧş yęŧ"
},
"key-value-map": {
"add": "Åđđ",
"confirm-add": "Cőʼnƒįřm ŧő äđđ"
},
"last-delivery-attempt": "Ŀäşŧ đęľįvęřy äŧŧęmpŧ",
"last-delivery-failed": "Ŀäşŧ đęľįvęřy äŧŧęmpŧ ƒäįľęđ",
"no-contact-points-found": "Ńő čőʼnŧäčŧ pőįʼnŧş ƒőūʼnđ",
Expand Down

0 comments on commit 98dd977

Please sign in to comment.