Skip to content

Commit 2757c38

Browse files
authored
Add search function in access menu (#1065)
* Add search function to access by position * Lint
1 parent 7f8e9d4 commit 2757c38

File tree

2 files changed

+43
-14
lines changed

2 files changed

+43
-14
lines changed

src/routes/(app)/admin/access/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
/>
7474

7575
{#if $search}
76-
<button class="btn btn-sm" on:click={() => search.set("")}> Clear </button>
76+
<button class="btn btn-sm" onclick={() => search.set("")}> Clear </button>
7777
{/if}
7878
</div>
7979

src/routes/(app)/admin/access/positions/+page.svelte

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,36 @@
22
import { superForm } from "$lib/utils/client/superForms";
33
import PolicyTreeNode from "$lib/components/access/PolicyTreeNode.svelte";
44
import type { PolicyNode } from "$lib/components/access/PolicyTreeNode.svelte";
5+
import { writable, derived } from "svelte/store";
56
67
let { data } = $props();
78
9+
const search = writable("");
10+
11+
// Filtered trees, reactive to search
12+
const filteredPosTrees = derived(search, ($search) => {
13+
const q = $search.toLowerCase().trim();
14+
15+
return Array.from(data.posToAccessPolicies.entries())
16+
.sort((a, b) => (a[0] < b[0] ? -1 : 1))
17+
.map(([position, policies]) => {
18+
const positionMatches = position.toLowerCase().includes(q);
19+
20+
const visibleApiNames = positionMatches
21+
? policies.map((p) => p.apiName)
22+
: policies
23+
.filter((p) => p.apiName.toLowerCase().includes(q))
24+
.map((p) => p.apiName);
25+
26+
return {
27+
position,
28+
policies,
29+
tree: buildPolicyTreeForPolicies(visibleApiNames),
30+
};
31+
})
32+
.filter(({ tree }) => Object.keys(tree).length > 0);
33+
});
34+
835
const {
936
form: createForm,
1037
errors: createErrors,
@@ -33,20 +60,22 @@
3360
policies.forEach((p) => insertPolicy(root, p));
3461
return root.children; // return children instead of the root node
3562
}
36-
37-
const posTrees: Array<{
38-
position: string;
39-
tree: Record<string, PolicyNode>;
40-
policies: Array<{ apiName: string; id: string }>;
41-
}> = Array.from(data.posToAccessPolicies.entries())
42-
.sort((a, b) => (a[0] < b[0] ? -1 : 1))
43-
.map(([position, policies]) => ({
44-
position,
45-
tree: buildPolicyTreeForPolicies(policies.map((p) => p.apiName)),
46-
policies,
47-
}));
4863
</script>
4964

65+
<!-- Search -->
66+
<div class="mb-4 flex items-center gap-2">
67+
<input
68+
type="text"
69+
placeholder="Search policies..."
70+
class="input input-bordered w-full max-w-md"
71+
bind:value={$search}
72+
/>
73+
74+
{#if $search}
75+
<button class="btn btn-sm" onclick={() => search.set("")}> Clear </button>
76+
{/if}
77+
</div>
78+
5079
<div class="overflow-x-auto">
5180
<table class="table w-full">
5281
<thead>
@@ -62,7 +91,7 @@
6291
</thead>
6392

6493
<tbody>
65-
{#each posTrees as { position, tree, policies }}
94+
{#each $filteredPosTrees as { position, tree, policies }}
6695
<tr class="odd:bg-gray/10 even:bg-base-200/50">
6796
<td class="font-medium">{position}</td>
6897
<td>

0 commit comments

Comments
 (0)