mirror of
https://github.com/decaf-dev/obsidian-vault-explorer.git
synced 2026-07-22 10:10:31 +00:00
feat: update property filter app UI (#25)
This commit is contained in:
parent
690adb28f6
commit
a4126e2453
8 changed files with 162 additions and 151 deletions
|
|
@ -1,87 +0,0 @@
|
|||
<script lang="ts">
|
||||
import IconButton from "src/svelte/shared/components/icon-button.svelte";
|
||||
import Stack from "src/svelte/shared/components/stack.svelte";
|
||||
import Switch from "src/svelte/shared/components/switch.svelte";
|
||||
import { PropertyFilterGroup } from "src/types";
|
||||
|
||||
export let groups: PropertyFilterGroup[];
|
||||
export let selectedGroup: PropertyFilterGroup | undefined;
|
||||
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import Spacer from "src/svelte/shared/components/spacer.svelte";
|
||||
import TabList from "src/svelte/shared/components/tab-list.svelte";
|
||||
import Tab from "src/svelte/shared/components/tab.svelte";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleGroupToggle() {
|
||||
dispatch("groupToggle");
|
||||
}
|
||||
|
||||
function handleAddGroupClick() {
|
||||
dispatch("addGroupClick");
|
||||
}
|
||||
|
||||
function handleDeleteGroupClick() {
|
||||
dispatch("deleteGroupClick");
|
||||
}
|
||||
|
||||
function handleEditClick() {
|
||||
dispatch("editClick");
|
||||
}
|
||||
|
||||
function handleGroupClick(id: string) {
|
||||
dispatch("groupClick", { id });
|
||||
}
|
||||
|
||||
$: selectedIndex =
|
||||
groups.findIndex((group) => group.id === selectedGroup?.id) ?? 0;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if groups.length > 0}
|
||||
<Stack spacing="sm" align="center">
|
||||
<TabList variant="line" initialSelectedIndex={selectedIndex}>
|
||||
{#each groups as group (group.id)}
|
||||
<Tab on:click={() => handleGroupClick(group.id)}
|
||||
>{group.name}</Tab
|
||||
>
|
||||
{/each}
|
||||
</TabList>
|
||||
<Spacer size="md" />
|
||||
</Stack>
|
||||
{/if}
|
||||
{#if selectedGroup == undefined}
|
||||
<IconButton
|
||||
ariaLabel="Add property filter group"
|
||||
iconId="plus"
|
||||
on:click={() => handleAddGroupClick()}
|
||||
/>
|
||||
{/if}
|
||||
{#if selectedGroup !== undefined}
|
||||
<Spacer size="sm" direction="vertical" />
|
||||
<Stack align="center" spacing="sm">
|
||||
<IconButton
|
||||
ariaLabel="Edit property filter group"
|
||||
iconId="pencil"
|
||||
on:click={() => handleEditClick()}
|
||||
/>
|
||||
<IconButton
|
||||
ariaLabel="Add property filter group"
|
||||
iconId="plus"
|
||||
on:click={() => handleAddGroupClick()}
|
||||
/>
|
||||
<Stack justify="flex-end" width="100%" align="center" spacing="sm">
|
||||
<Switch
|
||||
ariaLabel="Toggle property filter group"
|
||||
value={selectedGroup.isEnabled}
|
||||
on:change={() => handleGroupToggle()}
|
||||
/>
|
||||
<IconButton
|
||||
ariaLabel="Delete property filter group"
|
||||
iconId="trash"
|
||||
on:click={() => handleDeleteGroupClick()}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
export let name: string;
|
||||
export let isSelected: boolean;
|
||||
|
||||
$: className =
|
||||
"vault-explorer-group-button" +
|
||||
(isSelected ? " vault-explorer-group-button--active" : "");
|
||||
</script>
|
||||
|
||||
<button class={className} on:click>{name}</button>
|
||||
|
||||
<style>
|
||||
.vault-explorer-group-button {
|
||||
all: unset;
|
||||
width: calc(100% - 12px);
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.vault-explorer-group-button:hover {
|
||||
background-color: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.vault-explorer-group-button--active {
|
||||
background-color: var(--background-modifier-hover);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,13 +2,8 @@
|
|||
import Divider from "src/svelte/shared/components/divider.svelte";
|
||||
import IconButton from "src/svelte/shared/components/icon-button.svelte";
|
||||
import Stack from "src/svelte/shared/components/stack.svelte";
|
||||
import { generateUUID } from "src/svelte/shared/services/uuid";
|
||||
|
||||
import {
|
||||
PropertyFilterGroup,
|
||||
TextFilterCondition,
|
||||
TextPropertyFilter,
|
||||
} from "src/types";
|
||||
import { PropertyFilterGroup } from "src/types";
|
||||
import PropertyFilterList from "./property-filter-list.svelte";
|
||||
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
|
@ -27,27 +22,18 @@
|
|||
const name = (e.target as HTMLInputElement).value;
|
||||
dispatch("groupNameChange", { name });
|
||||
}
|
||||
|
||||
function handleBackClick() {
|
||||
dispatch("backClick");
|
||||
}
|
||||
</script>
|
||||
|
||||
<Stack direction="column" align="flex-start" spacing="sm">
|
||||
<Stack spacing="sm">
|
||||
<IconButton
|
||||
ariaLabel="Back"
|
||||
iconId="arrow-left"
|
||||
on:click={handleBackClick}
|
||||
/>
|
||||
<Stack width="100%" direction="column" align="flex-start" spacing="sm">
|
||||
<div class="vault-explorer-group-edit-view__header">
|
||||
<input
|
||||
type="text"
|
||||
value={selectedGroup.name}
|
||||
on:change={handleGroupNameChange}
|
||||
/>
|
||||
</Stack>
|
||||
</div>
|
||||
<Divider />
|
||||
<div class="vault-explorer-property-filter-content">
|
||||
<div class="vault-explorer-group-edit-view__body">
|
||||
{#if selectedGroup.filters.length > 0}
|
||||
<PropertyFilterList
|
||||
filters={selectedGroup.filters}
|
||||
|
|
@ -59,10 +45,10 @@
|
|||
on:filterToggle
|
||||
on:filterDeleteClick
|
||||
/>
|
||||
<Spacer direction="vertical" size="md" />
|
||||
<Spacer direction="vertical" size="sm" />
|
||||
{/if}
|
||||
<IconButton
|
||||
ariaLabel="Add filter"
|
||||
ariaLabel="Add property filter"
|
||||
iconId="plus"
|
||||
on:click={handleAddFilterClick}
|
||||
/>
|
||||
|
|
@ -70,10 +56,13 @@
|
|||
</Stack>
|
||||
|
||||
<style>
|
||||
.vault-explorer-property-filter-content {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
padding: 5px;
|
||||
/* padding-top: 5px; */
|
||||
.vault-explorer-group-edit-view__header {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.vault-explorer-group-edit-view__body {
|
||||
padding: 5px 10px;
|
||||
overflow-y: auto;
|
||||
max-height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<script lang="ts">
|
||||
import IconButton from "src/svelte/shared/components/icon-button.svelte";
|
||||
import Stack from "src/svelte/shared/components/stack.svelte";
|
||||
import { PropertyFilterGroup } from "src/types";
|
||||
|
||||
export let groups: PropertyFilterGroup[];
|
||||
export let selectedGroup: PropertyFilterGroup | undefined;
|
||||
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import GroupButton from "./group-button.svelte";
|
||||
import Flex from "src/svelte/shared/components/flex.svelte";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleAddGroupClick() {
|
||||
dispatch("addGroupClick");
|
||||
}
|
||||
|
||||
function handleDeleteGroupClick() {
|
||||
dispatch("deleteGroupClick");
|
||||
}
|
||||
|
||||
function handleGroupClick(id: string) {
|
||||
dispatch("groupClick", { id });
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="vault-explorer-group-list-container">
|
||||
<Stack direction="column" spacing="sm">
|
||||
<Stack spacing="sm">
|
||||
<IconButton
|
||||
ariaLabel="Add property filter group"
|
||||
iconId="plus"
|
||||
on:click={() => handleAddGroupClick()}
|
||||
/>
|
||||
<IconButton
|
||||
ariaLabel="Delete property filter group"
|
||||
iconId="trash"
|
||||
on:click={() => handleDeleteGroupClick()}
|
||||
/>
|
||||
</Stack>
|
||||
<div class="vault-explorer-group-list">
|
||||
<Flex direction="column" width="100px">
|
||||
{#each groups as group (group.id)}
|
||||
<GroupButton
|
||||
name={group.name}
|
||||
isSelected={selectedGroup?.id === group.id}
|
||||
on:click={() => handleGroupClick(group.id)}
|
||||
/>
|
||||
{/each}
|
||||
</Flex>
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.vault-explorer-group-list-container {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.vault-explorer-group-list {
|
||||
max-height: 220px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
import store from "src/svelte/shared/services/store";
|
||||
import VaultExplorerPlugin from "src/main";
|
||||
import { ObsidianProperty } from "src/obsidian/types";
|
||||
import Wrap from "src/svelte/shared/components/wrap.svelte";
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function handleDeleteClick() {
|
||||
|
|
@ -94,7 +95,7 @@
|
|||
</script>
|
||||
|
||||
<div class="vault-explorer-property-filter">
|
||||
<Stack spacing="md">
|
||||
<Wrap spacingX="sm" spacingY="sm">
|
||||
<select value={type} on:change={handlePropertyTypeChange}>
|
||||
{#each Object.values(PropertyFilterType) as type}
|
||||
<option value={type}>{type}</option>
|
||||
|
|
@ -118,9 +119,13 @@
|
|||
{/if}
|
||||
<Stack spacing="sm" align="center">
|
||||
<Switch value={isEnabled} on:change={() => handleToggle()} />
|
||||
<IconButton iconId="trash" on:click={() => handleDeleteClick()} />
|
||||
<IconButton
|
||||
ariaLabel="Delete property filter"
|
||||
iconId="trash"
|
||||
on:click={() => handleDeleteClick()}
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Wrap>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -13,11 +13,12 @@
|
|||
TextFilterCondition,
|
||||
} from "src/types";
|
||||
import { generateUUID } from "../shared/services/uuid";
|
||||
import BaseView from "./components/base-view.svelte";
|
||||
import GroupEditView from "./components/group-edit-view.svelte";
|
||||
import { createPropertyFilter } from "./utils";
|
||||
import GroupList from "./components/group-list.svelte";
|
||||
import Flex from "../shared/components/flex.svelte";
|
||||
import Divider from "../shared/components/divider.svelte";
|
||||
|
||||
let editMenu: boolean = false;
|
||||
let selectedGroupId: string = "";
|
||||
let groups: PropertyFilterGroup[] = [];
|
||||
let plugin: VaultExplorerPlugin;
|
||||
|
|
@ -247,39 +248,35 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if editMenu === false}
|
||||
<BaseView
|
||||
<div class="vault-explorer-property-filter-app">
|
||||
<Flex align="stretch" height="100%">
|
||||
<GroupList
|
||||
{groups}
|
||||
{selectedGroup}
|
||||
on:editClick={() => (editMenu = true)}
|
||||
on:groupClick={handleGroupClick}
|
||||
on:addGroupClick={handleAddGroupClick}
|
||||
on:deleteGroupClick={handleDeleteGroupClick}
|
||||
on:groupToggle={handleGroupToggle}
|
||||
on:groupNameChange={handleGroupNameChange}
|
||||
on:filterAddClick={handleFilterAddClick}
|
||||
on:groupClick={handleGroupClick}
|
||||
on:filterConditionChange={handleFilterConditionChange}
|
||||
on:filterDeleteClick={handleFilterDeleteClick}
|
||||
on:filterNameChange={handleFilterNameChange}
|
||||
on:filterToggle={handleFilterToggle}
|
||||
on:filterValueChange={handleFilterValueChange}
|
||||
/>
|
||||
{/if}
|
||||
{#if editMenu === true && selectedGroup !== undefined}
|
||||
<GroupEditView
|
||||
{selectedGroup}
|
||||
on:backClick={() => (editMenu = false)}
|
||||
on:groupNameChange={handleGroupNameChange}
|
||||
on:filterAddClick={handleFilterAddClick}
|
||||
on:groupClick={handleGroupClick}
|
||||
on:filterTypeChange={handleFilterTypeChange}
|
||||
on:filterConditionChange={handleFilterConditionChange}
|
||||
on:filterDeleteClick={handleFilterDeleteClick}
|
||||
on:filterNameChange={handleFilterNameChange}
|
||||
on:filterToggle={handleFilterToggle}
|
||||
on:filterValueChange={handleFilterValueChange}
|
||||
/>
|
||||
{/if}
|
||||
<Divider direction="vertical" />
|
||||
{#if selectedGroup !== undefined}
|
||||
<GroupEditView
|
||||
{selectedGroup}
|
||||
on:groupNameChange={handleGroupNameChange}
|
||||
on:filterAddClick={handleFilterAddClick}
|
||||
on:groupClick={handleGroupClick}
|
||||
on:filterTypeChange={handleFilterTypeChange}
|
||||
on:filterConditionChange={handleFilterConditionChange}
|
||||
on:filterDeleteClick={handleFilterDeleteClick}
|
||||
on:filterNameChange={handleFilterNameChange}
|
||||
on:filterToggle={handleFilterToggle}
|
||||
on:filterValueChange={handleFilterValueChange}
|
||||
/>
|
||||
{/if}
|
||||
</Flex>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.vault-explorer-property-filter-app {
|
||||
height: 255px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,23 @@
|
|||
<hr class="vault-explorer-divider" />
|
||||
<script lang="ts">
|
||||
export let direction: "horizontal" | "vertical" = "horizontal";
|
||||
|
||||
$: className = `vault-explorer-divider vault-explorer-divider--${direction}`;
|
||||
</script>
|
||||
|
||||
<div class={className} />
|
||||
|
||||
<style>
|
||||
.vault-explorer-divider {
|
||||
.vault-explorer-divider--horizontal {
|
||||
width: 100%;
|
||||
margin: 0.5rem 0;
|
||||
height: 0;
|
||||
border-top: var(--hr-thickness) solid var(--hr-color);
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.vault-explorer-divider--vertical {
|
||||
width: 0px;
|
||||
/* height: 100%; */
|
||||
border-top: 0;
|
||||
border-left: var(--hr-thickness) solid var(--hr-color);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
export let direction: "row" | "column" = "row";
|
||||
export let justify: "flex-start" | "center" | "space-between" | "flex-end" =
|
||||
"flex-start";
|
||||
export let align: "flex-start" | "center" | "flex-end" = "flex-start";
|
||||
export let align: "flex-start" | "center" | "flex-end" | "stretch" =
|
||||
"flex-start";
|
||||
export let wrap: "wrap" | "nowrap" = "nowrap";
|
||||
export let width: string = "";
|
||||
export let height: string = "";
|
||||
|
|
|
|||
Loading…
Reference in a new issue