ui: Better layout for root team
This commit is contained in:
parent
5bf14f4639
commit
2f8d0ee60c
@ -100,6 +100,7 @@ export const getUserDetails = async (event, isAdminRequired = true) => {
|
||||
message: 'OK'
|
||||
}
|
||||
};
|
||||
|
||||
if (isAdminRequired && permission !== 'admin' && permission !== 'owner') {
|
||||
payload.status = 401;
|
||||
payload.body.message =
|
||||
|
@ -12,7 +12,7 @@
|
||||
if (!session.userId) {
|
||||
return {};
|
||||
}
|
||||
const endpoint = `/teams.json`;
|
||||
const endpoint = `/dashboard.json`;
|
||||
const res = await fetch(endpoint);
|
||||
|
||||
if (res.ok) {
|
||||
|
@ -8,6 +8,16 @@
|
||||
const { id } = await post('/applications/new', {});
|
||||
return await goto(`/applications/${id}`, { replaceState: true });
|
||||
}
|
||||
const ownApplications = applications.filter((application) => {
|
||||
if (application.teams[0].id === $session.teamId) {
|
||||
return application;
|
||||
}
|
||||
});
|
||||
const otherApplications = applications.filter((application) => {
|
||||
if (application.teams[0].id !== $session.teamId) {
|
||||
return application;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@ -36,8 +46,23 @@
|
||||
<div class="text-center text-xl font-bold">No applications found</div>
|
||||
</div>
|
||||
{:else}
|
||||
{#each applications as application}
|
||||
<div class="flex flex-col">
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 -ml-10">Your Team's Applications</div>
|
||||
{/if}
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{#each ownApplications as application}
|
||||
<Application {application} />
|
||||
{/each}
|
||||
</div>
|
||||
{#if otherApplications.length > 0 && $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 pt-10 -ml-10">Other Team's Applications</div>
|
||||
<div class="flex">
|
||||
{#each otherApplications as application}
|
||||
<Application {application} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -9,23 +9,28 @@ export const get: RequestHandler = async (event) => {
|
||||
|
||||
try {
|
||||
const applicationsCount = await db.prisma.application.count({
|
||||
where: { teams: { some: { id: teamId } } }
|
||||
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }
|
||||
});
|
||||
const sourcesCount = await db.prisma.gitSource.count({
|
||||
where: { teams: { some: { id: teamId } } }
|
||||
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }
|
||||
});
|
||||
const destinationsCount = await db.prisma.destinationDocker.count({
|
||||
where: { teams: { some: { id: teamId } } }
|
||||
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }
|
||||
});
|
||||
const teamsCount = await db.prisma.permission.count({ where: { userId } });
|
||||
const databasesCount = await db.prisma.database.count({
|
||||
where: { teams: { some: { id: teamId } } }
|
||||
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }
|
||||
});
|
||||
const servicesCount = await db.prisma.service.count({
|
||||
where: { teams: { some: { id: teamId } } }
|
||||
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } }
|
||||
});
|
||||
const teams = await db.prisma.permission.findMany({
|
||||
where: { userId },
|
||||
include: { team: { include: { _count: { select: { users: true } } } } }
|
||||
});
|
||||
return {
|
||||
body: {
|
||||
teams,
|
||||
applicationsCount,
|
||||
sourcesCount,
|
||||
destinationsCount,
|
||||
|
@ -14,6 +14,16 @@
|
||||
const { id } = await post('/databases/new', {});
|
||||
return await goto(`/databases/${id}`, { replaceState: true });
|
||||
}
|
||||
const ownDatabases = databases.filter((database) => {
|
||||
if (database.teams[0].id === $session.teamId) {
|
||||
return database;
|
||||
}
|
||||
});
|
||||
const otherDatabases = databases.filter((database) => {
|
||||
if (database.teams[0].id !== $session.teamId) {
|
||||
return database;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@ -41,7 +51,12 @@
|
||||
<div class="text-center text-xl font-bold">No databases found</div>
|
||||
</div>
|
||||
{:else}
|
||||
{#each databases as database}
|
||||
<div class="flex flex-col">
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 -ml-10">Your Team's Databases</div>
|
||||
{/if}
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{#each ownDatabases as database}
|
||||
<a href="/databases/{database.id}" class="no-underline p-2 w-96">
|
||||
<div class="box-selection relative hover:bg-purple-600 group">
|
||||
{#if database.type === 'clickhouse'}
|
||||
@ -73,5 +88,44 @@
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{#if otherDatabases.length > 0 && $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 pt-10 -ml-10">Other Team's Databases</div>
|
||||
<div class="flex">
|
||||
{#each otherDatabases as database}
|
||||
<a href="/databases/{database.id}" class="no-underline p-2 w-96">
|
||||
<div class="box-selection relative hover:bg-purple-600 group">
|
||||
{#if database.type === 'clickhouse'}
|
||||
<Clickhouse isAbsolute />
|
||||
{:else if database.type === 'couchdb'}
|
||||
<CouchDB isAbsolute />
|
||||
{:else if database.type === 'mongodb'}
|
||||
<MongoDB isAbsolute />
|
||||
{:else if database.type === 'mysql'}
|
||||
<MySQL isAbsolute />
|
||||
{:else if database.type === 'postgresql'}
|
||||
<PostgreSQL isAbsolute />
|
||||
{:else if database.type === 'redis'}
|
||||
<Redis isAbsolute />
|
||||
{/if}
|
||||
<div class="font-bold text-xl text-center truncate">
|
||||
{database.name}
|
||||
</div>
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-center truncate">Team {database.teams[0].name}</div>
|
||||
{/if}
|
||||
{#if !database.type}
|
||||
<div class="font-bold text-center truncate text-red-500 group-hover:text-white">
|
||||
Configuration missing
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-center truncate">{database.type}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -24,6 +24,16 @@
|
||||
|
||||
import { session } from '$app/stores';
|
||||
export let destinations: Prisma.DestinationDocker[];
|
||||
const ownDestinations = destinations.filter((destination) => {
|
||||
if (destination.teams[0].id === $session.teamId) {
|
||||
return destination;
|
||||
}
|
||||
});
|
||||
const otherDestinations = destinations.filter((destination) => {
|
||||
if (destination.teams[0].id !== $session.teamId) {
|
||||
return destination;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@ -52,8 +62,28 @@
|
||||
<div class="text-center text-xl font-bold">No destination found</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-wrap justify-center">
|
||||
{#each destinations as destination}
|
||||
<div class="flex flex-col">
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 -ml-10">Your Team's Destinations</div>
|
||||
{/if}
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{#each ownDestinations as destination}
|
||||
<a href="/destinations/{destination.id}" class="no-underline p-2 w-96">
|
||||
<div class="box-selection hover:bg-sky-600">
|
||||
<div class="font-bold text-xl text-center truncate">{destination.name}</div>
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-center truncate">Team {destination.teams[0].name}</div>
|
||||
{/if}
|
||||
<div class="text-center truncate">{destination.network}</div>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if otherDestinations.length > 0 && $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 pt-10 -ml-10">Other Team's Destinations</div>
|
||||
<div class="flex">
|
||||
{#each otherDestinations as destination}
|
||||
<a href="/destinations/{destination.id}" class="no-underline p-2 w-96">
|
||||
<div class="box-selection hover:bg-sky-600">
|
||||
<div class="font-bold text-xl text-center truncate">{destination.name}</div>
|
||||
@ -66,4 +96,6 @@
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -19,6 +19,16 @@
|
||||
const { id } = await post('/services/new', {});
|
||||
return await goto(`/services/${id}`, { replaceState: true });
|
||||
}
|
||||
const ownServices = services.filter((service) => {
|
||||
if (service.teams[0].id === $session.teamId) {
|
||||
return service;
|
||||
}
|
||||
});
|
||||
const otherServices = services.filter((service) => {
|
||||
if (service.teams[0].id !== $session.teamId) {
|
||||
return service;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@ -46,7 +56,12 @@
|
||||
<div class="text-center text-xl font-bold">No services found</div>
|
||||
</div>
|
||||
{:else}
|
||||
{#each services as service}
|
||||
<div class="flex flex-col">
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 -ml-10">Your Team's Applications</div>
|
||||
{/if}
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{#each ownServices as service}
|
||||
<a href="/services/{service.id}" class="no-underline p-2 w-96">
|
||||
<div class="box-selection relative hover:bg-pink-600 group">
|
||||
{#if service.type === 'plausibleanalytics'}
|
||||
@ -88,5 +103,54 @@
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{#if otherServices.length > 0 && $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 pt-10 -ml-10">Other Team's Applications</div>
|
||||
<div class="flex">
|
||||
{#each otherServices as service}
|
||||
<a href="/services/{service.id}" class="no-underline p-2 w-96">
|
||||
<div class="box-selection relative hover:bg-pink-600 group">
|
||||
{#if service.type === 'plausibleanalytics'}
|
||||
<PlausibleAnalytics isAbsolute />
|
||||
{:else if service.type === 'nocodb'}
|
||||
<NocoDb isAbsolute />
|
||||
{:else if service.type === 'minio'}
|
||||
<MinIo isAbsolute />
|
||||
{:else if service.type === 'vscodeserver'}
|
||||
<VsCodeServer isAbsolute />
|
||||
{:else if service.type === 'wordpress'}
|
||||
<Wordpress isAbsolute />
|
||||
{:else if service.type === 'vaultwarden'}
|
||||
<VaultWarden isAbsolute />
|
||||
{:else if service.type === 'languagetool'}
|
||||
<LanguageTool isAbsolute />
|
||||
{:else if service.type === 'n8n'}
|
||||
<N8n isAbsolute />
|
||||
{:else if service.type === 'uptimekuma'}
|
||||
<UptimeKuma isAbsolute />
|
||||
{:else if service.type === 'ghost'}
|
||||
<Ghost isAbsolute />
|
||||
{:else if service.type === 'meilisearch'}
|
||||
<MeiliSearch isAbsolute />
|
||||
{/if}
|
||||
<div class="font-bold text-xl text-center truncate">
|
||||
{service.name}
|
||||
</div>
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-center truncate">Team {service.teams[0].name}</div>
|
||||
{/if}
|
||||
{#if !service.type || !service.fqdn}
|
||||
<div class="font-bold text-center truncate text-red-500 group-hover:text-white">
|
||||
Configuration missing
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-center truncate">{service.type}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -5,9 +5,9 @@ import type { RequestHandler } from '@sveltejs/kit';
|
||||
import { promises as dns } from 'dns';
|
||||
|
||||
export const get: RequestHandler = async (event) => {
|
||||
const { status, body } = await getUserDetails(event);
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
if (teamId !== '0') return { status: 401, body: { message: 'You are not an admin.' } };
|
||||
try {
|
||||
const settings = await listSettings();
|
||||
return {
|
||||
|
@ -11,7 +11,12 @@
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (res.status === 401) {
|
||||
return {
|
||||
status: 302,
|
||||
redirect: '/databases'
|
||||
};
|
||||
}
|
||||
return {
|
||||
status: res.status,
|
||||
error: new Error(`Could not load ${url}`)
|
||||
|
@ -22,6 +22,16 @@
|
||||
<script lang="ts">
|
||||
export let sources;
|
||||
import { session } from '$app/stores';
|
||||
const ownSources = sources.filter((source) => {
|
||||
if (source.teams[0].id === $session.teamId) {
|
||||
return source;
|
||||
}
|
||||
});
|
||||
const otherSources = sources.filter((source) => {
|
||||
if (source.teams[0].id !== $session.teamId) {
|
||||
return source;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@ -50,8 +60,39 @@
|
||||
<div class="text-center text-xl font-bold">No git sources found</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-wrap justify-center">
|
||||
{#each sources as source}
|
||||
<div class="flex flex-col">
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 -ml-10">Your Team's Applications</div>
|
||||
{/if}
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{#each ownSources as source}
|
||||
<a href="/sources/{source.id}" class="no-underline p-2 w-96">
|
||||
<div
|
||||
class="box-selection hover:bg-orange-600 group"
|
||||
class:border-red-500={source.gitlabApp && !source.gitlabAppId}
|
||||
class:border-0={source.gitlabApp && !source.gitlabAppId}
|
||||
class:border-l-4={source.gitlabApp && !source.gitlabAppId}
|
||||
>
|
||||
<div class="font-bold text-xl text-center truncate">{source.name}</div>
|
||||
{#if $session.teamId === '0'}
|
||||
<div class="text-center truncate">Team {source.teams[0].name}</div>
|
||||
{/if}
|
||||
{#if (source.type === 'gitlab' && !source.gitlabAppId) || (source.type === 'github' && !source.githubAppId && !source.githubApp?.installationId)}
|
||||
<div class="font-bold text-center truncate text-red-500 group-hover:text-white">
|
||||
Configuration missing
|
||||
</div>
|
||||
{:else}
|
||||
<div class="truncate text-center">{source.htmlUrl}</div>
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if otherSources.length > 0 && $session.teamId === '0'}
|
||||
<div class="text-xl font-bold pb-5 pt-10 -ml-10">Other Team's Applications</div>
|
||||
<div class="flex">
|
||||
{#each otherSources as source}
|
||||
<a href="/sources/{source.id}" class="no-underline p-2 w-96">
|
||||
<div
|
||||
class="box-selection hover:bg-orange-600 group"
|
||||
@ -75,4 +116,6 @@
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ export const get: RequestHandler = async (event) => {
|
||||
|
||||
try {
|
||||
const teams = await db.prisma.permission.findMany({
|
||||
where: { userId: teamId === '0' ? undefined : teamId },
|
||||
where: { userId: teamId === '0' ? undefined : userId },
|
||||
include: { team: { include: { _count: { select: { users: true } } } } }
|
||||
});
|
||||
|
||||
|
@ -43,6 +43,16 @@
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
const ownTeams = teams.filter((team) => {
|
||||
if (team.team.id === $session.teamId) {
|
||||
return team;
|
||||
}
|
||||
});
|
||||
const otherTeams = teams.filter((team) => {
|
||||
if (team.team.id !== $session.teamId) {
|
||||
return team;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
@ -92,7 +102,10 @@
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex flex-wrap justify-center">
|
||||
{#each teams as team}
|
||||
<div class="flex flex-col">
|
||||
<div class="-ml-10 pb-5 text-xl font-bold">Current Team</div>
|
||||
<div class="flex flex-col md:flex-row">
|
||||
{#each ownTeams as team}
|
||||
<a href="/teams/{team.teamId}" class="w-96 p-2 no-underline">
|
||||
<div
|
||||
class="box-selection relative"
|
||||
@ -101,11 +114,33 @@
|
||||
>
|
||||
<div class="truncate text-center text-xl font-bold">
|
||||
{team.team.name}
|
||||
{team.team?.id === '0' ? '(root)' : ''}
|
||||
{team.team?.id === '0' ? '(admin team)' : ''}
|
||||
</div>
|
||||
|
||||
<div class="mt-1 text-center">{team.team._count.users} member(s)</div>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="-ml-10 pb-5 pt-10 text-xl font-bold">Other Teams</div>
|
||||
<div class="flex">
|
||||
{#each otherTeams as team}
|
||||
<a href="/teams/{team.teamId}" class="w-96 p-2 no-underline">
|
||||
<div
|
||||
class="box-selection relative"
|
||||
class:hover:bg-cyan-600={team.team?.id !== '0'}
|
||||
class:hover:bg-red-500={team.team?.id === '0'}
|
||||
>
|
||||
<div class="truncate text-center text-xl font-bold">
|
||||
{team.team.name}
|
||||
{team.team?.id === '0' ? '(admin team)' : ''}
|
||||
</div>
|
||||
|
||||
<div class="mt-1 text-center">{team.team._count.users} member(s)</div>
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user