Skip to content

Commit e8c2bda

Browse files
committed
Rework admin page, add users
1 parent 1a91635 commit e8c2bda

File tree

11 files changed

+216
-30
lines changed

11 files changed

+216
-30
lines changed

src/lib/Pagination.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
{#if !pageInfo || pageInfo.totalCount == PendingValue}
2424
<!-- nothing -->
25-
{:else if pageInfo.totalCount <= limit}
25+
{:else if pageInfo.totalCount <= limit && offset == 0}
2626
<!-- nothing -->
2727
{:else}
2828
<Pagination

src/routes/admin/+layout.svelte

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<script lang="ts">
2+
import { page } from '$app/stores';
3+
import Tab from '$lib/Tab.svelte';
4+
import Tabs from '$lib/Tabs.svelte';
5+
import { replacer } from '$lib/replacer';
6+
7+
$: currentRoute = $page.route.id;
8+
const nav = [
9+
{
10+
tab: 'Users',
11+
routeId: '/admin',
12+
withSubRoutes: false
13+
},
14+
{
15+
tab: 'Reconcilers',
16+
routeId: '/admin/reconcilers',
17+
withSubRoutes: false
18+
}
19+
];
20+
21+
const isActive = (current: string | null, routeID: string, allWithPrefix = false) => {
22+
if (current === routeID) {
23+
return true;
24+
}
25+
if (current && allWithPrefix) {
26+
return current.startsWith(routeID);
27+
}
28+
return false;
29+
};
30+
</script>
31+
32+
<svelte:head><title>Admin - Console</title></svelte:head>
33+
34+
<div class="header">
35+
<h2>Admin</h2>
36+
</div>
37+
<Tabs>
38+
{#each nav as { tab, routeId, withSubRoutes }}
39+
<Tab
40+
href={replacer(routeId, {})}
41+
active={isActive(currentRoute, routeId, withSubRoutes)}
42+
title={tab}
43+
/>
44+
{/each}
45+
</Tabs>
46+
<div class="container">
47+
<slot />
48+
</div>
49+
50+
<style>
51+
.container {
52+
margin: auto;
53+
min-width: 1000px;
54+
max-width: 1432px;
55+
}
56+
57+
.header {
58+
display: flex;
59+
justify-content: space-between;
60+
}
61+
</style>

src/routes/admin/+page.gql

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1-
query AdminReconcilers {
2-
reconcilers(limit: 100) {
1+
query AdminUsers($limit: Int, $offset: Int) {
2+
userSync {
3+
startedAt
4+
finishedAt
5+
auditLogs(limit: 15) {
6+
nodes {
7+
actor
8+
message
9+
createdAt
10+
}
11+
}
12+
}
13+
users(limit: $limit, offset: $offset) {
314
nodes {
4-
...ReconcilerFragment
15+
name
16+
email
17+
externalId
18+
isAdmin
19+
}
20+
pageInfo {
21+
totalCount
22+
hasNextPage
23+
hasPreviousPage
524
}
625
}
726
}

src/routes/admin/+page.svelte

+54-24
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<script lang="ts">
22
import { graphql } from '$houdini';
3-
import { Alert, Button, Heading } from '@nais/ds-svelte-community';
3+
import Card from '$lib/Card.svelte';
4+
import Pagination from '$lib/Pagination.svelte';
5+
import { changeParams, limitOffset } from '$lib/pagination';
6+
import { Button, Table, Tbody, Td, Th, Thead, Tr } from '@nais/ds-svelte-community';
47
import type { PageData } from './$houdini';
5-
import Reconciler from './Reconciler.svelte';
68
79
export let data: PageData;
810
9-
$: ({ AdminReconcilers } = data);
10-
$: reconcilers = $AdminReconcilers.data?.reconcilers.nodes;
11+
$: ({ AdminUsers } = data);
12+
$: ({ limit, offset } = limitOffset($AdminUsers.variables));
1113
1214
const synchronize = graphql(`
13-
mutation Synchronize {
14-
synchronizeAllTeams {
15-
correlationID
16-
}
15+
mutation SynchronizeUsers {
16+
synchronizeUsers
1717
}
1818
`);
1919
@@ -24,37 +24,67 @@
2424
loading = true;
2525
const resp = await synchronize.mutate(null);
2626
loading = false;
27-
2827
if (resp.errors) {
2928
errors = resp.errors.filter((e) => e.message != 'unable to resolve').map((e) => e.message);
3029
}
3130
};
3231
</script>
3332

34-
<Heading size="large">
35-
<div class="h">
36-
Admin
37-
<Button disabled={loading} {loading} on:click={triggerSynchronize} size="small">
38-
Synchronize all teams
39-
</Button>
40-
</div>
41-
</Heading>
33+
<div class="h">
34+
<Button disabled={loading} {loading} on:click={triggerSynchronize} size="small">
35+
Synchronize users
36+
</Button>
37+
</div>
38+
4239
<br />
4340

4441
{#each errors as e}
45-
<Alert variant="error">{e}</Alert>
42+
<p>{e}</p>
4643
{/each}
4744

48-
{#each reconcilers || [] as r}
49-
<Reconciler reconciler={r} />
50-
{:else}
51-
<p>No reconcilers registered</p>
52-
{/each}
45+
<Card>
46+
{#if $AdminUsers.data}
47+
<Table zebraStripes>
48+
<Thead>
49+
<Tr>
50+
<Th>Name</Th>
51+
<Th>Email</Th>
52+
<Th>External ID</Th>
53+
<Th>Nais admin</Th>
54+
</Tr>
55+
</Thead>
56+
<Tbody>
57+
{#each $AdminUsers.data.users.nodes || [] as user}
58+
<Tr>
59+
<Td>{user.name}</Td>
60+
<Td>{user.email}</Td>
61+
<Td>{user.externalId}</Td>
62+
<Td>{user.isAdmin ? 'Yes' : ''}</Td>
63+
</Tr>
64+
{:else}
65+
<Tr>
66+
<Td colspan={99}>No users found</Td>
67+
</Tr>
68+
{/each}
69+
</Tbody>
70+
</Table>
71+
72+
<Pagination
73+
style="margin-top: 1rem;"
74+
pageInfo={$AdminUsers.data.users.pageInfo}
75+
{limit}
76+
{offset}
77+
changePage={(page) => {
78+
changeParams({ page: page.toString() });
79+
}}
80+
/>
81+
{/if}
82+
</Card>
5383

5484
<style>
5585
.h {
5686
display: flex;
57-
justify-content: space-between;
87+
justify-content: flex-end;
5888
align-items: center;
5989
}
6090
</style>

src/routes/admin/+page.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { error } from '@sveltejs/kit';
2+
import type { AdminUsersVariables } from './$houdini';
3+
export const _AdminUsersVariables: AdminUsersVariables = ({ url }) => {
4+
const page = parseInt(url.searchParams.get('page') || '1');
5+
if (!page || page < 1) {
6+
throw error(400, 'Bad pagenumber');
7+
}
8+
const limit = 50;
9+
const offset = (page - 1) * limit;
10+
11+
return { limit, offset };
12+
};
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
query AdminReconcilers {
2+
reconcilers(limit: 100) {
3+
nodes {
4+
...ReconcilerFragment
5+
}
6+
}
7+
}
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<script lang="ts">
2+
import { graphql } from '$houdini';
3+
import { Alert, Button } from '@nais/ds-svelte-community';
4+
import type { PageData } from './$houdini';
5+
import Reconciler from './Reconciler.svelte';
6+
7+
export let data: PageData;
8+
9+
$: ({ AdminReconcilers } = data);
10+
$: reconcilers = $AdminReconcilers.data?.reconcilers.nodes;
11+
12+
const synchronize = graphql(`
13+
mutation Synchronize {
14+
synchronizeAllTeams {
15+
correlationID
16+
}
17+
}
18+
`);
19+
20+
let errors: string[] = [];
21+
22+
let loading = false;
23+
const triggerSynchronize = async () => {
24+
loading = true;
25+
const resp = await synchronize.mutate(null);
26+
loading = false;
27+
28+
if (resp.errors) {
29+
errors = resp.errors.filter((e) => e.message != 'unable to resolve').map((e) => e.message);
30+
}
31+
};
32+
</script>
33+
34+
<div class="h">
35+
<Button disabled={loading} {loading} on:click={triggerSynchronize} size="small">
36+
Synchronize all teams
37+
</Button>
38+
</div>
39+
<br />
40+
41+
{#each errors as e}
42+
<Alert variant="error">{e}</Alert>
43+
{/each}
44+
45+
{#each reconcilers || [] as r}
46+
<Reconciler reconciler={r} />
47+
{:else}
48+
<p>No reconcilers registered</p>
49+
{/each}
50+
51+
<style>
52+
.h {
53+
display: flex;
54+
justify-content: flex-end;
55+
align-items: center;
56+
}
57+
</style>

src/routes/team/[team]/(teamTabs)/settings/+page.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { browser } from '$app/environment';
33
import { page } from '$app/stores';
44
import { PendingValue, graphql } from '$houdini';
5+
import LogLine from '$lib/AuditLogLine.svelte';
56
import Card from '$lib/Card.svelte';
67
import GraphErrors from '$lib/GraphErrors.svelte';
78
import Time from '$lib/Time.svelte';
@@ -15,7 +16,6 @@
1516
import { slide } from 'svelte/transition';
1617
import type { PageData } from './$houdini';
1718
import EditText from './EditText.svelte';
18-
import LogLine from './LogLine.svelte';
1919
2020
export let data: PageData;
2121

src/routes/team/[team]/(teamTabs)/settings/audit_logs/+page.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<script lang="ts">
22
import { PendingValue } from '$houdini';
3+
import LogLine from '$lib/AuditLogLine.svelte';
34
import Card from '$lib/Card.svelte';
45
import Pagination from '$lib/Pagination.svelte';
56
import { changeParams, limitOffset } from '$lib/pagination';
67
import { Skeleton } from '@nais/ds-svelte-community';
7-
import LogLine from '../LogLine.svelte';
88
import type { PageData } from './$houdini';
99
1010
export let data: PageData;

0 commit comments

Comments
 (0)