Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 0 additions & 42 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 30 additions & 20 deletions src/lib/components/tree/ConfigTree.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@
compatible_config_types,
selectClosestMatch,
} from "./../../../routes/EditorLayout";
import { type Config } from "../../schemas";
import type { Config } from "../../schemas";
import { Tree } from "./ConfigTree";
import { createEventDispatcher } from "svelte";
import { createEventDispatcher, tick } from "svelte";
import { parentIframeCommunication } from "../../utils";
import { dragTarget } from "../../actions/drag.action";
import ProfileCloudTreeItem from "./ProfileCloudTreeItem.svelte";
import {
type AbstractFolderData,
AbstractTreeNode,
TreeItemType,
type ContextMenuOptions,
type TreeProperties,
} from "./TreeNode.svelte";
import { TreeItemType } from "./TreeNode.svelte";
import type { AbstractFolderData, AbstractTreeNode } from "./TreeNode.svelte";
import type { TreeProperties } from "./TreeComponent.svelte";
import type { ContextMenuOptions } from "@intechstudio/grid-uikit";

import TreeFolder from "./TreeFolder.svelte";

Expand All @@ -36,8 +33,11 @@
const dispatch = createEventDispatcher();

export let configs: Config[];
export let scrollToSelectionTrigger = 0;

let treeProps: TreeProperties;
let treeRoot: Tree.Node;
let filteredConfigs: Config[] = [];

export function debounced<T>(store: Writable<T>, delay = 300) {
let timeout: ReturnType<typeof setTimeout>;
Expand All @@ -56,14 +56,31 @@
export const debounced_filter_value = debounced(filter_value, 300);

$: {
treeProps = buildProps(
const tree = buildTree(
configs,
$debounced_filter_value,
$sort_key,
$show_supported_only,
$hide_community_configs,
$compatible_config_types,
);
treeRoot = tree.root;
filteredConfigs = tree.filteredConfigs;
}

$: if (treeRoot) {
selectClosestMatch($selected_config, filteredConfigs);
const selected = get(selected_config);
treeProps = {
root: treeRoot,
selected: selected?.id,
expanded: treeRoot.getIncludingNodes(selected?.id),
scrollBehaviour: {
scrollToIndex: scrollToSelectionTrigger > 0,
scrollTrigger: scrollToSelectionTrigger,
easing: "smooth",
},
};
}

function filterNode(node: Tree.Node, filter: FilterValue, level = 0) {
Expand Down Expand Up @@ -112,14 +129,14 @@
});
}

