Adopt shared WebUI layout primitives
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
type FormEvent,
|
||||
} from "react";
|
||||
import { ArrowRightLeft, ListChecks, RefreshCw, Trash2 } from "lucide-react";
|
||||
import {
|
||||
import { FormGrid, DialogForm,
|
||||
ActionBlockerHint,
|
||||
Button,
|
||||
ColorPickerField,
|
||||
@@ -372,7 +372,7 @@ export function CalendarCollectionDialog({
|
||||
</>
|
||||
}>
|
||||
|
||||
<form id={formId} className="calendar-dialog-form" onSubmit={submit}>
|
||||
<DialogForm id={formId} className="calendar-dialog-form" onSubmit={submit}>
|
||||
<div className="calendar-dialog-documentation">
|
||||
<DocumentationHelpLink reference={CALENDAR_SOURCE_DOCUMENTATION} />
|
||||
</div>
|
||||
@@ -443,7 +443,7 @@ export function CalendarCollectionDialog({
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<div className="calendar-caldav-setup">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow" className="calendar-caldav-setup">
|
||||
<label className="calendar-dialog-wide">
|
||||
<span>{calendarSourceUrlLabel(sourceMode)}</span>
|
||||
<input
|
||||
@@ -532,7 +532,7 @@ export function CalendarCollectionDialog({
|
||||
}
|
||||
{effectiveCollectionUrl && <span>{effectiveCollectionUrl}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</FormGrid>
|
||||
{discoveryError && <p className="calendar-form-error">{discoveryError}</p>}
|
||||
{calendarSourceUsesCalDav(sourceMode) && discoveredCalendars.length > 0 &&
|
||||
<label>
|
||||
@@ -548,13 +548,13 @@ export function CalendarCollectionDialog({
|
||||
}
|
||||
<details className="calendar-advanced-settings">
|
||||
<summary>i18n:govoplan-calendar.advanced.4d064726</summary>
|
||||
<div className="calendar-dialog-grid-two">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.display_name.c7874aaa</span>
|
||||
<input value={displayName} onChange={(item) => setDisplayName(item.target.value)} maxLength={255} disabled={saving || !canEditMutableSourceSettings} />
|
||||
</label>
|
||||
</div>
|
||||
<div className="calendar-sync-settings">
|
||||
</FormGrid>
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<ToggleSwitch label="i18n:govoplan-calendar.automatic_sync.084644b2" checked={syncEnabled} disabled={saving || !canEditMutableSourceSettings} onChange={setSyncEnabled} />
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.interval.011efcd5</span>
|
||||
@@ -574,7 +574,7 @@ export function CalendarCollectionDialog({
|
||||
<option value="overwrite">i18n:govoplan-calendar.overwrite_remote.39625e32</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</details>
|
||||
{source &&
|
||||
<div className="calendar-sync-status-panel">
|
||||
@@ -614,7 +614,7 @@ export function CalendarCollectionDialog({
|
||||
{needsSourceSecret && <p className="calendar-form-note">i18n:govoplan-calendar.enter_a_password_or_token_for_this_source.74c09a54</p>}
|
||||
</section>
|
||||
}
|
||||
</form>
|
||||
</DialogForm>
|
||||
</Dialog>);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
type FormEvent,
|
||||
} from "react";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import {
|
||||
import { FormGrid, DialogForm,
|
||||
ActionBlockerHint,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
@@ -301,7 +301,7 @@ export function CalendarEventDialog({
|
||||
</>
|
||||
}>
|
||||
|
||||
<form id={formId} className="calendar-dialog-form" onSubmit={submit}>
|
||||
<DialogForm id={formId} className="calendar-dialog-form" onSubmit={submit}>
|
||||
<div className="calendar-dialog-documentation">
|
||||
<DocumentationHelpLink reference={CALENDAR_DOCUMENTATION} />
|
||||
</div>
|
||||
@@ -398,7 +398,7 @@ export function CalendarEventDialog({
|
||||
<summary>i18n:govoplan-calendar.vevent.9cf5be75</summary>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.identity.7e5a975b</h3>
|
||||
<div className="calendar-dialog-grid-three">
|
||||
<FormGrid columns={3} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.uid.d946adf5</span>
|
||||
<input value={uid} onChange={(item) => setUid(item.target.value)} maxLength={255} disabled={saving || !canWrite || Boolean(event)} />
|
||||
@@ -411,11 +411,11 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.sequence.5c8f4e0e</span>
|
||||
<input type="number" min={0} step={1} value={sequence} onChange={(item) => setSequence(item.target.value)} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.state.a7250206</h3>
|
||||
<div className="calendar-dialog-grid-three">
|
||||
<FormGrid columns={3} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.status.bae7d5be</span>
|
||||
<select value={status} onChange={(item) => setStatus(item.target.value)} disabled={saving || !canWrite}>
|
||||
@@ -447,11 +447,11 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.categories.6ccb6007</span>
|
||||
<input value={categoriesText} onChange={(item) => setCategoriesText(item.target.value)} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.participants.cd56e083</h3>
|
||||
<div className="calendar-dialog-grid-two">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.organizer_json.3add6f9f</span>
|
||||
<textarea value={organizerJson} onChange={(item) => setOrganizerJson(item.target.value)} rows={5} disabled={saving || !canWrite} />
|
||||
@@ -460,7 +460,7 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.attendees_json.aeb487bb</span>
|
||||
<textarea value={attendeesJson} onChange={(item) => setAttendeesJson(item.target.value)} rows={5} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.recurrence.f7ad40f5</h3>
|
||||
@@ -468,7 +468,7 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.rrule.c7b2f8a3</span>
|
||||
<input value={rruleText} onChange={(item) => setRruleText(item.target.value)} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
<div className="calendar-dialog-grid-two">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.rdate_json.5b51fca4</span>
|
||||
<textarea value={rdateJson} onChange={(item) => setRdateJson(item.target.value)} rows={5} disabled={saving || !canWrite} />
|
||||
@@ -477,11 +477,11 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.exdate_json.7d0c538d</span>
|
||||
<textarea value={exdateJson} onChange={(item) => setExdateJson(item.target.value)} rows={5} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.related.917df91e</h3>
|
||||
<div className="calendar-dialog-grid-three">
|
||||
<FormGrid columns={3} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.reminders_json.ca25e08f</span>
|
||||
<textarea value={remindersJson} onChange={(item) => setRemindersJson(item.target.value)} rows={5} disabled={saving || !canWrite} />
|
||||
@@ -494,11 +494,11 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.related_to_json.2d4e8f59</span>
|
||||
<textarea value={relatedToJson} onChange={(item) => setRelatedToJson(item.target.value)} rows={5} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.source.6da13add</h3>
|
||||
<div className="calendar-dialog-grid-three">
|
||||
<FormGrid columns={3} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.source_kind.7eda9bc4</span>
|
||||
<input value={sourceKind} onChange={(item) => setSourceKind(item.target.value)} maxLength={30} disabled={saving || !canWrite} />
|
||||
@@ -511,11 +511,11 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.etag.11d00f6e</span>
|
||||
<input value={etag} onChange={(item) => setEtag(item.target.value)} maxLength={255} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
<section className="calendar-vevent-section">
|
||||
<h3>i18n:govoplan-calendar.raw.da433cd4</h3>
|
||||
<div className="calendar-dialog-grid-two">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<label>
|
||||
<span>i18n:govoplan-calendar.icalendar_json.fb6cc33e</span>
|
||||
<textarea value={icalendarJson} onChange={(item) => setICalendarJson(item.target.value)} rows={8} disabled={saving || !canWrite} />
|
||||
@@ -524,10 +524,10 @@ export function CalendarEventDialog({
|
||||
<span>i18n:govoplan-calendar.metadata_json.b0e4c283</span>
|
||||
<textarea value={metadataJson} onChange={(item) => setMetadataJson(item.target.value)} rows={8} disabled={saving || !canWrite} />
|
||||
</label>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</section>
|
||||
</details>
|
||||
</form>
|
||||
</DialogForm>
|
||||
</Dialog>
|
||||
<ConfirmDialog
|
||||
open={Boolean(event && confirmingDelete)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { RefreshCw, RotateCcw, ScanSearch, Trash2 } from "lucide-react";
|
||||
import {
|
||||
import { ActionToolbar,
|
||||
ActionBlockerHint,
|
||||
Button,
|
||||
ConfirmDialog,
|
||||
@@ -113,7 +113,7 @@ export function CalendarOutboxDialog({
|
||||
<p className="calendar-outbox-calendar-name">{calendar.name}</p>
|
||||
<DocumentationHelpLink reference={CALENDAR_RECOVERY_DOCUMENTATION} />
|
||||
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
|
||||
<div className="calendar-outbox-toolbar">
|
||||
<ActionToolbar className="calendar-outbox-toolbar">
|
||||
<SegmentedControl<OutboxFilter>
|
||||
value={filter}
|
||||
ariaLabel="i18n:govoplan-calendar.outbox_filter.8305af40"
|
||||
@@ -128,7 +128,7 @@ export function CalendarOutboxDialog({
|
||||
<div><dt>i18n:govoplan-calendar.conflicts_dead.31252c3a</dt><dd>{conflictCount}</dd></div>
|
||||
<div><dt>i18n:govoplan-calendar.shown.498e85a1</dt><dd>{visibleOperations.length}</dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
</ActionToolbar>
|
||||
{loading && !operations.length
|
||||
? <p className="calendar-form-note">i18n:govoplan-calendar.loading_outbound_changes.3fc59656</p>
|
||||
: visibleOperations.length
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
type WheelEvent as ReactWheelEvent } from
|
||||
"react";
|
||||
import { CalendarDays, ChevronLeft, ChevronRight, Pencil, Plus, RefreshCw } from "lucide-react";
|
||||
import {
|
||||
import { ToolbarGroup, ActionToolbar,
|
||||
AdminIconButton,
|
||||
Button,
|
||||
DismissibleAlert,
|
||||
@@ -854,8 +854,8 @@ export default function CalendarPage({ settings, auth }: {settings: ApiSettings;
|
||||
</aside>
|
||||
|
||||
<section className="calendar-main-panel" aria-label="i18n:govoplan-calendar.calendar.adab5090">
|
||||
<div className="calendar-view-toolbar" aria-label="i18n:govoplan-calendar.calendar_controls.974f4fa1">
|
||||
<div className="calendar-toolbar-left">
|
||||
<ActionToolbar className="calendar-view-toolbar" aria-label="i18n:govoplan-calendar.calendar_controls.974f4fa1">
|
||||
<ToolbarGroup grow className="calendar-toolbar-left">
|
||||
<SegmentedControl
|
||||
className="calendar-mode-switch"
|
||||
size="equal"
|
||||
@@ -870,9 +870,9 @@ export default function CalendarPage({ settings, auth }: {settings: ApiSettings;
|
||||
}}
|
||||
options={modeOptions}
|
||||
/>
|
||||
</div>
|
||||
</ToolbarGroup>
|
||||
|
||||
<div className="calendar-toolbar-center">
|
||||
<ToolbarGroup align="center" className="calendar-toolbar-center">
|
||||
<div className="calendar-icon-group" aria-label="i18n:govoplan-calendar.calendar_navigation.7ba43cd2">
|
||||
<AdminIconButton
|
||||
label="i18n:govoplan-calendar.previous.50f94286"
|
||||
@@ -892,9 +892,9 @@ export default function CalendarPage({ settings, auth }: {settings: ApiSettings;
|
||||
<strong>{heading}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ToolbarGroup>
|
||||
|
||||
<div className="calendar-toolbar-right">
|
||||
<ToolbarGroup align="end" className="calendar-toolbar-right">
|
||||
<DocumentationHelpLink reference={CALENDAR_DOCUMENTATION} />
|
||||
<AdminIconButton
|
||||
label="i18n:govoplan-calendar.refresh.56e3badc"
|
||||
@@ -906,8 +906,8 @@ export default function CalendarPage({ settings, auth }: {settings: ApiSettings;
|
||||
<Plus size={17} /> i18n:govoplan-calendar.new.6403f2b7
|
||||
</Button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</ToolbarGroup>
|
||||
</ActionToolbar>
|
||||
|
||||
<div className={`calendar-view-shell is-${mode}`}>
|
||||
{mode === "continuous" ?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Save } from "lucide-react";
|
||||
import {
|
||||
import { FormGrid, ContentGrid,
|
||||
Button,
|
||||
Card,
|
||||
DismissibleAlert,
|
||||
@@ -124,12 +124,12 @@ export default function CalendarSettingsPanel({
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="dashboard-grid settings-dashboard-grid calendar-settings-panel">
|
||||
<ContentGrid columns={2} collapseAt="workspace" className="calendar-settings-panel">
|
||||
<div className="calendar-settings-documentation">
|
||||
<DocumentationHelpLink reference={CALENDAR_DOCUMENTATION} />
|
||||
</div>
|
||||
<Card title="Calendar display">
|
||||
<div className="form-grid">
|
||||
<FormGrid columns={1} collapseAt="standard" className="">
|
||||
<ToggleSwitch
|
||||
label="Dim weekends"
|
||||
help="Use a quieter background for Saturday and Sunday in week views."
|
||||
@@ -147,7 +147,7 @@ export default function CalendarSettingsPanel({
|
||||
setDraft((current) => ({ ...current, dim_off_hours }))
|
||||
}
|
||||
/>
|
||||
<div className="calendar-dialog-grid-two">
|
||||
<FormGrid columns={2} gap="small" collapseAt="narrow">
|
||||
<FormField label="Workday starts">
|
||||
<input
|
||||
type="number"
|
||||
@@ -178,11 +178,11 @@ export default function CalendarSettingsPanel({
|
||||
}
|
||||
/>
|
||||
</FormField>
|
||||
</div>
|
||||
</div>
|
||||
</FormGrid>
|
||||
</FormGrid>
|
||||
</Card>
|
||||
<Card title="Continuous view">
|
||||
<div className="form-grid">
|
||||
<FormGrid columns={1} collapseAt="standard" className="">
|
||||
<ToggleSwitch
|
||||
label="Virtualize distant weeks"
|
||||
help="Keep the continuous calendar responsive by rendering only nearby weeks."
|
||||
@@ -240,9 +240,9 @@ export default function CalendarSettingsPanel({
|
||||
{message}
|
||||
</DismissibleAlert>
|
||||
)}
|
||||
</div>
|
||||
</FormGrid>
|
||||
</Card>
|
||||
</div>
|
||||
</ContentGrid>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -944,19 +944,6 @@
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.calendar-dialog-grid-two,
|
||||
.calendar-dialog-grid-three,
|
||||
.calendar-caldav-setup,
|
||||
.calendar-sync-settings {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.calendar-dialog-grid-three {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.calendar-dialog-wide {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
@@ -1524,10 +1511,6 @@
|
||||
.calendar-dialog-row,
|
||||
.calendar-dialog-date-row,
|
||||
.calendar-dialog-name-color-row,
|
||||
.calendar-dialog-grid-two,
|
||||
.calendar-dialog-grid-three,
|
||||
.calendar-caldav-setup,
|
||||
.calendar-sync-settings,
|
||||
.calendar-sync-status-panel dl {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user