refactor: group commits by date and project

Yes, this means nested looping. But it also allows me to separate the
commits into a shape I need. I feel like this should not happen in
Vervis as it is something I as a consument of the data need.

I could have done this inside of the template but it feels ugly.

The main drawback I have with the current approach is that Svelte is not
capable of looping over objects so I have to turn that into a list of
nested Arrays. I might have done that in the function already but it is
easier to look up keys on an Object that to sift through Arrays.

The current implementation works. The next step is to extract it into a
component, test it and then I can refactor further.

Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
This commit is contained in:
André Jaenisch 2024-06-23 12:27:41 +02:00
parent e9c76418eb
commit 5753e14721
No known key found for this signature in database
GPG key ID: 5A668E771F1ED854

View file

@ -74,6 +74,31 @@ You should have received a copy of the GNU Affero General Public License along w
}) })
.flat(1); .flat(1);
}; };
/* Since I group commits by date and project I need to create a structure. */
const groupCommitsByDateAndProject = function (commitsMap) {
const groupByDateAndProject = {};
commitsMap
// Some commits couldn't be fetched from Vervis
.filter((commit) => Boolean(commit.id))
.forEach((commit) => {
const { committed, context } = commit;
// Ensure key exists
if (!groupByDateAndProject[committed]) {
groupByDateAndProject[committed] = {};
}
// Ensure Array exists
if (!groupByDateAndProject[committed][context]) {
groupByDateAndProject[committed][context] = [];
}
groupByDateAndProject[committed][context].push(commit);
});
return groupByDateAndProject;
};
</script> </script>
<section class="w-full mx-auto flex px-8 pt-8"> <section class="w-full mx-auto flex px-8 pt-8">
@ -199,86 +224,93 @@ You should have received a copy of the GNU Affero General Public License along w
</h2> </h2>
<ul> <ul>
{#if data?.user?.commitsMap} {#if data?.user?.commitsMap}
<!-- Commit day --> {#each Object.entries(groupCommitsByDateAndProject(data.user.commitsMap)) as commitsByDateAndProject}
<li> {#each Object.entries(commitsByDateAndProject[1]) as commitsByProject}
<!-- Indent the whole block by 6 --> <!-- Commit day -->
<div class="flex flex-col gap-6 ps-6"> <li>
<!-- Commit date --> <!-- Indent the whole block by 6 -->
<!-- But align the icon to History heading --> <div class="flex flex-col gap-6 ps-6">
<div class="flex gap-6 -ms-6"> <!-- Commit date -->
<!-- I don't group commits by date at the moment. --> <!-- But align the icon to History heading -->
<span class="bg-white"> <div class="flex gap-6 -ms-6">
<GitCommit24 fill="currentColor" /> <span class="bg-white">
</span> <GitCommit24 fill="currentColor" />
<!-- And align the date with the commits below --> </span>
<span class="flex gap-6 -ms-3"> <!-- And align the date with the commits below -->
<!-- Manually remove the failed commit map fetch from the equation --> <span class="flex gap-6 -ms-3">
<!-- Pluralisation: https://lokalise.com/blog/svelte-i18n/#Pluralization_with_Svelte_i18n --> <!-- Pluralisation: https://lokalise.com/blog/svelte-i18n/#Pluralization_with_Svelte_i18n -->
{$date(new Date(data.user.commitsMap[0].created))} - {$_( {$date(new Date(commitsByDateAndProject[0]))} - {$_(
'page.profile.history.activities.commits.number', 'page.profile.history.activities.commits.number',
{ values: { number: data.user.commitsMap.length - 1 } } { values: { number: commitsByProject[1].length } }
)} )}
<span class="flex gap-2"> <span class="flex gap-2">
<Repo24 fill="currentColor" /> <Repo24 fill="currentColor" />
<!-- Pick a repo with known commits --> {data.user.followingsMap.find(
{data.user.followingsMap[3].name} (following) => following.id === commitsByProject[0]
</span> ).name}
</span> </span>
</div> </span>
<!-- Commits --> </div>
<ul> <!-- Commits -->
{#each data.user.commitsMap as commit} <ul>
{#if commit.name} {#each commitsByProject[1] as commit}
<li class="ltr:border-l-2 rtl:border-r-2 ms-2"> {#if commit.name}
<!-- Commit body --> <li class="ltr:border-l-2 rtl:border-r-2 ms-2">
<div class="flex w-full justify-between gap-4 border border-surface-100"> <!-- Commit body -->
<!-- Detail text --> <div class="flex w-full justify-between gap-4 border border-surface-100">
<div class="flex flex-col flex-1"> <!-- Detail text -->
<span class="text-surface-500">{commit.name}</span> <div class="flex flex-col flex-1">
<span class="text-surface-400" <span class="text-surface-500">{commit.name}</span>
>{$_('page.profile.history.activities.commits.relative_time', { <span class="text-surface-400"
values: { relativeTime: $date(new Date(commit.committed)) } >{$_('page.profile.history.activities.commits.relative_time', {
})}</span values: { relativeTime: $date(new Date(commit.committed)) }
> })}</span
</div> >
<!-- SHA --> </div>
<div class="flex"> <!-- SHA -->
<button <div class="flex">
type="button" <button
class="btn-icon border border-surface-100 rounded bg-white self-start" type="button"
> class="btn-icon border border-surface-100 rounded bg-white self-start"
<Copy16 fill="currentColor" /> >
<span class="sr-only" <Copy16 fill="currentColor" />
>{$_('page.profile.history.activities.commits.actions.copy')}</span <span class="sr-only"
> >{$_(
</button> 'page.profile.history.activities.commits.actions.copy'
<!-- Since I cannot successfully define font-mono here, enforce a minimum width for equally sized buttons --> )}</span
<button >
type="button" </button>
class="btn border border-surface-100 rounded bg-white min-w-32 self-start" <!-- Since I cannot successfully define font-mono here, enforce a minimum width for equally sized buttons -->
> <button
{commit.hash.slice(0, 8)} type="button"
</button> class="btn border border-surface-100 rounded bg-white min-w-32 self-start"
</div> >
<!-- Browse --> {commit.hash.slice(0, 8)}
<div> </button>
<button </div>
type="button" <!-- Browse -->
class="btn-icon border border-surface-100 rounded bg-white" <div>
> <button
<FileDirectory16 fill="currentColor" /> type="button"
<span class="sr-only" class="btn-icon border border-surface-100 rounded bg-white"
>{$_('page.profile.history.activities.commits.actions.browse')}</span >
> <FileDirectory16 fill="currentColor" />
</button> <span class="sr-only"
</div> >{$_(
</div> 'page.profile.history.activities.commits.actions.browse'
</li> )}</span
{/if} >
{/each} </button>
</ul> </div>
</div> </div>
</li> </li>
{/if}
{/each}
</ul>
</div>
</li>
{/each}
{/each}
{:else} {:else}
<li class="flex flex-col ltr:border-l-2 rtl:border-r-2 ms-2"> <li class="flex flex-col ltr:border-l-2 rtl:border-r-2 ms-2">
<!-- Commit day --> <!-- Commit day -->