|
2 | 2 | import IconButton from "@rilldata/web-common/components/button/IconButton.svelte"; |
3 | 3 | import * as DropdownMenu from "@rilldata/web-common/components/dropdown-menu"; |
4 | 4 | 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"; |
5 | 7 | import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors"; |
6 | 8 | import type { V1Resource } from "@rilldata/web-common/runtime-client"; |
7 | 9 | import { |
8 | 10 | RefreshCcwIcon, |
| 11 | + LayoutGridIcon, |
9 | 12 | CodeIcon, |
10 | 13 | ScrollTextIcon, |
11 | 14 | AlertCircleIcon, |
|
14 | 17 |
|
15 | 18 | export let resourceKind: string; |
16 | 19 | export let resourceName: string; |
17 | | - export let canRefresh: boolean; |
18 | 20 | export let resource: V1Resource; |
| 21 | + export let isReconciling: boolean = false; |
19 | 22 | export let onClickRefreshDialog: ( |
20 | 23 | resourceName: string, |
21 | 24 | resourceKind: string, |
|
28 | 31 | resource: V1Resource, |
29 | 32 | ) => void; |
30 | 33 | export let onViewLogsClick: (name: string) => void = () => {}; |
| 34 | + export let onViewPartitionsClick: |
| 35 | + | ((resource: V1Resource) => void) |
| 36 | + | undefined = undefined; |
31 | 37 | export let isDropdownOpen: boolean; |
32 | 38 | export let onDropdownOpenChange: (isOpen: boolean) => void; |
33 | 39 |
|
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"); |
38 | 46 | $: isIncremental = actions.includes("incrementalRefresh"); |
39 | 47 | $: hasErroredPartitions = actions.includes("refreshErrored"); |
| 48 | +
|
| 49 | + $: refreshDisabled = isReconciling; |
| 50 | + $: refreshTooltip = isReconciling |
| 51 | + ? "Resource is currently being reconciled" |
| 52 | + : ""; |
40 | 53 | </script> |
41 | 54 |
|
42 | 55 | <DropdownMenu.Root open={isDropdownOpen} onOpenChange={onDropdownOpenChange}> |
|
46 | 59 | </IconButton> |
47 | 60 | </DropdownMenu.Trigger> |
48 | 61 | <DropdownMenu.Content align="start"> |
| 62 | + <!-- Describe (always available) --> |
49 | 63 | <DropdownMenu.Item |
50 | 64 | class="font-normal flex items-center" |
51 | 65 | on:click={() => onClickViewSpec(resourceName, resourceKind, resource)} |
|
55 | 69 | <span class="ml-2">Describe</span> |
56 | 70 | </div> |
57 | 71 | </DropdownMenu.Item> |
| 72 | + |
| 73 | + <!-- View Logs (always available) --> |
58 | 74 | <DropdownMenu.Item |
59 | 75 | class="font-normal flex items-center" |
60 | 76 | on:click={() => onViewLogsClick(resourceName)} |
|
64 | 80 | <span class="ml-2">View Logs</span> |
65 | 81 | </div> |
66 | 82 | </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} |
79 | 86 | <DropdownMenu.Item |
80 | 87 | class="font-normal flex items-center" |
81 | | - on:click={() => |
82 | | - onClickRefreshDialog(resourceName, resourceKind, "full")} |
| 88 | + on:click={() => onViewPartitionsClick?.(resource)} |
83 | 89 | > |
84 | 90 | <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> |
87 | 93 | </div> |
88 | 94 | </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}> |
90 | 122 | <DropdownMenu.Item |
91 | 123 | class="font-normal flex items-center" |
| 124 | + disabled={refreshDisabled} |
92 | 125 | on:click={() => |
93 | | - onClickRefreshDialog(resourceName, resourceKind, "incremental")} |
| 126 | + onClickRefreshDialog(resourceName, resourceKind, "full")} |
94 | 127 | > |
95 | 128 | <div class="flex items-center"> |
96 | 129 | <RefreshCcwIcon size="12px" /> |
97 | | - <span class="ml-2">Incremental Refresh</span> |
| 130 | + <span class="ml-2">Full Refresh</span> |
98 | 131 | </div> |
99 | 132 | </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> |
100 | 154 | {/if} |
101 | 155 | {/if} |
102 | 156 | </DropdownMenu.Content> |
|
0 commit comments