Skip to content

Commit 5344cdd

Browse files
authored
resource and tables drodown for model consolidate (#9074)
1 parent b8a48c8 commit 5344cdd

4 files changed

Lines changed: 162 additions & 59 deletions

File tree

web-admin/src/features/projects/status/resource-table/ActionsCell.svelte

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
import IconButton from "@rilldata/web-common/components/button/IconButton.svelte";
33
import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
44
import ThreeDot from "@rilldata/web-common/components/icons/ThreeDot.svelte";
5+
import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
6+
import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
57
import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
68
import type { V1Resource } from "@rilldata/web-common/runtime-client";
79
import {
810
RefreshCcwIcon,
11+
LayoutGridIcon,
912
CodeIcon,
1013
ScrollTextIcon,
1114
AlertCircleIcon,
@@ -14,8 +17,8 @@
1417
1518
export let resourceKind: string;
1619
export let resourceName: string;
17-
export let canRefresh: boolean;
1820
export let resource: V1Resource;
21+
export let isReconciling: boolean = false;
1922
export let onClickRefreshDialog: (
2023
resourceName: string,
2124
resourceKind: string,
@@ -28,15 +31,25 @@
2831
resource: V1Resource,
2932
) => void;
3033
export let onViewLogsClick: (name: string) => void = () => {};
34+
export let onViewPartitionsClick:
35+
| ((resource: V1Resource) => void)
36+
| undefined = undefined;
3137
export let isDropdownOpen: boolean;
3238
export let onDropdownOpenChange: (isOpen: boolean) => void;
3339
34-
$: actions =
35-
resourceKind === ResourceKind.Model
36-
? getAvailableModelActions(resource)
37-
: [];
40+
$: isModel = resourceKind === ResourceKind.Model;
41+
$: isSource = resourceKind === ResourceKind.Source;
42+
$: canRefresh = isModel || isSource;
43+
44+
$: actions = isModel ? getAvailableModelActions(resource) : [];
45+
$: isPartitioned = actions.includes("viewPartitions");
3846
$: isIncremental = actions.includes("incrementalRefresh");
3947
$: hasErroredPartitions = actions.includes("refreshErrored");
48+
49+
$: refreshDisabled = isReconciling;
50+
$: refreshTooltip = isReconciling
51+
? "Resource is currently being reconciled"
52+
: "";
4053
</script>
4154

4255
<DropdownMenu.Root open={isDropdownOpen} onOpenChange={onDropdownOpenChange}>
@@ -46,6 +59,7 @@
4659
</IconButton>
4760
</DropdownMenu.Trigger>
4861
<DropdownMenu.Content align="start">
62+
<!-- Describe (always available) -->
4963
<DropdownMenu.Item
5064
class="font-normal flex items-center"
5165
on:click={() => onClickViewSpec(resourceName, resourceKind, resource)}
@@ -55,6 +69,8 @@
5569
<span class="ml-2">Describe</span>
5670
</div>
5771
</DropdownMenu.Item>
72+
73+
<!-- View Logs (always available) -->
5874
<DropdownMenu.Item
5975
class="font-normal flex items-center"
6076
on:click={() => onViewLogsClick(resourceName)}
@@ -64,39 +80,77 @@
6480
<span class="ml-2">View Logs</span>
6581
</div>
6682
</DropdownMenu.Item>
67-
{#if canRefresh}
68-
{#if hasErroredPartitions}
69-
<DropdownMenu.Item
70-
class="font-normal flex items-center"
71-
on:click={() => onClickRefreshErroredPartitions(resourceName)}
72-
>
73-
<div class="flex items-center">
74-
<AlertCircleIcon size="12px" />
75-
<span class="ml-2">Refresh Errored Partitions</span>
76-
</div>
77-
</DropdownMenu.Item>
78-
{/if}
83+
84+
<!-- View Partitions (models only, if partitioned) -->
85+
{#if isPartitioned && onViewPartitionsClick}
7986
<DropdownMenu.Item
8087
class="font-normal flex items-center"
81-
on:click={() =>
82-
onClickRefreshDialog(resourceName, resourceKind, "full")}
88+
on:click={() => onViewPartitionsClick?.(resource)}
8389
>
8490
<div class="flex items-center">
85-
<RefreshCcwIcon size="12px" />
86-
<span class="ml-2">Full Refresh</span>
91+
<LayoutGridIcon size="12px" />
92+
<span class="ml-2">View Partitions</span>
8793
</div>
8894
</DropdownMenu.Item>
89-
{#if isIncremental}
95+
{/if}
96+
97+
<!-- Refresh actions (models + sources) -->
98+
{#if canRefresh}
99+
<DropdownMenu.Separator />
100+
101+
<!-- Refresh Errored Partitions (models with errors) -->
102+
{#if hasErroredPartitions}
103+
<Tooltip distance={8} suppress={!refreshDisabled}>
104+
<DropdownMenu.Item
105+
class="font-normal flex items-center"
106+
disabled={refreshDisabled}
107+
on:click={() => onClickRefreshErroredPartitions(resourceName)}
108+
>
109+
<div class="flex items-center">
110+
<AlertCircleIcon size="12px" />
111+
<span class="ml-2">Refresh Errored Partitions</span>
112+
</div>
113+
</DropdownMenu.Item>
114+
<TooltipContent slot="tooltip-content"
115+
>{refreshTooltip}</TooltipContent
116+
>
117+
</Tooltip>
118+
{/if}
119+
120+
<!-- Full Refresh -->
121+
<Tooltip distance={8} suppress={!refreshDisabled}>
90122
<DropdownMenu.Item
91123
class="font-normal flex items-center"
124+
disabled={refreshDisabled}
92125
on:click={() =>
93-
onClickRefreshDialog(resourceName, resourceKind, "incremental")}
126+
onClickRefreshDialog(resourceName, resourceKind, "full")}
94127
>
95128
<div class="flex items-center">
96129
<RefreshCcwIcon size="12px" />
97-
<span class="ml-2">Incremental Refresh</span>
130+
<span class="ml-2">Full Refresh</span>
98131
</div>
99132
</DropdownMenu.Item>
133+
<TooltipContent slot="tooltip-content">{refreshTooltip}</TooltipContent>
134+
</Tooltip>
135+
136+
<!-- Incremental Refresh (incremental models only) -->
137+
{#if isIncremental}
138+
<Tooltip distance={8} suppress={!refreshDisabled}>
139+
<DropdownMenu.Item
140+
class="font-normal flex items-center"
141+
disabled={refreshDisabled}
142+
on:click={() =>
143+
onClickRefreshDialog(resourceName, resourceKind, "incremental")}
144+
>
145+
<div class="flex items-center">
146+
<RefreshCcwIcon size="12px" />
147+
<span class="ml-2">Incremental Refresh</span>
148+
</div>
149+
</DropdownMenu.Item>
150+
<TooltipContent slot="tooltip-content"
151+
>{refreshTooltip}</TooltipContent
152+
>
153+
</Tooltip>
100154
{/if}
101155
{/if}
102156
</DropdownMenu.Content>

web-admin/src/features/projects/status/resource-table/ProjectResourcesTable.svelte

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import NameCell from "./NameCell.svelte";
1919
import RefreshCell from "./RefreshCell.svelte";
2020
import RefreshErroredPartitionsDialog from "../tables/RefreshErroredPartitionsDialog.svelte";
21+
import ModelPartitionsDialog from "../tables/ModelPartitionsDialog.svelte";
2122
import RefreshResourceConfirmDialog from "./RefreshResourceConfirmDialog.svelte";
2223
import ResourceErrorMessage from "./ResourceErrorMessage.svelte";
2324
import ResourceSpecDialog from "./ResourceSpecDialog.svelte";
@@ -37,6 +38,9 @@
3738
let isErroredPartitionsDialogOpen = false;
3839
let erroredPartitionsModelName = "";
3940
41+
let isPartitionsDialogOpen = false;
42+
let partitionsResource: V1Resource | null = null;
43+
4044
let openDropdownResourceKey = "";
4145
4246
const runtimeClient = useRuntimeClient();
@@ -78,6 +82,11 @@
7882
return openDropdownResourceKey === resourceKey;
7983
};
8084
85+
const openPartitionsDialog = (resource: V1Resource) => {
86+
partitionsResource = resource;
87+
isPartitionsDialogOpen = true;
88+
};
89+
8190
const openRefreshErroredPartitionsDialog = (resourceName: string) => {
8291
erroredPartitionsModelName = resourceName;
8392
isErroredPartitionsDialogOpen = true;
@@ -211,14 +220,12 @@
211220
resourceKind: row.original.meta.name.kind,
212221
resourceName: row.original.meta.name.name,
213222
resource: row.original,
214-
canRefresh:
215-
!isRowReconciling &&
216-
(row.original.meta.name.kind === ResourceKind.Model ||
217-
row.original.meta.name.kind === ResourceKind.Source),
223+
isReconciling: isRowReconciling,
218224
onClickRefreshDialog: openRefreshDialog,
219225
onClickRefreshErroredPartitions: openRefreshErroredPartitionsDialog,
220226
onClickViewSpec: openSpecDialog,
221227
onViewLogsClick: handleViewLogsClick,
228+
onViewPartitionsClick: openPartitionsDialog,
222229
isDropdownOpen: isDropdownOpen(resourceKey),
223230
onDropdownOpenChange: (isOpen: boolean) =>
224231
setDropdownOpen(resourceKey, isOpen),
@@ -255,6 +262,14 @@
255262
onRefresh={handleRefreshErroredPartitions}
256263
/>
257264

265+
<ModelPartitionsDialog
266+
bind:open={isPartitionsDialogOpen}
267+
resource={partitionsResource}
268+
onClose={() => {
269+
isPartitionsDialogOpen = false;
270+
}}
271+
/>
272+
258273
<ResourceSpecDialog
259274
bind:open={isSpecDialogOpen}
260275
resourceName={specResourceName}

web-admin/src/features/projects/status/tables/ModelActionsCell.svelte

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import IconButton from "@rilldata/web-common/components/button/IconButton.svelte";
33
import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu";
44
import ThreeDot from "@rilldata/web-common/components/icons/ThreeDot.svelte";
5+
import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
6+
import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
57
import {
68
RefreshCcwIcon,
79
LayoutGridIcon,
@@ -13,19 +15,25 @@
1315
import { getAvailableModelActions } from "./model-actions";
1416
1517
export let resource: V1Resource | undefined;
18+
export let isReconciling: boolean = false;
1619
export let isDropdownOpen: boolean;
1720
export let onDropdownOpenChange: (isOpen: boolean) => void;
1821
export let onModelInfoClick: (resource: V1Resource) => void;
1922
export let onViewPartitionsClick: (resource: V1Resource) => void;
2023
export let onRefreshErroredClick: (resource: V1Resource) => void;
2124
export let onIncrementalRefreshClick: (resource: V1Resource) => void;
2225
export let onFullRefreshClick: (resource: V1Resource) => void;
23-
export let onViewLogsClick: (name: string) => void;
26+
export let onViewLogsClick: ((name: string) => void) | undefined = undefined;
2427
2528
$: actions = getAvailableModelActions(resource);
2629
$: isPartitioned = actions.includes("viewPartitions");
2730
$: isIncremental = actions.includes("incrementalRefresh");
2831
$: hasErroredPartitions = actions.includes("refreshErrored");
32+
33+
$: refreshDisabled = isReconciling;
34+
$: refreshTooltip = isReconciling
35+
? "Model is currently being reconciled"
36+
: "";
2937
</script>
3038

3139
{#if resource}
@@ -36,6 +44,7 @@
3644
</IconButton>
3745
</DropdownMenu.Trigger>
3846
<DropdownMenu.Content align="start">
47+
<!-- Describe (always available) -->
3948
<DropdownMenu.Item
4049
class="font-normal flex items-center"
4150
on:click={() => onModelInfoClick(resource)}
@@ -46,62 +55,85 @@
4655
</div>
4756
</DropdownMenu.Item>
4857

49-
<DropdownMenu.Item
50-
class="font-normal flex items-center"
51-
on:click={() => onViewLogsClick(resource.meta?.name?.name ?? "")}
52-
>
53-
<div class="flex items-center">
54-
<ScrollTextIcon size="12px" />
55-
<span class="ml-2">View Logs</span>
56-
</div>
57-
</DropdownMenu.Item>
58-
59-
{#if isPartitioned}
58+
<!-- View Logs (always available, optional) -->
59+
{#if onViewLogsClick}
6060
<DropdownMenu.Item
6161
class="font-normal flex items-center"
62-
on:click={() => onViewPartitionsClick(resource)}
62+
on:click={() => onViewLogsClick?.(resource.meta?.name?.name ?? "")}
6363
>
6464
<div class="flex items-center">
65-
<LayoutGridIcon size="12px" />
66-
<span class="ml-2">View Partitions</span>
65+
<ScrollTextIcon size="12px" />
66+
<span class="ml-2">View Logs</span>
6767
</div>
6868
</DropdownMenu.Item>
6969
{/if}
7070

71-
{#if hasErroredPartitions}
71+
<!-- View Partitions (if partitioned, always available) -->
72+
{#if isPartitioned}
7273
<DropdownMenu.Item
7374
class="font-normal flex items-center"
74-
on:click={() => onRefreshErroredClick(resource)}
75+
on:click={() => onViewPartitionsClick(resource)}
7576
>
7677
<div class="flex items-center">
77-
<AlertCircleIcon size="12px" />
78-
<span class="ml-2">Refresh Errored Partitions</span>
78+
<LayoutGridIcon size="12px" />
79+
<span class="ml-2">View Partitions</span>
7980
</div>
8081
</DropdownMenu.Item>
8182
{/if}
8283

8384
<DropdownMenu.Separator />
8485

85-
<DropdownMenu.Item
86-
class="font-normal flex items-center"
87-
on:click={() => onFullRefreshClick(resource)}
88-
>
89-
<div class="flex items-center">
90-
<RefreshCcwIcon size="12px" />
91-
<span class="ml-2">Full Refresh</span>
92-
</div>
93-
</DropdownMenu.Item>
86+
<!-- Refresh Errored Partitions (disabled when reconciling) -->
87+
{#if hasErroredPartitions}
88+
<Tooltip distance={8} suppress={!refreshDisabled}>
89+
<DropdownMenu.Item
90+
class="font-normal flex items-center"
91+
disabled={refreshDisabled}
92+
on:click={() => onRefreshErroredClick(resource)}
93+
>
94+
<div class="flex items-center">
95+
<AlertCircleIcon size="12px" />
96+
<span class="ml-2">Refresh Errored Partitions</span>
97+
</div>
98+
</DropdownMenu.Item>
99+
<TooltipContent slot="tooltip-content"
100+
>{refreshTooltip}</TooltipContent
101+
>
102+
</Tooltip>
103+
{/if}
94104

95-
{#if isIncremental}
105+
<!-- Full Refresh (disabled when reconciling) -->
106+
<Tooltip distance={8} suppress={!refreshDisabled}>
96107
<DropdownMenu.Item
97108
class="font-normal flex items-center"
98-
on:click={() => onIncrementalRefreshClick(resource)}
109+
disabled={refreshDisabled}
110+
on:click={() => onFullRefreshClick(resource)}
99111
>
100112
<div class="flex items-center">
101113
<RefreshCcwIcon size="12px" />
102-
<span class="ml-2">Incremental Refresh</span>
114+
<span class="ml-2">Full Refresh</span>
103115
</div>
104116
</DropdownMenu.Item>
117+
<TooltipContent slot="tooltip-content">{refreshTooltip}</TooltipContent>
118+
</Tooltip>
119+
120+
<!-- Incremental Refresh (incremental models only, disabled when reconciling) -->
121+
{#if isIncremental}
122+
<Tooltip distance={8} suppress={!refreshDisabled}>
123+
<DropdownMenu.Item
124+
class="font-normal flex items-center"
125+
disabled={refreshDisabled}
126+
on:click={() => onIncrementalRefreshClick(resource)}
127+
>
128+
<div class="flex items-center">
129+
<RefreshCcwIcon size="12px" />
130+
<span class="ml-2">Incremental Refresh</span>
131+
</div>
132+
</DropdownMenu.Item>
133+
<TooltipContent slot="tooltip-content"
134+
>{refreshTooltip}</TooltipContent
135+
>
136+
</Tooltip>
105137
{/if}
106138
</DropdownMenu.Content>
107139
</DropdownMenu.Root>

0 commit comments

Comments
 (0)