@lapis-notes/bases 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +1 -1
- package/dist/bases-plugin.js +18 -21
- package/dist/bases-view/bases.svelte.d.ts +7 -0
- package/dist/bases-view/bases.svelte.js +37 -7
- package/dist/bases-view/card-view/components/card-placeholder.svelte +7 -3
- package/dist/bases-view/card-view/components/card.svelte +23 -15
- package/dist/bases-view/cell.svelte +147 -16
- package/dist/bases-view/cell.svelte.d.ts +2 -0
- package/dist/bases-view/columns.js +3 -2
- package/dist/bases-view/components/bases-embed.svelte +28 -0
- package/dist/bases-view/components/bases-embed.svelte.d.ts +12 -0
- package/dist/bases-view/components/bases-error.svelte +26 -0
- package/dist/bases-view/components/bases-error.svelte.d.ts +6 -0
- package/dist/bases-view/components/datetime.svelte +3 -0
- package/dist/bases-view/components/datetime.svelte.d.ts +1 -0
- package/dist/bases-view/components/file-preview.svelte +57 -0
- package/dist/bases-view/components/file-preview.svelte.d.ts +8 -0
- package/dist/bases-view/components/file.svelte +22 -5
- package/dist/bases-view/components/property-picker.svelte +147 -0
- package/dist/bases-view/components/property-picker.svelte.d.ts +13 -0
- package/dist/bases-view/components/sort/sort-root.svelte +107 -88
- package/dist/bases-view/components/sort/sort-root.svelte.d.ts +1 -0
- package/dist/bases-view/components/views.svelte +96 -42
- package/dist/bases-view/document-core.js +30 -0
- package/dist/bases-view/filter-parser.d.ts +1 -1
- package/dist/bases-view/filter-parser.js +2 -1
- package/dist/bases-view/index.js +15 -0
- package/dist/bases-view/kanban-view/configuration.d.ts +8 -0
- package/dist/bases-view/kanban-view/configuration.js +40 -0
- package/dist/bases-view/kanban-view/index.d.ts +55 -0
- package/dist/bases-view/kanban-view/index.js +296 -0
- package/dist/bases-view/kanban-view/kanban.svelte +284 -0
- package/dist/bases-view/kanban-view/kanban.svelte.d.ts +7 -0
- package/dist/bases-view/kanban-view/mapping.d.ts +77 -0
- package/dist/bases-view/kanban-view/mapping.js +206 -0
- package/dist/bases-view/kanban-view/markdown-detail.svelte +123 -0
- package/dist/bases-view/kanban-view/markdown-detail.svelte.d.ts +13 -0
- package/dist/bases-view/kanban-view/settings.svelte +87 -0
- package/dist/bases-view/kanban-view/settings.svelte.d.ts +7 -0
- package/dist/bases-view/list-view/list.svelte +84 -84
- package/dist/bases-view/map-view/view.svelte +6 -1
- package/dist/bases-view/metadata-invalidation-core.d.ts +1 -0
- package/dist/bases-view/metadata-invalidation-core.js +3 -2
- package/dist/bases-view/models.d.ts +26 -0
- package/dist/bases-view/unknown-view/view.svelte +13 -6
- package/dist/bases-view/view-header.svelte +20 -6
- package/dist/bases-view/view-registration-inventory.d.ts +8 -0
- package/dist/bases-view/view-registration-inventory.js +2 -0
- package/dist/bases-view/view-settings.svelte +213 -237
- package/dist/index.d.ts +1 -1
- package/dist/styles.css +495 -74
- package/manifest.json +2 -1
- package/package.json +3 -2
- package/registry.json +85 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as Alert from "@lapismd/design-core/shadcn/alert";
|
|
3
|
+
import CircleAlert from "@lucide/svelte/icons/circle-alert";
|
|
4
|
+
|
|
5
|
+
let { message }: { message: string } = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<div class="bases-view-error-container">
|
|
9
|
+
<Alert.Root variant="destructive" class="bases-view-error">
|
|
10
|
+
<CircleAlert aria-hidden="true" />
|
|
11
|
+
<Alert.Title>Unable to render base</Alert.Title>
|
|
12
|
+
<Alert.Description>
|
|
13
|
+
<p class="bases-view-error__message">{message}</p>
|
|
14
|
+
</Alert.Description>
|
|
15
|
+
</Alert.Root>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
.bases-view-error-container {
|
|
20
|
+
margin: 1rem;
|
|
21
|
+
}
|
|
22
|
+
.bases-view-error__message {
|
|
23
|
+
white-space: pre-wrap;
|
|
24
|
+
overflow-wrap: anywhere;
|
|
25
|
+
}
|
|
26
|
+
</style>
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
6
|
value,
|
|
7
|
+
label,
|
|
7
8
|
}: {
|
|
8
9
|
value: number | DateTime | string;
|
|
10
|
+
label: string;
|
|
9
11
|
} = $props();
|
|
10
12
|
|
|
11
13
|
let date = $derived.by(() => {
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
|
|
27
29
|
<div class="bases-table-cell bases-rendered-value">
|
|
28
30
|
<input
|
|
31
|
+
aria-label={label}
|
|
29
32
|
class="metadata-input metadata-input-text mod-datetime !static !ps-0"
|
|
30
33
|
value={date}
|
|
31
34
|
step="any"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { untrack } from "svelte";
|
|
3
|
+
import type { App, TFile } from "@lapis-notes/api";
|
|
4
|
+
import { ScrollArea } from "@lapismd/design-core/shadcn/scroll-area";
|
|
5
|
+
|
|
6
|
+
let { app, file }: { app: App; file: TFile } = $props();
|
|
7
|
+
let container = $state<HTMLDivElement>();
|
|
8
|
+
let error = $state("");
|
|
9
|
+
|
|
10
|
+
$effect(() => {
|
|
11
|
+
if (!container) return;
|
|
12
|
+
const owner = app;
|
|
13
|
+
const source = file;
|
|
14
|
+
const host = container;
|
|
15
|
+
error = "";
|
|
16
|
+
let cancelled = false;
|
|
17
|
+
// Defer invocation so synchronous and asynchronous provider errors share
|
|
18
|
+
// the same fallback and late mounts still get disposed after dismissal.
|
|
19
|
+
const mounted = Promise.resolve().then(() =>
|
|
20
|
+
untrack(() =>
|
|
21
|
+
owner.markdownFileSurfaces.mount({
|
|
22
|
+
containerEl: host,
|
|
23
|
+
file: source,
|
|
24
|
+
editable: false,
|
|
25
|
+
surface: {
|
|
26
|
+
id: "bases-file-link-preview",
|
|
27
|
+
context: { path: source.path },
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
void mounted.catch((reason) => {
|
|
33
|
+
if (!cancelled)
|
|
34
|
+
error = reason instanceof Error ? reason.message : String(reason);
|
|
35
|
+
});
|
|
36
|
+
return () => {
|
|
37
|
+
cancelled = true;
|
|
38
|
+
void mounted
|
|
39
|
+
.then(
|
|
40
|
+
(surface) => surface.dispose(),
|
|
41
|
+
() => undefined,
|
|
42
|
+
)
|
|
43
|
+
.catch(console.error);
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<section
|
|
49
|
+
aria-label={`Preview of ${file.name}`}
|
|
50
|
+
data-ui-component="bases-file-preview"
|
|
51
|
+
>
|
|
52
|
+
<div class="bases-file-preview__title">{file.name}</div>
|
|
53
|
+
<ScrollArea class="bases-file-preview__scroll" orientation="vertical">
|
|
54
|
+
{#if error}<p role="status">Preview unavailable: {error}</p>{/if}
|
|
55
|
+
<div bind:this={container} class="bases-file-preview__surface"></div>
|
|
56
|
+
</ScrollArea>
|
|
57
|
+
</section>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { App, TFile } from "@lapis-notes/api";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
app: App;
|
|
4
|
+
file: TFile;
|
|
5
|
+
};
|
|
6
|
+
declare const FilePreview: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type FilePreview = ReturnType<typeof FilePreview>;
|
|
8
|
+
export default FilePreview;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { App, TFile } from "@lapis-notes/api";
|
|
3
|
+
import * as HoverCard from "@lapismd/design-core/shadcn/hover-card";
|
|
4
|
+
import FilePreview from "./file-preview.svelte";
|
|
3
5
|
let {
|
|
4
6
|
app,
|
|
5
7
|
file,
|
|
@@ -7,8 +9,14 @@
|
|
|
7
9
|
app: App;
|
|
8
10
|
file: TFile;
|
|
9
11
|
} = $props();
|
|
12
|
+
let open = $state(false);
|
|
13
|
+
const previewable = $derived(
|
|
14
|
+
["md", "markdown"].includes(file.extension.toLowerCase()) &&
|
|
15
|
+
app.markdownFileSurfaces.available,
|
|
16
|
+
);
|
|
10
17
|
|
|
11
18
|
function openFile(evt: MouseEvent) {
|
|
19
|
+
open = false;
|
|
12
20
|
if (evt.metaKey || evt.ctrlKey) {
|
|
13
21
|
const leaf = app.workspace.getLeaf("tab");
|
|
14
22
|
leaf.openFile(file).then(() => {
|
|
@@ -24,8 +32,17 @@
|
|
|
24
32
|
}
|
|
25
33
|
</script>
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
>
|
|
35
|
+
{#if previewable}
|
|
36
|
+
<HoverCard.Root bind:open openDelay={350} closeDelay={150}>
|
|
37
|
+
<HoverCard.Trigger href="#/" onclick={openFile}>
|
|
38
|
+
{#snippet child({ props })}
|
|
39
|
+
<a {...props} role="link" class="bases-file-link">{file.name}</a>
|
|
40
|
+
{/snippet}
|
|
41
|
+
</HoverCard.Trigger>
|
|
42
|
+
<HoverCard.Content class="bases-file-preview" align="start">
|
|
43
|
+
<FilePreview {app} {file} />
|
|
44
|
+
</HoverCard.Content>
|
|
45
|
+
</HoverCard.Root>
|
|
46
|
+
{:else}
|
|
47
|
+
<a href="#/" class="bases-file-link" onclick={openFile}>{file.name}</a>
|
|
48
|
+
{/if}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { tick } from "svelte";
|
|
3
|
+
import { Icon } from "@lapis-notes/api/icon";
|
|
4
|
+
import type { BasesPropertyId } from "@lapis-notes/api";
|
|
5
|
+
import { Button } from "@lapismd/design-core/shadcn/button";
|
|
6
|
+
import * as Popover from "@lapismd/design-core/shadcn/popover";
|
|
7
|
+
import * as Command from "@lapismd/design-core/shadcn/command";
|
|
8
|
+
import ArrowUpDown from "@lucide/svelte/icons/chevrons-up-down";
|
|
9
|
+
import X from "@lucide/svelte/icons/x";
|
|
10
|
+
import Check from "@lucide/svelte/icons/check";
|
|
11
|
+
import type { ColumnDefinition } from "../columns";
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
id,
|
|
15
|
+
label,
|
|
16
|
+
columns,
|
|
17
|
+
value,
|
|
18
|
+
placeholder = "Property",
|
|
19
|
+
onChange,
|
|
20
|
+
}: {
|
|
21
|
+
id?: string;
|
|
22
|
+
label: string;
|
|
23
|
+
columns: ColumnDefinition[];
|
|
24
|
+
value?: BasesPropertyId | null;
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
onChange: (value: BasesPropertyId | "") => void;
|
|
27
|
+
} = $props();
|
|
28
|
+
let open = $state(false);
|
|
29
|
+
let trigger = $state<HTMLButtonElement>(null!);
|
|
30
|
+
const selected = $derived(columns.find((column) => column.id === value));
|
|
31
|
+
const listId = $props.id();
|
|
32
|
+
async function choose(next: BasesPropertyId | "") {
|
|
33
|
+
onChange(next);
|
|
34
|
+
open = false;
|
|
35
|
+
await tick();
|
|
36
|
+
trigger?.focus();
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<div class="bases-property-setting">
|
|
41
|
+
<Popover.Root bind:open>
|
|
42
|
+
<Popover.Trigger>
|
|
43
|
+
{#snippet child({ props })}
|
|
44
|
+
<Button
|
|
45
|
+
{...props}
|
|
46
|
+
bind:ref={trigger}
|
|
47
|
+
{id}
|
|
48
|
+
variant="outline"
|
|
49
|
+
role="combobox"
|
|
50
|
+
aria-label={label}
|
|
51
|
+
aria-expanded={open}
|
|
52
|
+
class="bases-property-setting__trigger"
|
|
53
|
+
>
|
|
54
|
+
<Icon name={selected?.icon ?? "lucide-file"} />
|
|
55
|
+
<span>{selected?.displayName ?? placeholder}</span>
|
|
56
|
+
<ArrowUpDown />
|
|
57
|
+
</Button>
|
|
58
|
+
{/snippet}
|
|
59
|
+
</Popover.Trigger>
|
|
60
|
+
<Popover.Content
|
|
61
|
+
class="bases-style-w-310px-8357f2 bases-style-p-0-8a539c"
|
|
62
|
+
align="start"
|
|
63
|
+
>
|
|
64
|
+
<Command.Root label="Find property">
|
|
65
|
+
<Command.Input
|
|
66
|
+
aria-label="Find property"
|
|
67
|
+
aria-controls={listId}
|
|
68
|
+
placeholder="Find property"
|
|
69
|
+
/>
|
|
70
|
+
<Command.List id={listId}>
|
|
71
|
+
<Command.Empty>No properties found.</Command.Empty>
|
|
72
|
+
<Command.Group>
|
|
73
|
+
{#each columns as column (column.id)}
|
|
74
|
+
<Command.Item
|
|
75
|
+
class="bases-property-setting-option"
|
|
76
|
+
value={`${column.displayName} ${column.id}`}
|
|
77
|
+
onSelect={() => choose(column.id)}
|
|
78
|
+
>
|
|
79
|
+
<span
|
|
80
|
+
class="bases-property-setting__check"
|
|
81
|
+
class:is-selected={value === column.id}><Check /></span
|
|
82
|
+
>
|
|
83
|
+
<Icon name={column.icon ?? "lucide-info"} />
|
|
84
|
+
<span>{column.displayName}</span>
|
|
85
|
+
<span class="bases-property-setting__id">{column.id}</span>
|
|
86
|
+
</Command.Item>
|
|
87
|
+
{/each}
|
|
88
|
+
</Command.Group>
|
|
89
|
+
</Command.List>
|
|
90
|
+
</Command.Root>
|
|
91
|
+
</Popover.Content>
|
|
92
|
+
</Popover.Root>
|
|
93
|
+
{#if value}
|
|
94
|
+
<Button
|
|
95
|
+
variant="ghost"
|
|
96
|
+
size="icon-xs"
|
|
97
|
+
class="bases-property-setting__clear"
|
|
98
|
+
aria-label={`Clear ${label.toLowerCase()}`}
|
|
99
|
+
onclick={() => choose("")}><X /></Button
|
|
100
|
+
>
|
|
101
|
+
{/if}
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<style>
|
|
105
|
+
.bases-property-setting {
|
|
106
|
+
position: relative;
|
|
107
|
+
min-width: 0;
|
|
108
|
+
width: 100%;
|
|
109
|
+
}
|
|
110
|
+
.bases-property-setting :global(.bases-property-setting__trigger) {
|
|
111
|
+
width: 100%;
|
|
112
|
+
justify-content: space-between;
|
|
113
|
+
padding-inline-end: 0.75rem;
|
|
114
|
+
}
|
|
115
|
+
.bases-property-setting :global(.bases-property-setting__trigger > span) {
|
|
116
|
+
min-width: 0;
|
|
117
|
+
flex: 1;
|
|
118
|
+
text-align: left;
|
|
119
|
+
overflow: hidden;
|
|
120
|
+
text-overflow: ellipsis;
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
padding-inline-end: 1.5rem;
|
|
123
|
+
}
|
|
124
|
+
.bases-property-setting :global(.bases-property-setting__clear) {
|
|
125
|
+
position: absolute;
|
|
126
|
+
inset-inline-end: 1.65rem;
|
|
127
|
+
top: 50%;
|
|
128
|
+
transform: translateY(-50%);
|
|
129
|
+
}
|
|
130
|
+
.bases-property-setting__check {
|
|
131
|
+
visibility: hidden;
|
|
132
|
+
}
|
|
133
|
+
.bases-property-setting__check.is-selected {
|
|
134
|
+
visibility: visible;
|
|
135
|
+
}
|
|
136
|
+
.bases-property-setting__id {
|
|
137
|
+
margin-inline-start: auto;
|
|
138
|
+
color: var(--ui-workspace-muted-foreground);
|
|
139
|
+
font-size: 0.75rem;
|
|
140
|
+
}
|
|
141
|
+
/* The leading check reflects the saved mapping, independently of search focus. */
|
|
142
|
+
:global(
|
|
143
|
+
.bases-property-setting-option > [data-ui-part="command-check-icon"]
|
|
144
|
+
) {
|
|
145
|
+
display: none;
|
|
146
|
+
}
|
|
147
|
+
</style>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BasesPropertyId } from "@lapis-notes/api";
|
|
2
|
+
import type { ColumnDefinition } from "../columns";
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
id?: string;
|
|
5
|
+
label: string;
|
|
6
|
+
columns: ColumnDefinition[];
|
|
7
|
+
value?: BasesPropertyId | null;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
onChange: (value: BasesPropertyId | "") => void;
|
|
10
|
+
};
|
|
11
|
+
declare const PropertyPicker: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
12
|
+
type PropertyPicker = ReturnType<typeof PropertyPicker>;
|
|
13
|
+
export default PropertyPicker;
|
|
@@ -21,12 +21,14 @@
|
|
|
21
21
|
import { getSortDirectionLabels } from "./sort-direction-labels";
|
|
22
22
|
|
|
23
23
|
let {
|
|
24
|
+
showGrouping = true,
|
|
24
25
|
class: className,
|
|
25
26
|
orderBy = $bindable(),
|
|
26
27
|
table,
|
|
27
28
|
controller = table as QueryController,
|
|
28
29
|
}: {
|
|
29
30
|
orderBy: Array<SortColumn>;
|
|
31
|
+
showGrouping?: boolean;
|
|
30
32
|
class?: string;
|
|
31
33
|
controller?: QueryController;
|
|
32
34
|
table?: any;
|
|
@@ -106,7 +108,10 @@
|
|
|
106
108
|
{...props}
|
|
107
109
|
variant="outline"
|
|
108
110
|
size="sm"
|
|
109
|
-
class={cn(
|
|
111
|
+
class={cn(
|
|
112
|
+
"bases-style-h-8-ed8a5d bases-style-border-dashed-a29b7a",
|
|
113
|
+
className,
|
|
114
|
+
)}
|
|
110
115
|
>
|
|
111
116
|
<SortIcon /> Sort
|
|
112
117
|
</Button>
|
|
@@ -117,99 +122,113 @@
|
|
|
117
122
|
data-bases-popover="sort"
|
|
118
123
|
align="start"
|
|
119
124
|
>
|
|
120
|
-
|
|
125
|
+
{#if showGrouping}
|
|
121
126
|
<div
|
|
122
|
-
class="bases-style-
|
|
127
|
+
class="bases-style-mb-2-a77ed4 bases-style-grid-f3c543 bases-style-gap-2-77a2a2"
|
|
123
128
|
>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<div class="bases-style-flex-60fbb7 bases-style-h-9-e7a768 bases-style-items-center-3960ff bases-style-rounded-md-421ac2 bases-style-border-2-65935d">
|
|
127
|
-
<Popover.Root>
|
|
128
|
-
<Popover.Trigger>
|
|
129
|
-
{#snippet child({ props }: { props: Record<string, any> })}
|
|
130
|
-
<Button
|
|
131
|
-
{...props}
|
|
132
|
-
variant="outline"
|
|
133
|
-
size="sm"
|
|
134
|
-
class="bases-style-h-8-ed8a5d grow bases-style-rounded-none-0c5e91 bases-style-rounded-l-md-9b2e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
|
|
135
|
-
>
|
|
136
|
-
{#if selectedGroupColumn}
|
|
137
|
-
<Icon name={[selectedGroupColumn.icon ?? "lucide-file"]} />
|
|
138
|
-
{selectedGroupColumn.displayName}
|
|
139
|
-
{:else}
|
|
140
|
-
<span class="bases-style-opacity-50-0b8c50">Property</span>
|
|
141
|
-
{/if}
|
|
142
|
-
<SortIcon />
|
|
143
|
-
</Button>
|
|
144
|
-
{/snippet}
|
|
145
|
-
</Popover.Trigger>
|
|
146
|
-
<Popover.Content class="bases-style-w-max-2f935d bases-style-p-0-8a539c" align="start">
|
|
147
|
-
<Command.Root>
|
|
148
|
-
<Command.Input aria-controls={commandListId} placeholder="Group by property" />
|
|
149
|
-
<Command.List id={commandListId} class="bases-style-p-1-eb6a3c">
|
|
150
|
-
<Command.Empty>No results found.</Command.Empty>
|
|
151
|
-
{#each controller.getAllColumns() as column (column.id)}
|
|
152
|
-
<Command.Item onSelect={() => setGroupBy(column.id)}>
|
|
153
|
-
<div
|
|
154
|
-
data-ui-part="bases-option-indicator"
|
|
155
|
-
data-selected={groupBy?.property === column.id}
|
|
156
|
-
class={cn(
|
|
157
|
-
"bases-style-mr-2-d2347e bases-style-flex-60fbb7 bases-style-size-4-f7b5fa bases-style-items-center-3960ff bases-style-justify-center-86843c bases-style-rounded-sm-36d446 border bases-style-border-var-interactive-accent-f46c93",
|
|
158
|
-
groupBy?.property === column.id
|
|
159
|
-
? "bases-style-ring-ring-3e1868 bases-style-border-none-4a5f0e bases-style-bg-var-interactive-accent-c58cc0 bases-style-text-var-text-on-accent-22b2b1 hover:ring"
|
|
160
|
-
: "bases-style-opacity-50-0b8c50 [&_svg]:invisible",
|
|
161
|
-
)}
|
|
162
|
-
>
|
|
163
|
-
<CheckIcon class="bases-style-size-4-f7b5fa" />
|
|
164
|
-
</div>
|
|
165
|
-
<Icon name={[column.icon ?? "lucide-info"]} />
|
|
166
|
-
<span class="bases-style-overflow-hidden-2cd02d bases-style-text-ellipsis-6e2e11"
|
|
167
|
-
>{column.displayName}</span
|
|
168
|
-
>
|
|
169
|
-
{#if !column.id.startsWith("note.")}
|
|
170
|
-
<Command.Shortcut class="bases-style-font-mono-0e6570 bases-style-text-0-75em-c425cc"
|
|
171
|
-
>{column.id}</Command.Shortcut
|
|
172
|
-
>
|
|
173
|
-
{/if}
|
|
174
|
-
</Command.Item>
|
|
175
|
-
{/each}
|
|
176
|
-
</Command.List>
|
|
177
|
-
</Command.Root>
|
|
178
|
-
</Popover.Content>
|
|
179
|
-
</Popover.Root>
|
|
180
|
-
<Select.Root
|
|
181
|
-
type="single"
|
|
182
|
-
bind:value={getGroupDirection, setGroupDirection}
|
|
129
|
+
<div
|
|
130
|
+
class="bases-style-text-muted-foreground-bfa603 bases-style-px-1-d8e0e3 bases-style-text-xs-359090 bases-style-font-semibold-e83a70 bases-style-tracking-0-18em-a82f6f uppercase"
|
|
183
131
|
>
|
|
184
|
-
|
|
185
|
-
|
|
132
|
+
Group by
|
|
133
|
+
</div>
|
|
134
|
+
<div
|
|
135
|
+
class="bases-style-flex-60fbb7 bases-style-h-9-e7a768 bases-style-items-center-3960ff bases-style-rounded-md-421ac2 bases-style-border-2-65935d"
|
|
136
|
+
>
|
|
137
|
+
<Popover.Root>
|
|
138
|
+
<Popover.Trigger>
|
|
139
|
+
{#snippet child({ props }: { props: Record<string, any> })}
|
|
140
|
+
<Button
|
|
141
|
+
{...props}
|
|
142
|
+
variant="outline"
|
|
143
|
+
size="sm"
|
|
144
|
+
class="bases-style-h-8-ed8a5d grow bases-style-rounded-none-0c5e91 bases-style-rounded-l-md-9b2e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
|
|
145
|
+
>
|
|
146
|
+
{#if selectedGroupColumn}
|
|
147
|
+
<Icon name={[selectedGroupColumn.icon ?? "lucide-file"]} />
|
|
148
|
+
{selectedGroupColumn.displayName}
|
|
149
|
+
{:else}
|
|
150
|
+
<span class="bases-style-opacity-50-0b8c50">Property</span>
|
|
151
|
+
{/if}
|
|
152
|
+
<SortIcon />
|
|
153
|
+
</Button>
|
|
154
|
+
{/snippet}
|
|
155
|
+
</Popover.Trigger>
|
|
156
|
+
<Popover.Content
|
|
157
|
+
class="bases-style-w-max-2f935d bases-style-p-0-8a539c"
|
|
158
|
+
align="start"
|
|
159
|
+
>
|
|
160
|
+
<Command.Root>
|
|
161
|
+
<Command.Input
|
|
162
|
+
aria-controls={commandListId}
|
|
163
|
+
placeholder="Group by property"
|
|
164
|
+
/>
|
|
165
|
+
<Command.List id={commandListId} class="bases-style-p-1-eb6a3c">
|
|
166
|
+
<Command.Empty>No results found.</Command.Empty>
|
|
167
|
+
{#each controller.getAllColumns() as column (column.id)}
|
|
168
|
+
<Command.Item onSelect={() => setGroupBy(column.id)}>
|
|
169
|
+
<div
|
|
170
|
+
data-ui-part="bases-option-indicator"
|
|
171
|
+
data-selected={groupBy?.property === column.id}
|
|
172
|
+
class={cn(
|
|
173
|
+
"bases-style-mr-2-d2347e bases-style-flex-60fbb7 bases-style-size-4-f7b5fa bases-style-items-center-3960ff bases-style-justify-center-86843c bases-style-rounded-sm-36d446 border bases-style-border-var-interactive-accent-f46c93",
|
|
174
|
+
groupBy?.property === column.id
|
|
175
|
+
? "bases-style-ring-ring-3e1868 bases-style-border-none-4a5f0e bases-style-bg-var-interactive-accent-c58cc0 bases-style-text-var-text-on-accent-22b2b1 hover:ring"
|
|
176
|
+
: "bases-style-opacity-50-0b8c50 [&_svg]:invisible",
|
|
177
|
+
)}
|
|
178
|
+
>
|
|
179
|
+
<CheckIcon class="bases-style-size-4-f7b5fa" />
|
|
180
|
+
</div>
|
|
181
|
+
<Icon name={[column.icon ?? "lucide-info"]} />
|
|
182
|
+
<span
|
|
183
|
+
class="bases-style-overflow-hidden-2cd02d bases-style-text-ellipsis-6e2e11"
|
|
184
|
+
>{column.displayName}</span
|
|
185
|
+
>
|
|
186
|
+
{#if !column.id.startsWith("note.")}
|
|
187
|
+
<Command.Shortcut
|
|
188
|
+
class="bases-style-font-mono-0e6570 bases-style-text-0-75em-c425cc"
|
|
189
|
+
>{column.id}</Command.Shortcut
|
|
190
|
+
>
|
|
191
|
+
{/if}
|
|
192
|
+
</Command.Item>
|
|
193
|
+
{/each}
|
|
194
|
+
</Command.List>
|
|
195
|
+
</Command.Root>
|
|
196
|
+
</Popover.Content>
|
|
197
|
+
</Popover.Root>
|
|
198
|
+
<Select.Root
|
|
199
|
+
type="single"
|
|
200
|
+
bind:value={getGroupDirection, setGroupDirection}
|
|
201
|
+
>
|
|
202
|
+
<Select.Trigger
|
|
203
|
+
aria-label="Group sort direction"
|
|
204
|
+
size="sm"
|
|
205
|
+
class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
|
|
206
|
+
>
|
|
207
|
+
{groupDirectionLabel}
|
|
208
|
+
<SortIcon />
|
|
209
|
+
</Select.Trigger>
|
|
210
|
+
<Select.Content>
|
|
211
|
+
{#each groupDirections as direction (direction.value)}
|
|
212
|
+
<Select.Item value={direction.value} label={direction.label}
|
|
213
|
+
>{direction.label}</Select.Item
|
|
214
|
+
>
|
|
215
|
+
{/each}
|
|
216
|
+
</Select.Content>
|
|
217
|
+
</Select.Root>
|
|
218
|
+
<Button
|
|
219
|
+
variant="ghost"
|
|
186
220
|
size="sm"
|
|
187
|
-
|
|
221
|
+
aria-label="Clear grouping"
|
|
222
|
+
class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-rounded-r-md-d4eb07 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
|
|
223
|
+
disabled={!selectedGroupColumn}
|
|
224
|
+
onclick={() => (controller.selectedView.groupBy = undefined)}
|
|
188
225
|
>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<Select.Content>
|
|
193
|
-
{#each groupDirections as direction (direction.value)}
|
|
194
|
-
<Select.Item value={direction.value} label={direction.label}
|
|
195
|
-
>{direction.label}</Select.Item
|
|
196
|
-
>
|
|
197
|
-
{/each}
|
|
198
|
-
</Select.Content>
|
|
199
|
-
</Select.Root>
|
|
200
|
-
<Button
|
|
201
|
-
variant="ghost"
|
|
202
|
-
size="sm"
|
|
203
|
-
aria-label="Clear grouping"
|
|
204
|
-
class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-rounded-r-md-d4eb07 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
|
|
205
|
-
disabled={!selectedGroupColumn}
|
|
206
|
-
onclick={() => (controller.selectedView.groupBy = undefined)}
|
|
207
|
-
>
|
|
208
|
-
<Trash />
|
|
209
|
-
</Button>
|
|
226
|
+
<Trash />
|
|
227
|
+
</Button>
|
|
228
|
+
</div>
|
|
210
229
|
</div>
|
|
211
|
-
|
|
212
|
-
|
|
230
|
+
<div class="bases-style-mb-2-a77ed4 bases-style-border-t-b950dd"></div>
|
|
231
|
+
{/if}
|
|
213
232
|
<div
|
|
214
233
|
class="bases-style-text-muted-foreground-bfa603 bases-style-mb-2-a77ed4 bases-style-px-1-d8e0e3 bases-style-text-xs-359090 bases-style-font-semibold-e83a70 bases-style-tracking-0-18em-a82f6f uppercase"
|
|
215
234
|
>
|