|
|
@@ -36,21 +36,26 @@ export default function SearchForm({
|
|
|
<form
|
|
|
onSubmit={(e) => {
|
|
|
e.preventDefault();
|
|
|
+
|
|
|
+ // UX rule:
|
|
|
+ // - Only submit when the query is non-empty.
|
|
|
+ // - This keeps the Search API safe and avoids accidental “match everything”.
|
|
|
if (!canSearch) return;
|
|
|
+
|
|
|
onSubmit();
|
|
|
}}
|
|
|
- className="space-y-3"
|
|
|
+ className="space-y-4"
|
|
|
>
|
|
|
- <SearchQueryBox
|
|
|
- qDraft={qDraft}
|
|
|
- onQDraftChange={onQDraftChange}
|
|
|
- onSubmit={onSubmit}
|
|
|
- currentQuery={currentQuery}
|
|
|
- isSubmitting={isSubmitting}
|
|
|
- canSearch={canSearch}
|
|
|
- />
|
|
|
-
|
|
|
- <div className="flex flex-wrap items-center gap-2">
|
|
|
+ {/*
|
|
|
+ Layout goal (RHL-038):
|
|
|
+ - Desktop: one row with (1) scope, (2) query, (3) limit
|
|
|
+ - Mobile: natural stacking
|
|
|
+ Implementation:
|
|
|
+ - Use a responsive grid that becomes 3 columns on lg+
|
|
|
+ - Align items to the bottom so labels line up nicely.
|
|
|
+ */}
|
|
|
+ <div className="grid gap-3 lg:grid-cols-[auto_1fr_auto] lg:items-end">
|
|
|
+ {/* 1) Scope (admin/dev only) */}
|
|
|
{isAdminDev ? (
|
|
|
<SearchScopeSelect
|
|
|
branch={branch}
|
|
|
@@ -60,24 +65,43 @@ export default function SearchForm({
|
|
|
/>
|
|
|
) : null}
|
|
|
|
|
|
- {isAdminDev && scope === SEARCH_SCOPE.SINGLE ? (
|
|
|
- <SearchSingleBranchCombobox
|
|
|
- branch={branch}
|
|
|
- branchesStatus={branchesStatus}
|
|
|
- availableBranches={availableBranches}
|
|
|
- onSingleBranchChange={onSingleBranchChange}
|
|
|
- isSubmitting={isSubmitting}
|
|
|
- />
|
|
|
- ) : null}
|
|
|
+ {/* 2) Query (always) */}
|
|
|
+ <SearchQueryBox
|
|
|
+ qDraft={qDraft}
|
|
|
+ onQDraftChange={onQDraftChange}
|
|
|
+ onSubmit={onSubmit}
|
|
|
+ currentQuery={currentQuery}
|
|
|
+ isSubmitting={isSubmitting}
|
|
|
+ canSearch={canSearch}
|
|
|
+ />
|
|
|
|
|
|
+ {/* 3) Limit (always) */}
|
|
|
<SearchLimitSelect
|
|
|
limit={limit}
|
|
|
onLimitChange={onLimitChange}
|
|
|
isSubmitting={isSubmitting}
|
|
|
/>
|
|
|
</div>
|
|
|
+
|
|
|
+ {/*
|
|
|
+ Admin/dev: SINGLE branch selection.
|
|
|
+ We keep this *below* the main row so the top row stays exactly:
|
|
|
+ Scope | Query | Limit
|
|
|
+ */}
|
|
|
+ {isAdminDev && scope === SEARCH_SCOPE.SINGLE ? (
|
|
|
+ <div>
|
|
|
+ <SearchSingleBranchCombobox
|
|
|
+ branch={branch}
|
|
|
+ branchesStatus={branchesStatus}
|
|
|
+ availableBranches={availableBranches}
|
|
|
+ onSingleBranchChange={onSingleBranchChange}
|
|
|
+ isSubmitting={isSubmitting}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
</form>
|
|
|
|
|
|
+ {/* Multi scope branch picker remains below the form row (as requested). */}
|
|
|
{isAdminDev && scope === SEARCH_SCOPE.MULTI ? (
|
|
|
<SearchMultiBranchPicker
|
|
|
branchesStatus={branchesStatus}
|