Calendar · Agenda and people: an agenda, an event's details, its guests
AgendaView lists the days ahead under their names, whole days first, then by the hour, and leaves out days with nothing; it rides on lists::Sections, so a press or an arrow selects and Enter opens. An empty stretch says nothing is planned. EventPopover is an event's chip that opens its details: its title in its hue, when and where, who is asked, and Edit and Delete when the owner handles them. It opens through Popover::with_opener, which now hands any element the toggle and keeps focus, placement and every way out in the popover. AttendeeList counts the answers and lists each guest with their answer, the organizer first. A hue worn in a row is now data_display::color_mark, for mail labels and events alike.
This commit is contained in:
1 parent
57dd55320e
commit
48ff348357
17 files changed
+940
-37
No files matched your search
@@ -8,6 +8,7 @@ use gpui::{
|
||||
use jiff::{Timestamp, ToSpan, civil::Date, tz::TimeZone};
|
||||
|
||||
mod months;
|
||||
mod people;
|
||||
mod times;
|
||||
|
||||
use super::Page;
|
||||
@@ -45,6 +46,11 @@ const SCRIPT: &[Step] = &[
|
||||
Step::UpAt("calendar-week", 560.0, 380.0),
|
||||
Step::Wait(200),
|
||||
Step::Shot("week-made"),
|
||||
Step::DownAt("calendar-popover", 60.0, 10.0),
|
||||
Step::UpAt("calendar-popover", 60.0, 10.0),
|
||||
Step::Wait(300),
|
||||
Step::Shot("popover-open"),
|
||||
Step::Key("escape"),
|
||||
];
|
||||
|
||||
/// What a demo says it did, under it.
|
||||
@@ -101,6 +107,8 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
.child(months::mini(window, cx))
|
||||
.child(times::week(window, cx))
|
||||
.child(times::day(window, cx))
|
||||
.child(people::agenda(window, cx))
|
||||
.child(people::details(window, cx))
|
||||
.child(months::year(window, cx))
|
||||
.child(months::marks(cx))
|
||||
.into_any_element()
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
use ely_gpui_component::calendar::{AgendaView, Answer, Attendee, AttendeeList, EventPopover};
|
||||
use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, px};
|
||||
|
||||
use super::{here, plan, quiet};
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{change, keep, section, set},
|
||||
};
|
||||
|
||||
fn guests() -> [Attendee; 5] {
|
||||
[
|
||||
Attendee::new("Chloé Martin", "chloe@atrium.studio", Answer::Going).organizer(),
|
||||
Attendee::new("Ana Lima", "ana@atrium.studio", Answer::Going),
|
||||
Attendee::new("Ben Ito", "ben@atrium.studio", Answer::Maybe),
|
||||
Attendee::new("Dev Rao", "dev@atrium.studio", Answer::Waiting),
|
||||
Attendee::new("Eli Park", "eli@atrium.studio", Answer::Declined),
|
||||
]
|
||||
}
|
||||
|
||||
pub fn agenda(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let (zone, today) = here();
|
||||
let listed = plan(window, cx).read(cx).clone();
|
||||
let said = keep("calendar-agenda-said", || None::<SharedString>, window, cx);
|
||||
let shown = said.read(cx).clone();
|
||||
section(
|
||||
"AgendaView",
|
||||
"The days ahead with their events under each day's name, whole days first, then by the hour; days with nothing are left out. A press or an arrow selects, Enter or a double press opens.",
|
||||
cx,
|
||||
)
|
||||
.child(probe(
|
||||
"calendar-agenda",
|
||||
div()
|
||||
.w(px(420.))
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_3()
|
||||
.child(
|
||||
AgendaView::new("calendar-agenda", today, 7, listed)
|
||||
.zone(zone)
|
||||
.on_event(move |key, _, cx| set(&said, Some(format!("Opened {key}.").into()), cx)),
|
||||
)
|
||||
.children(shown.map(|shown| quiet(shown, cx))),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn details(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let (zone, _) = here();
|
||||
let events = plan(window, cx);
|
||||
let review = events
|
||||
.read(cx)
|
||||
.iter()
|
||||
.find(|event| event.key.as_ref() == "review")
|
||||
.cloned()
|
||||
.expect("the demo holds the review");
|
||||
let said = keep("calendar-popover-said", || None::<SharedString>, window, cx);
|
||||
let shown = said.read(cx).clone();
|
||||
let (edited, dropped) = (said.clone(), said);
|
||||
section(
|
||||
"EventPopover / AttendeeList",
|
||||
"An event's chip opens its details: when and where, who is asked and what each said, and what can be done with it. The list of guests stands on its own too.",
|
||||
cx,
|
||||
)
|
||||
.child(probe(
|
||||
"calendar-popover",
|
||||
div()
|
||||
.flex()
|
||||
.items_start()
|
||||
.gap_8()
|
||||
.child(
|
||||
div()
|
||||
.w(px(200.))
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_3()
|
||||
.child(
|
||||
EventPopover::new("calendar-popover", review)
|
||||
.zone(zone)
|
||||
.attendees(guests())
|
||||
.on_edit(move |key, _, cx| {
|
||||
set(&edited, Some(format!("Edit {key}.").into()), cx)
|
||||
})
|
||||
.on_delete(move |key, _, cx| {
|
||||
change(&events, cx, |events| events.retain(|event| event.key != *key));
|
||||
set(&dropped, Some(format!("Deleted {key}.").into()), cx)
|
||||
}),
|
||||
)
|
||||
.children(shown.map(|shown| quiet(shown, cx))),
|
||||
)
|
||||
.child(div().w(px(360.)).child(AttendeeList::new("calendar-guests", guests()))),
|
||||
))
|
||||
}
|
||||
Reference in new issue
Block a user