Skip to content

Commit 68e4e18

Browse files
committed
fix: counts & save button align
1 parent 9ee255d commit 68e4e18

7 files changed

Lines changed: 195 additions & 206 deletions

File tree

src/taxonomy/tag-list/UsageCountDisplay.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,13 @@ import type { Row } from '@tanstack/react-table';
55
import type {
66
TreeRowData,
77
} from '../tree-table/types';
8-
9-
interface TagListRowData extends TreeRowData {
10-
depth: number;
11-
childCount: number;
12-
usageCount?: number;
13-
isNew?: boolean;
14-
isEditing?: boolean;
15-
}
8+
import { TagListRowData } from './types';
169

1710
const asTagListRowData = (row: Row<TreeRowData>): TagListRowData => (
1811
row.original as unknown as TagListRowData
1912
);
2013

21-
export const UsageCountDisplay = ({ row }: { row: Row<TreeRowData> }) => {
14+
const UsageCountDisplay = ({ row }: { row: Row<TreeRowData> }) => {
2215
const count = asTagListRowData(row).usageCount ?? 0;
2316
return (
2417
count > 0 && (
@@ -28,3 +21,5 @@ export const UsageCountDisplay = ({ row }: { row: Row<TreeRowData> }) => {
2821
)
2922
);
3023
};
24+
25+
export default UsageCountDisplay;

src/taxonomy/tag-list/tagColumns.tsx

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
Bubble,
32
Icon,
43
IconButton,
54
IconButtonWithTooltip,
@@ -18,18 +17,12 @@ import type {
1817
TreeColumnDef,
1918
TreeRowData,
2019
} from '../tree-table/types';
20+
import { TagListRowData } from './types';
2121
import OptionalExpandLink from './OptionalExpandLink';
22+
import UsageCountDisplay from './UsageCountDisplay';
2223

2324
const EDITABLE_COLUMNS = ['value'];
2425

25-
interface TagListRowData extends TreeRowData {
26-
depth: number;
27-
childCount: number;
28-
usageCount?: number;
29-
isNew?: boolean;
30-
isEditing?: boolean;
31-
}
32-
3326
const asTagListRowData = (row: Row<TreeRowData>): TagListRowData => (
3427
row.original as unknown as TagListRowData
3528
);
@@ -49,17 +42,6 @@ interface GetColumnsArgs {
4942
maxDepth: number;
5043
}
5144

52-
const UsageCountDisplay = ({ row }: { row: Row<TreeRowData> }) => {
53-
const count = asTagListRowData(row).usageCount ?? 0;
54-
return (
55-
count > 0 && (
56-
<Bubble expandable>
57-
{count}
58-
</Bubble>
59-
)
60-
);
61-
};
62-
6345
interface ActionsHeaderProps {
6446
onStartDraft: () => void;
6547
setDraftError: (error: string) => void;

src/taxonomy/tag-list/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { TreeRowData } from '../tree-table/types';
2+
3+
export interface TagListRowData extends TreeRowData {
4+
depth: number;
5+
childCount: number;
6+
usageCount?: number;
7+
isNew?: boolean;
8+
isEditing?: boolean;
9+
}

src/taxonomy/tree-table/CreateRow.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { IntlProvider } from '@edx/frontend-platform/i18n';
33
import { fireEvent, render, screen } from '@testing-library/react';
44

5-
import { CreateRow } from './CreateRow';
5+
import CreateRow from './CreateRow';
66

77
const wrapper = ({ children }: { children: React.ReactNode }) => (
88
<IntlProvider locale="en" messages={{}}>{children}</IntlProvider>
Lines changed: 4 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,6 @@
1-
import React, { useState } from 'react';
2-
import { Button, Spinner } from '@openedx/paragon';
3-
import { useIntl } from '@edx/frontend-platform/i18n';
4-
5-
import { EditableCell } from './EditableCell';
6-
import type { CreateRowMutationState, TreeColumnDef } from './types';
7-
import messages from './messages';
8-
import { Row } from '@tanstack/react-table';
9-
import { UsageCountDisplay } from '../tag-list/UsageCountDisplay';
10-
11-
interface DraftRowProps {
12-
draftError: string;
13-
initialValue?: string;
14-
onSave: (value: string) => void;
15-
onCancel: () => void;
16-
mutationState: CreateRowMutationState;
17-
columns: TreeColumnDef[];
18-
indent?: number;
19-
validate: (value: string, mode?: 'soft' | 'hard') => boolean;
20-
requireValueChangeToEnableSave?: boolean;
21-
rowTestId?: string;
22-
rowId?: string;
23-
row?: any;
24-
}
1+
import React from 'react';
2+
import type { CreateRowMutationState } from './types';
3+
import DraftRow from './DraftRow';
254

265
interface CreateRowProps {
276
draftError: string;
@@ -30,134 +9,17 @@ interface CreateRowProps {
309
setIsCreatingTopRow: (isCreating: boolean) => void;
3110
exitDraftWithoutSave: () => void;
3211
createRowMutation: CreateRowMutationState;
33-
columns: TreeColumnDef[];
3412
indent?: number;
3513
validate: (value: string, mode?: 'soft' | 'hard') => boolean;
3614
}
3715

38-
interface EditRowProps {
39-
draftError: string;
40-
setDraftError: (error: string) => void;
41-
initialValue: string;
42-
handleUpdateRow: (value: string) => void;
43-
cancelEditRow: () => void;
44-
updateRowMutation: CreateRowMutationState;
45-
columns: TreeColumnDef[];
46-
indent?: number;
47-
validate: (value: string, mode?: 'soft' | 'hard') => boolean;
48-
row: any;
49-
}
50-
51-
const DraftRow: React.FC<DraftRowProps> = ({
52-
draftError,
53-
initialValue = '',
54-
onSave,
55-
onCancel,
56-
mutationState,
57-
columns,
58-
indent = 0,
59-
validate,
60-
requireValueChangeToEnableSave = false,
61-
rowTestId,
62-
rowId,
63-
row,
64-
65-
}) => {
66-
const [rowValue, setRowValue] = useState(initialValue);
67-
const [saveDisabled, setSaveDisabled] = useState(true);
68-
const intl = useIntl();
69-
70-
const updateSaveDisabled = (value: string) => {
71-
const trimmedValue = value.trim();
72-
const isValid = validate(value, 'soft');
73-
const isUnchanged = requireValueChangeToEnableSave && trimmedValue === initialValue.trim();
74-
setSaveDisabled(!isValid || !trimmedValue || isUnchanged || mutationState.isPending || false);
75-
};
76-
77-
const handleValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
78-
const { value } = e.target;
79-
setRowValue(value);
80-
updateSaveDisabled(value);
81-
};
82-
83-
const handleSave = () => {
84-
onSave(rowValue.trim());
85-
};
86-
87-
const handleValueCellKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
88-
if (e.key === 'Enter' && !saveDisabled && !draftError) {
89-
e.preventDefault();
90-
handleSave();
91-
return;
92-
}
93-
94-
if (e.key === 'Escape') {
95-
e.preventDefault();
96-
onCancel();
97-
}
98-
};
99-
100-
const indentClass = indent > 0 ? `tree-table-indent tree-table-indent-${indent}` : '';
101-
102-
return (
103-
<tr id={rowId} data-testid={rowTestId}>
104-
<td colSpan={1} className="py-2 pr-2 pl-0">
105-
<div className={indentClass}>
106-
<EditableCell
107-
initialValue={initialValue}
108-
errorMessage={draftError}
109-
isSaving={mutationState.isPending}
110-
onChange={handleValueChange}
111-
onKeyDown={handleValueCellKeyPress}
112-
autoFocus
113-
/>
114-
</div>
115-
</td>
116-
<td colSpan={1} aria-label="Usage Count">
117-
{row ? <UsageCountDisplay row={row} /> : null}
118-
</td>
119-
<td
120-
colSpan={1}
121-
className="tree-table-create-row-actions-cell p-2 align-top"
122-
>
123-
<span className="d-flex justify-content-end">
124-
<span className="mr-2">
125-
<Button
126-
variant="secondary"
127-
size="sm"
128-
onClick={onCancel}
129-
>
130-
{intl.formatMessage(messages.cancelButtonLabel)}
131-
</Button>
132-
</span>
133-
<span className="mr-2">
134-
<Button variant="primary" size="sm" onClick={handleSave} disabled={saveDisabled}>
135-
{intl.formatMessage(messages.saveButtonLabel)}
136-
</Button>
137-
</span>
138-
{mutationState.isPending && (
139-
<Spinner
140-
animation="border"
141-
role="status"
142-
variant="primary"
143-
size="sm"
144-
screenReaderText={intl.formatMessage(messages.savingSpinnerScreenReaderText)}
145-
/>
146-
)}
147-
</span>
148-
</td>
149-
</tr>
150-
);
151-
};
152-
15316
const CreateRow: React.FC<CreateRowProps> = ({
15417
draftError,
15518
setDraftError,
15619
handleCreateRow,
15720
setIsCreatingTopRow,
15821
exitDraftWithoutSave,
15922
createRowMutation,
160-
columns,
16123
indent = 0,
16224
validate,
16325
}) => {
@@ -173,7 +35,6 @@ const CreateRow: React.FC<CreateRowProps> = ({
17335
onSave={handleCreateRow}
17436
onCancel={handleCancel}
17537
mutationState={createRowMutation}
176-
columns={columns}
17738
indent={indent}
17839
validate={validate}
17940
rowId="creating-top-row"
@@ -182,37 +43,4 @@ const CreateRow: React.FC<CreateRowProps> = ({
18243
);
18344
};
18445

185-
const EditRow: React.FC<EditRowProps> = ({
186-
draftError,
187-
setDraftError,
188-
initialValue,
189-
handleUpdateRow,
190-
cancelEditRow,
191-
updateRowMutation,
192-
columns,
193-
indent = 0,
194-
validate,
195-
row,
196-
}) => {
197-
const handleCancel = () => {
198-
setDraftError('');
199-
cancelEditRow();
200-
};
201-
202-
return (
203-
<DraftRow
204-
draftError={draftError}
205-
initialValue={initialValue}
206-
onSave={handleUpdateRow}
207-
onCancel={handleCancel}
208-
mutationState={updateRowMutation}
209-
columns={columns}
210-
indent={indent}
211-
validate={validate}
212-
requireValueChangeToEnableSave
213-
row={row}
214-
/>
215-
);
216-
};
217-
218-
export { CreateRow, EditRow };
46+
export default CreateRow;

0 commit comments

Comments
 (0)