* chore: add i18n localization comment for AlwaysMakeProd component * feat: enhance accessibility by adding aria-label and aria-labelledby to Switch component * feat: add aria-labels for accessibility in Agent and Assistant avatar buttons * fix: add switch aria-labels for accessibility in various components * feat: add aria-labels and localization keys for accessibility in DataTable, DataTableColumnHeader, and OGDialogTemplate components * chore: refactor out nested ternary * feat: add aria-label to DataTable filter button for My Files modal * feat: add aria-labels for Buttons and localization strings * feat: add aria-labels to Checkboxes in Agent Builder * feat: enhance accessibility by adding aria-label and aria-labelledby to Checkbox component * feat: add aria-label to FileSearchCheckbox in Agent Builder * feat: add aria-label to Prompts text input area * feat: enhance accessibility by adding aria-label and aria-labelledby to TextAreaAutosize component * feat: remove improper role: "list" prop from List in Conversations.tsx to enhance accessibility and stop aria rules conflicting within react-virtualized component * feat: enhance accessibility by allowing tab navigation and adding ring highlights for conversation title editing accept/reject buttons * feat: add aria-label to Copy Link button in the conversation share modal * feat: add title to QR code svg in conversation share modal to describe the image content * feat: enhance accessibility by making Agent Avatar upload keyboard navigable and round out highlight border on focus * feat: enhance accessibility by adding aria attributes around alerting users with screen readers to invalid email address inputs in the Agent Builder * feat: add aria-labels to buttons in Advanced panel of Agent Builder * feat: enhance accessibility by making FileUpload and Clear All buttons in PresetItems keyboard navigable * feat: enchance accessiblity by indexing view and delete button aria-labels in shared links management modal to their specific chat titles * feat: add border highlighting on focus for AnimatedSearchInput * feat: add category description to aria-labels for prompts in ListCard * feat: add proper scoping to rows and columns in table headers * feat: add localized aria-labelling to EditTextPart's TextAreaAutosize component and base dynamic paramters panel components and their supporting translation keys * feat: add localized aria-labels and aria-labelledBy to Checkbox components without them * feat: add localized aria-labeledBy for endpoint settings Sliders * feat: add localized aria-labels for TextareaAutosize components * chore: remove unused i18n string * feat: add localized aria-label for BookmarkForm Checkbox * fix: add stopPropagation onKeyDown for Preview and Edit menu items in prompts that was causing the prompts to inadvertently be sent when triggered with keyboard navigation when Auto-send Prompts was toggled on * fix: switch TableCell to TableHead for title cells according to harvard issue #789 * fix: add more descriptive localization key for file filter button in DataTable * chore: remove self-explanatory code comment from RenameForm * fix: remove stray bg-yellow highlight that was left in during debugging * fix: add aria-label to model configurator panel back button * fix: undo incorrect hoist of tool name split for aria-label and span in MCPInput --------- Co-authored-by: Danny Avila <danny@librechat.ai>
118 lines
3.6 KiB
TypeScript
118 lines
3.6 KiB
TypeScript
import { OGDialogTemplate, Input, Button, OGDialog } from '@librechat/client';
|
|
import type { UseFormRegister, UseFormHandleSubmit } from 'react-hook-form';
|
|
import type { ApiKeyFormData } from '~/common';
|
|
import type { RefObject } from 'react';
|
|
import { useLocalize } from '~/hooks';
|
|
|
|
export default function ApiKeyDialog({
|
|
isOpen,
|
|
onSubmit,
|
|
onRevoke,
|
|
onOpenChange,
|
|
isUserProvided,
|
|
isToolAuthenticated,
|
|
register,
|
|
handleSubmit,
|
|
triggerRef,
|
|
triggerRefs,
|
|
}: {
|
|
isOpen: boolean;
|
|
onOpenChange: (open: boolean) => void;
|
|
onSubmit: (data: { apiKey: string }) => void;
|
|
onRevoke: () => void;
|
|
isUserProvided: boolean;
|
|
isToolAuthenticated: boolean;
|
|
register: UseFormRegister<ApiKeyFormData>;
|
|
handleSubmit: UseFormHandleSubmit<ApiKeyFormData>;
|
|
triggerRef?: RefObject<HTMLInputElement | HTMLButtonElement>;
|
|
triggerRefs?: RefObject<HTMLInputElement | HTMLButtonElement>[];
|
|
}) {
|
|
const localize = useLocalize();
|
|
const languageIcons = [
|
|
'python.svg',
|
|
'nodedotjs.svg',
|
|
'tsnode.svg',
|
|
'rust.svg',
|
|
'go.svg',
|
|
'c.svg',
|
|
'cplusplus.svg',
|
|
'php.svg',
|
|
'fortran.svg',
|
|
'r.svg',
|
|
];
|
|
|
|
return (
|
|
<OGDialog
|
|
open={isOpen}
|
|
onOpenChange={onOpenChange}
|
|
triggerRef={triggerRef}
|
|
triggerRefs={triggerRefs}
|
|
>
|
|
<OGDialogTemplate
|
|
className="w-11/12 sm:w-[450px]"
|
|
title=""
|
|
main={
|
|
<>
|
|
<div className="mb-4 text-center font-medium">
|
|
{localize('com_ui_librechat_code_api_title')}
|
|
</div>
|
|
<div className="mb-4 text-center text-sm">
|
|
{localize('com_ui_librechat_code_api_subtitle')}
|
|
</div>
|
|
{/* Language Icons Stack */}
|
|
<div className="mb-6">
|
|
<div className="mx-auto mb-4 flex max-w-[400px] flex-wrap justify-center gap-3">
|
|
{languageIcons.map((icon) => (
|
|
<div key={icon} className="h-6 w-6">
|
|
<img
|
|
src={`assets/${icon}`}
|
|
alt=""
|
|
className="h-full w-full object-contain opacity-[0.85] dark:invert"
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<a
|
|
href="https://code.librechat.ai/pricing"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="block text-center text-[15px] font-medium text-blue-500 underline decoration-1 hover:text-blue-600 dark:text-blue-400 dark:hover:text-blue-300"
|
|
>
|
|
{localize('com_ui_librechat_code_api_key')}
|
|
</a>
|
|
</div>
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<Input
|
|
type="password"
|
|
placeholder={localize('com_ui_enter_api_key')}
|
|
autoComplete="one-time-code"
|
|
readOnly={true}
|
|
onFocus={(e) => (e.target.readOnly = false)}
|
|
{...register('apiKey', { required: true })}
|
|
/>
|
|
</form>
|
|
</>
|
|
}
|
|
selection={{
|
|
selectHandler: handleSubmit(onSubmit),
|
|
selectClasses: 'bg-green-500 hover:bg-green-600 text-white',
|
|
selectText: localize('com_ui_save'),
|
|
}}
|
|
buttons={
|
|
isUserProvided &&
|
|
isToolAuthenticated && (
|
|
<Button
|
|
onClick={onRevoke}
|
|
className="bg-destructive text-white transition-all duration-200 hover:bg-destructive/80"
|
|
aria-label={localize('com_ui_revoke')}
|
|
>
|
|
{localize('com_ui_revoke')}
|
|
</Button>
|
|
)
|
|
}
|
|
showCancelButton={true}
|
|
/>
|
|
</OGDialog>
|
|
);
|
|
}
|