Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(storage-browser): add displayText interfaces and context #6028

Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { renderHook } from '@testing-library/react';

import { DisplayTextProvider, useDisplayText } from '../context';
import { DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT } from '../libraries';

describe('useDisplayText', () => {
it('returns default displayText`', () => {
const { result } = renderHook(useDisplayText, {
wrapper: (props) => <DisplayTextProvider {...props} />,
});

expect(result.current.LocationDetailView).toStrictEqual(
DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT['LocationDetailView']
);
expect(result.current.LocationsView).toStrictEqual(
DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT['LocationsView']
);
expect(result.current.UploadView).toStrictEqual(
DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT['UploadView']
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import { createContextUtilities } from '@aws-amplify/ui-react-core';

import { DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT } from './libraries';
import {
DefaultStorageBrowserDisplayText,
StorageBrowserDisplayText,
} from './types';

export const { DisplayTextContext, useDisplayText } = createContextUtilities<
DefaultStorageBrowserDisplayText,
'DisplayText'
>({
contextName: 'DisplayText',
errorMessage: '`useDisplayText` must be called inside `DisplayTextProvider`',
});

export function DisplayTextProvider({
children,
displayText: _override,
}: {
children?: React.ReactNode;
displayText?: StorageBrowserDisplayText;
}): React.JSX.Element {
// do deep merge here of default and override here
return (
<DisplayTextContext.Provider value={DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT}>
{children}
</DisplayTextContext.Provider>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { DisplayTextProvider, useDisplayText } from './context';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DefaultStorageBrowserDisplayText } from '../../types';

import { DEFAULT_LOCATION_DETAIL_VIEW_DISPLAY_TEXT } from './locationDetailView';
import { DEFAULT_LOCATIONS_VIEW_DISPLAY_TEXT } from './locationsView';
import { DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT } from './uploadView';

export const DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT: DefaultStorageBrowserDisplayText =
{
LocationDetailView: DEFAULT_LOCATION_DETAIL_VIEW_DISPLAY_TEXT,
LocationsView: DEFAULT_LOCATIONS_VIEW_DISPLAY_TEXT,
UploadView: DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DEFAULT_LIST_VIEW_DISPLAY_TEXT } from './shared';
import { DefaultLocationDetailViewDisplayText } from '../../types';

export const DEFAULT_LOCATION_DETAIL_VIEW_DISPLAY_TEXT: DefaultLocationDetailViewDisplayText =
{
...DEFAULT_LIST_VIEW_DISPLAY_TEXT,
getListResultsMessage: () => 'help me',
searchExhaustedMessage: 'Showing results for up to the first 10,000 items',
searchIncludeSubfoldersLabel: 'Include subfolders',
searchPlaceholder: 'Search current folder',
tableColumnLastModifiedHeader: 'Last modified',
tableColumnNameHeader: 'Name',
tableColumnSizeHeader: 'Size',
tableColumnTypeHeader: 'Type',
title: (_locations) => 'use _location to derive display value',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DEFAULT_LIST_VIEW_DISPLAY_TEXT } from './shared';
import { DefaultLocationsViewDisplayText } from '../../types';

export const DEFAULT_LOCATIONS_VIEW_DISPLAY_TEXT: DefaultLocationsViewDisplayText =
{
...DEFAULT_LIST_VIEW_DISPLAY_TEXT,
searchPlaceholder: 'Filter files and folders',
getListResultsMessage: () => 'lol',
tableColumnBucketHeader: 'Bucket',
tableColumnFolderHeader: 'Folder',
tableColumnPermissionsHeader: 'Permissions',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
DefaultActionViewDisplayText,
DefaultListViewDisplayText,
} from '../../types';

export const DEFAULT_ACTION_VIEW_DISPLAY_TEXT: Omit<
DefaultActionViewDisplayText,
'actionStartLabel' | 'getActionCompleteMessage' | 'title'
> = {
actionCancelLabel: 'Cancel',
actionExitLabel: 'Exit',
actionDestinationLabel: 'Destination',
statusDisplayCanceledLabel: 'Canceled',
statusDisplayCompletedLabel: 'Completed',
statusDisplayFailedLabel: 'Failed',
statusDisplayTotalLabel: 'Total',
statusDisplayQueuedLabel: 'Not Started',
// empty by default
tableColumnCancelHeader: '',
tableColumnStatusHeader: 'Status',
tableColumnFolderHeader: 'Folder',
tableColumnNameHeader: 'Name',
tableColumnTypeHeader: 'Type',
tableColumnSizeHeader: 'Size',
};

export const DEFAULT_LIST_VIEW_DISPLAY_TEXT: Omit<
DefaultListViewDisplayText,
'getListResultsMessage' | 'searchPlaceholder'
> = {
searchSubmitLabel: 'Search',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { DEFAULT_ACTION_VIEW_DISPLAY_TEXT } from './shared';
import { DefaultUploadViewDisplayText } from '../../types';

export const DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT: DefaultUploadViewDisplayText = {
...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
title: 'Upload',
actionStartLabel: 'Upload',
addFilesLabel: 'Add files',
addFolderLabel: 'Add folder',
getActionCompleteMessage: (counts) => {
if (counts.FAILED === counts.TOTAL) {
return 'All uploads failed to complete.';
}

if (counts.CANCELED === counts.TOTAL) {
return 'All uploads canceled.';
}

if (counts.OVERWRITE_PREVENTED === counts.TOTAL) {
return 'Overwrite prevention applied to all uploads.';
}

if (counts.TOTAL === counts.COMPLETE) {
return 'All uploads completed successfully.';
}

const prefix = 'All uploads complete';

const succeeded = `${counts.COMPLETE} uploads successful`;
const overwritePrevented = `overwrite prevention applied to ${counts.OVERWRITE_PREVENTED} uploads`;
const _canceled = `${counts.CANCELED} uploads canceled`;
const _failed = `${counts.FAILED} uploads failed`;

// succeeded & errors
// succeeded & errors & cancellations
// succeeded & errors & cancellations & overwrite prevented
// succeeded & cancellations
// succeeded & cancellations & overwrite prevented
// errors & cancellations
// errors & cancellations & overwrite prevented
// succeeded & cancellations & overwrite prevented
// succeeded & overwrite prevented
if (counts.TOTAL === counts.COMPLETE + counts.OVERWRITE_PREVENTED) {
return `${prefix}. ${succeeded}, ${overwritePrevented}.`;
}

const hasErrors = counts.FAILED > 0;
const _hasCanceledTasks = counts.CANCELED > 0;

if (hasErrors) {
return `All uploads complete. ${counts.COMPLETE} of ${counts.TOTAL} uploads successful, ${counts.FAILED} uploads failed to complete.`;
}

return '🤷';
},
statusDisplayCanceledLabel: 'Canceled',
statusDisplayCompletedLabel: 'Completed',
statusDisplayFailedLabel: 'Failed',
statusDisplayOverridePreventedLabel: 'Overwrite prevented',
statusDisplayQueuedLabel: 'Not Started',
overwriteExistingLabel: 'Overwrite existing files',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT } from './en/default';
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { TaskCounts } from '../controls/types';
import { LocationData, LocationItemData } from '../actions';

/**
* Common display text values available on each action view (e.g. upload, copy, etc)
*/
export interface DefaultActionViewDisplayText {
actionCancelLabel: string;
actionDestinationLabel: string;
actionExitLabel: string;
actionStartLabel: string;
getActionCompleteMessage: (counts: TaskCounts) => string;
statusDisplayCanceledLabel: string;
statusDisplayCompletedLabel: string;
statusDisplayFailedLabel: string;
statusDisplayQueuedLabel: string;
statusDisplayTotalLabel: string;
title: string;
tableColumnCancelHeader: string;
tableColumnStatusHeader: string;
tableColumnFolderHeader: string;
tableColumnNameHeader: string;
tableColumnTypeHeader: string;
tableColumnSizeHeader: string;
}

/**
* Common list view display text values
*/
export interface DefaultListViewDisplayText<T = any> {
searchPlaceholder: string;
searchSubmitLabel: string;
getListResultsMessage: (data: T, error?: Error) => string;
}

export interface DefaultLocationsViewDisplayText
extends DefaultListViewDisplayText<LocationData> {
tableColumnFolderHeader: string;
tableColumnBucketHeader: string;
tableColumnPermissionsHeader: string;
}

export interface DefaultLocationDetailViewDisplayText
extends DefaultListViewDisplayText<LocationItemData> {
title: string | ((location: LocationData) => string);
searchExhaustedMessage: string;
searchIncludeSubfoldersLabel: string;
tableColumnLastModifiedHeader: string;
tableColumnNameHeader: string;
tableColumnSizeHeader: string;
tableColumnTypeHeader: string;
}

export interface DefaultUploadViewDisplayText
extends DefaultActionViewDisplayText {
addFilesLabel: string;
addFolderLabel: string;
statusDisplayOverridePreventedLabel: string;
overwriteExistingLabel: string;
}

export interface DefaultStorageBrowserDisplayText {
LocationsView: DefaultLocationsViewDisplayText;
LocationDetailView: DefaultLocationDetailViewDisplayText;
UploadView: DefaultUploadViewDisplayText;
// CopyView
// DeleteView
// CreateFolderView
}

interface LocationsViewDisplayText
extends Partial<DefaultLocationsViewDisplayText> {}
interface LocationDetailViewDisplayText
extends Partial<DefaultLocationDetailViewDisplayText> {}
interface UploadViewDisplayText extends Partial<DefaultUploadViewDisplayText> {}

export interface StorageBrowserDisplayText {
LocationsView?: LocationsViewDisplayText;
LocationDetailView?: LocationDetailViewDisplayText;
UploadView?: UploadViewDisplayText;
// CopyView
// DeleteView
// CreateFolderView
}
Loading