Commit 3bd366f0 authored by Alejandro Celaya's avatar Alejandro Celaya Committed by Alejandro Celaya

Add annotations export format select

parent 82830801
...@@ -26,6 +26,30 @@ export type ExportAnnotationsProps = { ...@@ -26,6 +26,30 @@ export type ExportAnnotationsProps = {
toastMessenger: ToastMessengerService; toastMessenger: ToastMessengerService;
}; };
type ExportFormat = {
value: 'json' | 'csv' | 'text' | 'html';
name: string;
};
const exportFormats: ExportFormat[] = [
{
value: 'json',
name: 'JSON',
},
{
value: 'csv',
name: 'CSV',
},
{
value: 'text',
name: 'Text',
},
{
value: 'html',
name: 'HTML',
},
];
/** /**
* Render content for "export" tab panel: allow user to export annotations * Render content for "export" tab panel: allow user to export annotations
* with a specified filename. * with a specified filename.
...@@ -68,6 +92,9 @@ function ExportAnnotations({ ...@@ -68,6 +92,9 @@ function ExportAnnotations({
allAnnotationsOption, allAnnotationsOption,
); );
const exportFormatsEnabled = store.isFeatureEnabled('export_formats');
const [exportFormat, setExportFormat] = useState(exportFormats[0]);
const fileInputId = useId(); const fileInputId = useId();
const userSelectId = useId(); const userSelectId = useId();
...@@ -133,17 +160,39 @@ function ExportAnnotations({ ...@@ -133,17 +160,39 @@ function ExportAnnotations({
> >
Name of export file: Name of export file:
</label> </label>
<Input <div className="flex">
data-testid="export-filename" <Input
id={fileInputId} classes="grow"
defaultValue={defaultFilename} data-testid="export-filename"
value={customFilename} id={fileInputId}
onChange={e => defaultValue={defaultFilename}
setCustomFilename((e.target as HTMLInputElement).value) value={customFilename}
} onChange={e =>
required setCustomFilename((e.target as HTMLInputElement).value)
maxLength={250} }
/> required
maxLength={250}
/>
{exportFormatsEnabled && (
<div className="grow-0 ml-2 min-w-[5rem]">
<SelectNext
value={exportFormat}
onChange={setExportFormat}
buttonContent={exportFormat.name}
data-testid="export-format-select"
>
{exportFormats.map(exportFormat => (
<SelectNext.Option
key={exportFormat.value}
value={exportFormat}
>
{exportFormat.name}
</SelectNext.Option>
))}
</SelectNext>
</div>
)}
</div>
<label htmlFor={userSelectId} className="block font-medium"> <label htmlFor={userSelectId} className="block font-medium">
Select which user{"'"}s annotations to export: Select which user{"'"}s annotations to export:
</label> </label>
...@@ -154,6 +203,7 @@ function ExportAnnotations({ ...@@ -154,6 +203,7 @@ function ExportAnnotations({
buttonContent={ buttonContent={
<UserAnnotationsListItem userAnnotations={selectedUser} /> <UserAnnotationsListItem userAnnotations={selectedUser} />
} }
data-testid="user-select"
> >
<SelectNext.Option value={allAnnotationsOption}> <SelectNext.Option value={allAnnotationsOption}>
<UserAnnotationsListItem userAnnotations={allAnnotationsOption} /> <UserAnnotationsListItem userAnnotations={allAnnotationsOption} />
......
...@@ -81,6 +81,9 @@ describe('ExportAnnotations', () => { ...@@ -81,6 +81,9 @@ describe('ExportAnnotations', () => {
$imports.$restore(); $imports.$restore();
}); });
const waitForTestId = async (wrapper, testId) =>
waitForElement(wrapper, `[data-testid="${testId}"]`);
context('export annotations not ready (loading)', () => { context('export annotations not ready (loading)', () => {
it('renders a loading spinner if there is no focused group', () => { it('renders a loading spinner if there is no focused group', () => {
fakeStore.focusedGroup.returns(null); fakeStore.focusedGroup.returns(null);
...@@ -181,7 +184,7 @@ describe('ExportAnnotations', () => { ...@@ -181,7 +184,7 @@ describe('ExportAnnotations', () => {
const wrapper = createComponent(); const wrapper = createComponent();
const userList = await waitForElement(wrapper, SelectNext); const userList = await waitForTestId(wrapper, 'user-select');
const users = userList.find(SelectNext.Option); const users = userList.find(SelectNext.Option);
assert.equal(users.length, userEntries.length); assert.equal(users.length, userEntries.length);
...@@ -207,6 +210,22 @@ describe('ExportAnnotations', () => { ...@@ -207,6 +210,22 @@ describe('ExportAnnotations', () => {
assert.equal(input.prop('defaultValue'), 'suggested-filename'); assert.equal(input.prop('defaultValue'), 'suggested-filename');
}); });
[
{ exportFormatsEnabled: true, expectedAmountOfSelects: 2 },
{ exportFormatsEnabled: false, expectedAmountOfSelects: 1 },
].forEach(({ exportFormatsEnabled, expectedAmountOfSelects }) => {
it('displays format selector when feature is enabled', async () => {
fakeStore.isFeatureEnabled.callsFake(
ff => exportFormatsEnabled || ff !== 'export_formats',
);
const wrapper = createComponent();
const selects = await waitForElement(wrapper, SelectNext);
assert.equal(selects.length, expectedAmountOfSelects);
});
});
describe('export form submitted', () => { describe('export form submitted', () => {
const submitExportForm = wrapper => const submitExportForm = wrapper =>
wrapper.find('[data-testid="export-form"]').simulate('submit'); wrapper.find('[data-testid="export-form"]').simulate('submit');
...@@ -265,7 +284,7 @@ describe('ExportAnnotations', () => { ...@@ -265,7 +284,7 @@ describe('ExportAnnotations', () => {
const wrapper = createComponent(); const wrapper = createComponent();
// Select the user whose annotations we want to export // Select the user whose annotations we want to export
const userList = await waitForElement(wrapper, SelectNext); const userList = await waitForTestId(wrapper, 'user-select');
const option = userList const option = userList
.find(SelectNext.Option) .find(SelectNext.Option)
.filterWhere( .filterWhere(
...@@ -376,7 +395,7 @@ describe('ExportAnnotations', () => { ...@@ -376,7 +395,7 @@ describe('ExportAnnotations', () => {
it('should pass a11y checks', async () => { it('should pass a11y checks', async () => {
const wrapper = createComponent(); const wrapper = createComponent();
const select = await waitForElement(wrapper, SelectNext); const select = await waitForTestId(wrapper, 'user-select');
await checkAccessibility({ await checkAccessibility({
content: () => wrapper, content: () => wrapper,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment