-
Notifications
You must be signed in to change notification settings - Fork 146
Expand file tree
/
Copy pathworkers-table-cell.svelte
More file actions
124 lines (112 loc) · 3.42 KB
/
workers-table-cell.svelte
File metadata and controls
124 lines (112 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<script lang="ts">
import type { Snippet } from 'svelte';
import { page } from '$app/state';
import FilterOrCopyButtons from '$lib/holocene/filter-or-copy-buttons.svelte';
import Link from '$lib/holocene/link.svelte';
import Tooltip from '$lib/holocene/tooltip.svelte';
import { translate } from '$lib/i18n/translate';
import type { SearchAttributeFilter } from '$lib/models/search-attribute-filters';
import { workerFilters } from '$lib/stores/filters';
import {
createFilter,
updateQueryParamsFromFilter,
} from '$lib/utilities/query/to-list-workflow-filters';
import { truncateValue } from '$lib/utilities/truncate-value';
interface Props {
attribute?: string;
copyable?: boolean;
filters?: SearchAttributeFilter[];
value?: string | null;
filterable?: boolean;
href?: string;
children?: Snippet;
}
let {
attribute,
copyable = true,
filters,
value,
filterable = false,
href,
children,
}: Props = $props();
const matchesFilter = (a: SearchAttributeFilter, b: SearchAttributeFilter) =>
a.attribute === b.attribute && a.value === b.value;
const toggleFilters = $derived(
filters && filters.length > 0
? filters
: [createFilter({ attribute, value: value ?? '', conditional: '=' })],
);
const isFiltered = $derived(
toggleFilters.some((f) =>
$workerFilters.some((wf) => matchesFilter(wf, f)),
),
);
const onRowFilterClick = async () => {
const toRemove = toggleFilters.filter((f) =>
$workerFilters.some((wf) => matchesFilter(wf, f)),
);
const toAdd = toggleFilters.filter(
(f) => !$workerFilters.some((wf) => matchesFilter(wf, f)),
);
$workerFilters = [
...$workerFilters.filter(
(wf) => !toRemove.some((f) => matchesFilter(wf, f)),
),
...toAdd,
];
updateQueryParamsFromFilter(page.url, $workerFilters);
};
let filterOrCopyButtonsVisible = $state(false);
const showFilterOrCopy = () => (filterOrCopyButtonsVisible = true);
const hideFilterOrCopy = () => (filterOrCopyButtonsVisible = false);
const handleFocusOut = (e: FocusEvent) => {
const nextTarget = e.relatedTarget as HTMLElement;
if (
nextTarget &&
!['filter-button', 'copy-button'].includes(nextTarget.id)
) {
hideFilterOrCopy();
}
};
</script>
<td
class="relative h-8"
onfocus={showFilterOrCopy}
onfocusin={showFilterOrCopy}
onfocusout={handleFocusOut}
onmouseover={showFilterOrCopy}
onmouseleave={hideFilterOrCopy}
onblur={hideFilterOrCopy}
>
{#if attribute === 'BuildId' || attribute === 'WorkerInstanceKey'}
{#if href}
<Tooltip text={value ?? undefined} top class="min-w-0">
<Link {href}>{truncateValue(value)}</Link>
</Tooltip>
{:else}
<Tooltip text={value ?? undefined} top class="min-w-0">
{truncateValue(value)}
</Tooltip>
{/if}
{:else if href}
<Link {href}>{value}</Link>
{:else if children}
{@render children?.()}
{:else}
{value}
{/if}
{#if value || (filters && filters.length > 0)}
<FilterOrCopyButtons
copyIconTitle={translate('common.copy-icon-title')}
copySuccessIconTitle={translate('common.copy-success-icon-title')}
filterIconTitle={translate('common.filter-workflows')}
show={filterOrCopyButtonsVisible}
content={value ?? ''}
onFilter={onRowFilterClick}
{copyable}
{filterable}
filtered={isFiltered}
/>
{/if}
</td>