refactor: break Project into its own component
I feel like Fork-Star-Watch is a pattern that we will reuse. Therefore the new component is a molecule. I also look up the person as collaborator which works for the small test set I used during development but will likely break in production for others. That's good. It will show me more information I need to design the component better. I lack that at the moment. Ideally I would use a database here, but before I can set up one I better understand the data model. Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
This commit is contained in:
parent
dda12368b3
commit
acc76294f3
2 changed files with 100 additions and 57 deletions
83
src/lib/components/molecules/Project.svelte
Normal file
83
src/lib/components/molecules/Project.svelte
Normal file
|
@ -0,0 +1,83 @@
|
|||
<!--
|
||||
A single project on the profile.
|
||||
Copyright (C) 2024 André Jaenisch
|
||||
SPDX-FileCopyrightText: 2024 André Jaenisch
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<script>
|
||||
import {
|
||||
EyeClosed16,
|
||||
Person24,
|
||||
Repo24,
|
||||
RepoForked16,
|
||||
Star16,
|
||||
TriangleDown16
|
||||
} from 'svelte-octicons';
|
||||
|
||||
/**
|
||||
* Collaborators to this project.
|
||||
*/
|
||||
export let collaborators = [];
|
||||
|
||||
/**
|
||||
* A followed project.
|
||||
*/
|
||||
export let following = {
|
||||
name: '',
|
||||
summary: ''
|
||||
};
|
||||
</script>
|
||||
|
||||
<div class="flex bg-white border border-surface-100 p-4">
|
||||
<!-- Left -->
|
||||
<div class="flex flex-col flex-grow ps-10">
|
||||
<!-- Name + Icon -->
|
||||
<div class="flex -ms-10">
|
||||
<Repo24 fill="currentColor" />
|
||||
{following.name}
|
||||
<!-- Members -->
|
||||
<ul class="ms-2 gap-4">
|
||||
{#each collaborators as member}
|
||||
<li title={member.preferredUsername}>
|
||||
<div class="bg-surface-500 text-white rounded-full">
|
||||
<Person24 fill="currentColor" />
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Description -->
|
||||
<!-- Compensate padding with negative margin -->
|
||||
<div class="flex -ms-4">
|
||||
{following.summary}
|
||||
</div>
|
||||
<!-- Tags -->
|
||||
<div class="flex"></div>
|
||||
</div>
|
||||
<!-- Right -->
|
||||
<div class="flex flex-col">
|
||||
<!-- Star Fork Watch -->
|
||||
<div class="flex gap-4">
|
||||
<button type="button" class="btn-icon border rounded-none">
|
||||
<RepoForked16 fill="currentColor" />
|
||||
</button>
|
||||
<button type="button" class="btn-icon border rounded-none">
|
||||
<Star16 fill="currentColor" />
|
||||
</button>
|
||||
<button type="button" class="btn-icon border rounded-none">
|
||||
<EyeClosed16 fill="currentColor" />
|
||||
<TriangleDown16 fill="currentColor" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- FIXME: Mark up as translatable once I figured out the
|
||||
timestamp needed here -->
|
||||
<div class="self-end">Updated somewhen</div>
|
||||
</div>
|
||||
</div>
|
|
@ -13,20 +13,13 @@ You should have received a copy of the GNU Affero General Public License along w
|
|||
|
||||
<script>
|
||||
import { _, date } from 'svelte-i18n';
|
||||
import {
|
||||
EyeClosed16,
|
||||
NorthStar24,
|
||||
Person24,
|
||||
Repo24,
|
||||
RepoForked16,
|
||||
Star16,
|
||||
TriangleDown16
|
||||
} from 'svelte-octicons';
|
||||
import { NorthStar24, Star16 } from 'svelte-octicons';
|
||||
|
||||
import Avatar from '../atoms/Avatar.svelte';
|
||||
import BlockOrReport from '../atoms/BlockOrReport.svelte';
|
||||
import Created from '../atoms/Created.svelte';
|
||||
import DisplayName from '../atoms/DisplayName.svelte';
|
||||
import Project from '../molecules/Project.svelte';
|
||||
|
||||
/**
|
||||
* Translation keys.
|
||||
|
@ -57,12 +50,17 @@ You should have received a copy of the GNU Affero General Public License along w
|
|||
export let sb = '';
|
||||
|
||||
/* Since I fetch collaborators for every following I need to filter. */
|
||||
const mapCollaboratorsToMember = function (collaborators, associatedProject) {
|
||||
const mapCollaboratorsToMember = function (people, collaborators, associatedProject) {
|
||||
const candidates = collaborators.filter((collaborator) => {
|
||||
return collaborator.context === associatedProject;
|
||||
});
|
||||
|
||||
return candidates.map((candidate) => candidate.items).flat(1);
|
||||
return candidates
|
||||
.map((candidate) => candidate.items)
|
||||
.map((members) => {
|
||||
return people.find((person) => members.find((member) => person.id === member.object));
|
||||
})
|
||||
.flat(1);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -107,52 +105,14 @@ You should have received a copy of the GNU Affero General Public License along w
|
|||
{#each data.user.followingsMap as following}
|
||||
{#if following.type === 'Project'}
|
||||
<li>
|
||||
<div class="flex bg-white border border-surface-100 p-4">
|
||||
<!-- Left -->
|
||||
<div class="flex flex-col flex-grow ps-10">
|
||||
<!-- Name + Icon -->
|
||||
<div class="flex -ms-10">
|
||||
<Repo24 fill="currentColor" />
|
||||
{following.name}
|
||||
<!-- Members -->
|
||||
<ul class="ms-2 gap-4">
|
||||
{#each mapCollaboratorsToMember(data.user.collaboratorsMap, following.id) as member}
|
||||
<li title={member.object}>
|
||||
<div class="bg-surface-500 text-white rounded-full">
|
||||
<Person24 fill="currentColor" />
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Description -->
|
||||
<!-- Compensate padding with negative margin -->
|
||||
<div class="flex -ms-4">
|
||||
{following.summary}
|
||||
</div>
|
||||
<!-- Tags -->
|
||||
<div class="flex"></div>
|
||||
</div>
|
||||
<!-- Right -->
|
||||
<div class="flex flex-col">
|
||||
<!-- Star Fork Watch -->
|
||||
<div class="flex gap-4">
|
||||
<button type="button" class="btn-icon border rounded-none">
|
||||
<RepoForked16 fill="currentColor" />
|
||||
</button>
|
||||
<button type="button" class="btn-icon border rounded-none">
|
||||
<Star16 fill="currentColor" />
|
||||
</button>
|
||||
<button type="button" class="btn-icon border rounded-none">
|
||||
<EyeClosed16 fill="currentColor" />
|
||||
<TriangleDown16 fill="currentColor" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- FIXME: Mark up as translatable once I figured out the
|
||||
timestamp needed here -->
|
||||
<div class="self-end">Updated somewhen</div>
|
||||
</div>
|
||||
</div>
|
||||
<Project
|
||||
collaborators={mapCollaboratorsToMember(
|
||||
[data.user.person],
|
||||
data.user.collaboratorsMap,
|
||||
following.id
|
||||
)}
|
||||
{following}
|
||||
/>
|
||||
</li>
|
||||
{/if}
|
||||
{/each}
|
||||
|
|
Loading…
Reference in a new issue