improvement: clinic/lab search button removed. search now happens on debounce.

This commit is contained in:
2026-07-12 18:37:04 +03:30
parent fab5111aa8
commit 3b47aa9605

View File

@@ -48,6 +48,7 @@ export default function OrganizationsPage() {
const { currentOrganization } = useAuth(); const { currentOrganization } = useAuth();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const toast = useToast(); const toast = useToast();
const { showError, setError: setToastError } = toast;
const formatApiMessage = useCallback( const formatApiMessage = useCallback(
(err: unknown): string => getUserFacingError(err, tErrors, tCommon('errorGeneric')), (err: unknown): string => getUserFacingError(err, tErrors, tCommon('errorGeneric')),
@@ -122,29 +123,44 @@ export default function OrganizationsPage() {
void loadList(); void loadList();
}, []); }, []);
async function runSearch() { useEffect(() => {
let cancelled = false;
const q = query.trim(); const q = query.trim();
if (!q) { if (!q) {
setMode('existing'); setMode('existing');
setSearchResults([]); setSearchResults([]);
setShowInviteForm(false); setShowInviteForm(false);
setSearching(false);
return; return;
} }
setSearching(true);
toast.setError('');
setMode('search'); setMode('search');
setShowInviteForm(false); setShowInviteForm(false);
setSearching(true);
const timeout = setTimeout(() => {
void (async () => {
setToastError('');
try { try {
const res = await organizationApi.search(q); const res = await organizationApi.search(q);
if (cancelled) return;
setSearchResults(res.data); setSearchResults(res.data);
} catch (e) { } catch (e) {
toast.showError(formatApiMessage(e)); if (cancelled) return;
showError(formatApiMessage(e));
setSearchResults([]); setSearchResults([]);
} finally { } finally {
setSearching(false); if (!cancelled) setSearching(false);
}
} }
})();
}, 300);
return () => {
cancelled = true;
clearTimeout(timeout);
};
}, [query, formatApiMessage, showError, setToastError]);
async function submitConnectionRequest(targetOrganizationId: string) { async function submitConnectionRequest(targetOrganizationId: string) {
setPendingConnectionRowId(targetOrganizationId); setPendingConnectionRowId(targetOrganizationId);
@@ -315,19 +331,9 @@ export default function OrganizationsPage() {
<SearchBar <SearchBar
value={query} value={query}
onChange={setQuery} onChange={setQuery}
onSubmit={() => void runSearch()}
placeholder={t('searchPlaceholder', { counterpart: counterpart.toLowerCase() })} placeholder={t('searchPlaceholder', { counterpart: counterpart.toLowerCase() })}
actions={ actions={
<> query.trim() ? (
<button
type="button"
onClick={() => void runSearch()}
disabled={searching}
className="px-4 py-2 rounded-[var(--radius-sm)] text-sm font-medium border bg-primary-soft text-primary border-primary/50 disabled:opacity-60"
>
{tCommon('search')}
</button>
{mode === 'search' && (
<button <button
type="button" type="button"
onClick={clearSearchView} onClick={clearSearchView}
@@ -335,13 +341,12 @@ export default function OrganizationsPage() {
> >
{t('backToList')} {t('backToList')}
</button> </button>
)} ) : undefined
</>
} }
/> />
<OrganizationConnectionsMobileList <OrganizationConnectionsMobileList
loading={loading} loading={loading || searching}
mode={mode} mode={mode}
existingRows={existingRows} existingRows={existingRows}
searchResults={searchResults} searchResults={searchResults}
@@ -409,7 +414,7 @@ export default function OrganizationsPage() {
} }
body={ body={
<> <>
{loading ? ( {loading || (mode === 'search' && searching) ? (
<tr> <tr>
<td colSpan={5} className="px-6 py-8 text-sm text-text-secondary"> <td colSpan={5} className="px-6 py-8 text-sm text-text-secondary">
{tCommon('loadingEllipsis')} {tCommon('loadingEllipsis')}