Skip to content

Commit

Permalink
Filter by lead on changes page.
Browse files Browse the repository at this point in the history
  • Loading branch information
amyjko committed Dec 20, 2024
1 parent ba2e8e6 commit 5f1dd4a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Dates should be in`YYYY-MM-DD` format and versions are in [semantic versioning](

## v0.7.5 2024-12-19

### Added

- Filter by lead on changes page.

### Fixed

- Prevented cycle in changes and processes URL navigation.
Expand Down
45 changes: 42 additions & 3 deletions src/lib/Changes.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import Dialog from './Dialog.svelte';
import NewComment from './NewComment.svelte';
import Button from './Button.svelte';
import Select from './Select.svelte';
interface Props {
changes: ChangeRow[];
Expand All @@ -44,6 +45,7 @@
let filterText = $state(getInitialTextFilter());
let filterStatus = $state<undefined | StatusType>(getInitialStatusFilter());
let filterLead = $state<undefined | string>(getInitialLeadFilter());
let lowerFilter = $derived(filterText.toLocaleLowerCase().trim());
let textFilteredChanges = $derived(
Expand All @@ -62,6 +64,14 @@
: textFilteredChanges.filter((change) => change.status === filterStatus)
);
let leadFilteredChanges = $derived(
filterLead === undefined
? statusFilteredChanges
: statusFilteredChanges.filter((change) => change.lead === filterLead)
);
let filteredChanges = $derived(leadFilteredChanges);
/** The change for which a comment is being submitted */
let submittingComment: ChangeRow | undefined = $state(undefined);
function hideNewComment() {
Expand All @@ -78,6 +88,12 @@
return status !== null && status in Statuses ? (status as StatusType) : undefined;
}
function getInitialLeadFilter() {
const params = $page.url.searchParams;
const lead = params.get('lead');
return lead !== null ? lead : undefined;
}
// When the filters change, update the URL to match
$effect(() => {
const params = new URLSearchParams($page.url.searchParams.toString());
Expand All @@ -86,14 +102,16 @@
else params.set('words', encodeURI(filterText));
if (filterStatus === undefined) params.delete('status');
else params.set('status', filterStatus);
if (filterLead === undefined) params.delete('lead');
else params.set('lead', filterLead);
// Did the params change? Navigate.
if (start !== params.toString())
goto(`?${params.toString()}`, { replaceState: true, keepFocus: true });
});
// The filtered list of comment IDs that we need to asynchronously load.
let latestCommentIDs = $derived(
statusFilteredChanges.map((change) => change.comments.at(-1))?.filter((c) => c !== undefined)
filteredChanges.map((change) => change.comments.at(-1))?.filter((c) => c !== undefined)
);
let latestComments = $state<CommentRow[]>([]);
Expand All @@ -120,6 +138,27 @@
value={filterStatus}
/>
</Labeled>
<Labeled label="Filter by lead">
<!-- An option of all leads specified in the changes -->
<Select
tip="Filter by lead"
selection={filterLead}
options={[
{ value: undefined, label: 'All' },
...changes
.map((change) =>
change.lead === null
? null
: {
value: change.lead,
label: org.getProfileNameOrEmail(change.lead) ?? ''
}
)
.filter((change) => change !== null)
]}
change={(value) => (filterLead = value)}
/>
</Labeled>
</Flow>
<Table fixed>
<thead>
Expand All @@ -131,7 +170,7 @@
</tr>
</thead>
<tbody>
{#each statusFilteredChanges
{#each filteredChanges
.sort((a, b) => timestampToDate(a.when).getTime() - timestampToDate(b.when).getTime())
.sort((a, b) => Levels[a.status] - Levels[b.status]) as change}
<!-- Get the most recent comment -->
Expand All @@ -152,7 +191,7 @@
>+</Button
>
{#if comment}
<em>{(org.getProfileWithPersonID(comment.who)?.name ?? '').split(' ')[0]}</em>
<em>{(org.getPersonNameOrEmail(comment.who) ?? '').split(' ')[0]}</em>
<TimeView time={false} date={timestampToDate(comment.when)} />
<MarkupView small markup={comment.what.split('\n')[0]} placeholder="status"
></MarkupView>
Expand Down
12 changes: 12 additions & 0 deletions src/types/Organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,18 @@ export default class Organization {
});
}

/** Get the name or email of the profile ID */
getPersonNameOrEmail(id: PersonID): string | null {
const profile = this.getProfileWithPersonID(id);
return profile === null ? null : profile.name === '' ? profile.email : profile.name;
}

/** Get the name or email of the profile ID */
getProfileNameOrEmail(id: PersonID): string | null {
const profile = this.getProfileWithID(id);
return profile === null ? null : profile.name === '' ? profile.email : profile.name;
}

/** Find the profile of the given person, or null if no match */
getProfileWithID(id: ProfileID): ProfileRow | null {
return this.data.profiles.find((person) => person.id === id) ?? null;
Expand Down

0 comments on commit 5f1dd4a

Please sign in to comment.