function buildProps(
function buildTree(
configs: Config[],
filter: FilterValue,
key: Sort.Key,
supported: boolean,
community: boolean,
compatibileTypes: string[],
): TreeProperties {
) {
const filteredConfigs = configs.filter((e) => matches(e, filter));
const root = Tree.create(configs, {
showSupportedOnly: supported,
Expand All @@ -129,14 +146,7 @@

filterNode(root, filter);

selectClosestMatch($selected_config, filteredConfigs);

return {
root: root,
selected: $selected_config?.id,
expanded: root.getIncludingNodes($selected_config?.id),
scrollBehaviour: { scrollToIndex: true, easing: "instant" },
};
return { root, filteredConfigs };
}

function handleDeleteVirtualDirectory(title: string) {
Expand Down
13 changes: 7 additions & 6 deletions src/lib/components/tree/ConfigTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
config_manager,
compatible_config_types,
} from "./../../../routes/EditorLayout";
import { type Config } from "../../schemas";
import type { Config } from "../../schemas";
import { filter_value } from "../../../routes/Filter";
import { Sort } from "../../../routes/Sorter";

Expand All @@ -22,6 +22,7 @@ import { ElementType, grid, ModuleType } from "@intechstudio/grid-protocol";
export namespace Tree {
export interface Options {
showSupportedOnly?: boolean;
hideCommunityConfigs?: boolean;
compatibileTypes: string[];
}

Expand Down Expand Up @@ -287,7 +288,7 @@ export namespace Tree {
e.owner ?? "",
);

const cct = get(compatible_config_types);
const cct = get(compatible_config_types) as string[];

return (
!isMyConfig &&
Expand All @@ -311,7 +312,7 @@ export namespace Tree {
const isOfficialConfig =
configuration.WORKFLOW_CONFIG_PROFILE_IDS.includes(e.owner ?? "");

const cct = get(compatible_config_types);
const cct = get(compatible_config_types) as string[];

return (
!isMyConfig &&
Expand All @@ -336,7 +337,7 @@ export namespace Tree {
configuration.RECOMMENDED_CONFIG_PROFILE_IDS.includes(
e.owner ?? "",
);
const cct = get(compatible_config_types);
const cct = get(compatible_config_types) as string[];
return (
!isMyConfig &&
!isOfficialConfig &&
Expand All @@ -356,7 +357,7 @@ export namespace Tree {
.filter((e: Config) => {
const isMyConfig =
e.syncStatus == "local" || e.owner === cm?.getCurrentOwnerId();
const cct = get(compatible_config_types);
const cct = get(compatible_config_types) as string[];
return !isMyConfig && (!showSupportedOnly || cct.includes(e.type));
})
.map(
Expand All @@ -372,7 +373,7 @@ export namespace Tree {
.filter((e: Config) => {
const isMyConfig =
e.syncStatus == "local" || e.owner === cm?.getCurrentOwnerId();
const cct = get(compatible_config_types);
const cct = get(compatible_config_types) as string[];

return !isMyConfig && showSupportedOnly && !cct.includes(e.type);
})
Expand Down
89 changes: 49 additions & 40 deletions src/lib/components/tree/TreeComponent.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export interface TreeScrollBehaviour {
scrollToIndex?: boolean;
easing?: "smooth" | "instant";
scrollTrigger?: number;
}

export interface TreeProperties {
Expand All @@ -13,10 +14,12 @@
</script>

<script lang="ts">
import { createTreeView, type TreeView } from "@melt-ui/svelte";
import { setContext } from "svelte";
import TreeNode, { type AbstractTreeNode } from "./TreeNode.svelte";
import { type FolderSlotProps, type ItemSlotProps } from "./TreeChild.svelte";
import { createTreeView } from "@melt-ui/svelte";
import type { TreeView } from "@melt-ui/svelte";
import { setContext, tick } from "svelte";
import TreeNode from "./TreeNode.svelte";
import type { AbstractTreeNode } from "./TreeNode.svelte";
import type { FolderSlotProps, ItemSlotProps } from "./TreeChild.svelte";
import { get } from "svelte/store";

interface $$Slots {
Expand All @@ -33,7 +36,7 @@
let rootHeight: number;

let ctx: TreeView;
$: if ($root?.id) {
$: if ($root?.id && !ctx) {
ctx = createTreeView({ onExpandedChange: handleExpandedChange });
setContext("tree", ctx);
}
Expand Down Expand Up @@ -63,10 +66,14 @@
}

let scrollTimeout: any;
async function scrollToNode(node: HTMLElement, id: string) {
let lastScrollTrigger: number | undefined;
async function scrollToNode(id: string, attempt = 0) {
clearTimeout(scrollTimeout);
await tick();
scrollTimeout = setTimeout(() => {
const target = node.querySelector(`#${CSS.escape(id)}`) as HTMLElement;
const target = rootElement?.querySelector(
`#${CSS.escape(id)}`,
) as HTMLElement;
if (target) {
target.scrollIntoView({
behavior: scrollBehaviour.easing ?? "smooth",
Expand All @@ -75,46 +82,48 @@
});
return;
}

if (attempt < 4) {
scrollToNode(id, attempt + 1);
}
}, 100);
}

$: if (selected && (scrollBehaviour.scrollToIndex ?? false)) {
scrollToNode(rootElement, selected);
$: if (
selected &&
rootElement &&
(scrollBehaviour.scrollToIndex ?? false) &&
scrollBehaviour.scrollTrigger !== undefined &&
scrollBehaviour.scrollTrigger !== lastScrollTrigger
) {
lastScrollTrigger = scrollBehaviour.scrollTrigger;
scrollToNode(selected);
}
</script>

{#key tree}
<ul
bind:this={rootElement}
bind:clientHeight={rootHeight}
{...$tree}
class="tree"
>
<TreeNode node={root} level={0} {rootElement} {rootHeight}>
<svelte:fragment slot="folder" let:level let:item let:expanded>
<slot name="folder" {level} {item} {expanded} />
</svelte:fragment>
<ul
bind:this={rootElement}
bind:clientHeight={rootHeight}
{...$tree}
class="tree"
>
<TreeNode node={root} level={0} {rootElement} {rootHeight}>
<svelte:fragment slot="folder" let:level let:item let:expanded>
<slot name="folder" {level} {item} {expanded} />
</svelte:fragment>

<svelte:fragment
slot="item"
let:item
let:level
let:expanded
let:itemFunction
let:itemProps
>
<slot
name="item"
{level}
{item}
{expanded}
{itemFunction}
{itemProps}
/>
</svelte:fragment>
</TreeNode>
</ul>
{/key}
<svelte:fragment
slot="item"
let:item
let:level
let:expanded
let:itemFunction
let:itemProps
>
<slot name="item" {level} {item} {expanded} {itemFunction} {itemProps} />
</svelte:fragment>
</TreeNode>
</ul>

<style>
ul {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/tree/TreeNode.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
}

$: {
const items = Array.from(listItems.values());
const items = Array.from(listItems.values()).filter(Boolean);
if (items.length > 0 && level === 0) {
setMaxHeight(rootHeight, items);
}
Expand Down
Loading
Loading