new next sidebar (#315)

* #314 filter with new sidebar

---------

Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
Neil 2023-03-21 10:08:03 +08:00 committed by GitHub
parent 76cddeae2d
commit 8501fc1765
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 183 additions and 63 deletions

View file

@ -96,6 +96,7 @@
"lorem-ipsum": "^2.0.8",
"mixpanel-browser": "^2.45.0",
"mkdirp": "^2.1.3",
"moment": "^2.29.4",
"pushy-electron": "^1.0.11",
"renderer": "link:@types/electron/renderer",
"semver": "^7.3.8",

View file

@ -1,8 +1,9 @@
<script lang="ts">
import '$appcss';
import { t } from '$libs/translations';
// import { t } from '$libs/translations';
import type { GUIPackage } from '$libs/types';
import { PackageStates } from '$libs/types';
import moment from "moment";
import { PackageStates, SideMenuOptions } from '$libs/types';
import Preloader from '@tea/ui/Preloader/Preloader.svelte';
import Package from "./package.svelte";
import { packagesStore } from '$libs/stores';
@ -11,14 +12,33 @@
import { trackInstall, trackInstallFailed } from '$libs/analytics';
const { packages: allPackages } = packagesStore;
export let packageFilter: SideMenuOptions = SideMenuOptions.all;
export let stateFilters: {[key: string]: boolean};
export let sortBy: "popularity" | "most recent" = 'popularity';
export let sortDirection: 'asc' | 'desc' = 'desc';
const loadMore = 9;
let limit = loadMore;
$: filterExists = Object.keys(stateFilters).some((k) => stateFilters[k]);
// TODO: figure out a better type strategy here so that this breaks if SideMenuOptions is updated
const pkgFilters: { [key:string]: (pkg: GUIPackage) => boolean } = {
[SideMenuOptions.all]: (_pkg: GUIPackage) => true,
[SideMenuOptions.installed]: (pkg: GUIPackage) => pkg.state === PackageStates.INSTALLED,
[SideMenuOptions.installed_updates_available]: (pkg: GUIPackage) => pkg.state === PackageStates.NEEDS_UPDATE,
[SideMenuOptions.recently_updated]: (pkg: GUIPackage) => {
return moment(pkg.last_modified).isAfter(moment().subtract(30, "days"));
},
[SideMenuOptions.new_packages]: (_pkg: GUIPackage) => {
// todo: use pkg.created_at but its depends on https://github.com/teaxyz/kettle/issues/119
return true;
},
[SideMenuOptions.popular]: (pkg: GUIPackage) => pkg.categories.includes(SideMenuOptions.popular),
[SideMenuOptions.featured]: (pkg: GUIPackage) => pkg.categories.includes(SideMenuOptions.featured),
[SideMenuOptions.essentials]: (pkg: GUIPackage) => pkg.categories.includes(SideMenuOptions.essentials),
[SideMenuOptions.star_struct]: (pkg: GUIPackage) => pkg.categories.includes(SideMenuOptions.star_struct),
[SideMenuOptions.made_by_tea]: (pkg: GUIPackage) => pkg.full_name.includes("tea.xyz"),
}
$: packages = $allPackages
.sort((a, b) => {
if (sortBy === 'popularity') {
@ -32,20 +52,9 @@
return sortDirection === 'asc' ? +aDate - +bDate : +bDate - +aDate;
}
})
.filter((pkg) => {
if (!filterExists || pkg.state === PackageStates.INSTALLING) return true;
return stateFilters[pkg.state];
});
.filter(pkgFilters[packageFilter] || pkgFilters.all);
</script>
<!-- <header class="flex items-center justify-between z-50 w-full absolute">
<h1 class="text-primary text-4xl font-bold">{$t("home.all-packages")}</h1>
<div class="flex">
<section class="border-gray h-10 w-48 border rounded-sm">
<SortingButtons {onSort} />
</section>
</div>
</header> -->
<div>
<ul class="grid grid-cols-3 gap-2 bg-black">
{#if packages.length > 0}

View file

@ -0,0 +1,23 @@
<script lang="ts">
import '$appcss';
export let icon:string;
export let label:string;
export let active = false;
</script>
<button on:click class={`text-xs w-full flex transition-all rounded-sm hover:bg-opacity-25 border-gray hover:border p-2 gap-2 items-center align-middle text-left hover:bg-gray box-border ${active && 'active'}`}>
<i class={`icon-${icon} mt-1`}/>
<div class="font-thin">{label}</div>
</button>
<style>
button {
box-sizing: border-box;
height: 37px;
}
button.active {
background: rgba(148, 148, 148, 0.5);
border: rgba(148, 148, 148, 1) 1px solid;
}
</style>

View file

@ -0,0 +1,69 @@
<script lang="ts">
import '$appcss';
import { PackageStates, SideMenuOptions } from '$libs/types';
import { packagesStore } from '$libs/stores';
import MenuButton from './menu-button.svelte';
const { packages } = packagesStore;
export let activeOption:SideMenuOptions;
$: needsUpdateCount = $packages.filter((p) => p.state === PackageStates.NEEDS_UPDATE).length;
const selectToggle = (option: SideMenuOptions) => {
activeOption = option === activeOption ? SideMenuOptions.all : option;
}
</script>
<aside class="border border-t-0 border-b-0 border-gray p-2">
<ul class="flex flex-col pt-4 gap-1 pl-1">
<MenuButton label="Installed" icon="tea-checkmark"
active={activeOption === SideMenuOptions.installed}
on:click={() => selectToggle(SideMenuOptions.installed)}
/>
{#if needsUpdateCount}
<MenuButton label="Updates available" icon="update"
active={activeOption === SideMenuOptions.installed_updates_available}
on:click={() => selectToggle(SideMenuOptions.installed_updates_available)}
/>
{/if}
<MenuButton label="Recently updated" icon="back-in-time"
active={activeOption === SideMenuOptions.recently_updated}
on:click={() => selectToggle(SideMenuOptions.recently_updated)}
/>
<!-- <MenuButton label="New packages" icon="birthday-cake"
active={activeOption === SideMenuOptions.new_packages}
on:click={() => selectToggle(SideMenuOptions.new_packages)}
/> -->
<MenuButton label="Popular" icon="bar-chart"
active={activeOption === SideMenuOptions.popular}
on:click={() => selectToggle(SideMenuOptions.popular)}
/>
<MenuButton label="Featured" icon="lightbulb"
active={activeOption === SideMenuOptions.featured}
on:click={() => selectToggle(SideMenuOptions.featured)}
/>
<MenuButton label="Essentials" icon="square"
active={activeOption === SideMenuOptions.essentials}
on:click={() => selectToggle(SideMenuOptions.essentials)}
/>
<MenuButton label="Star-struct" icon="star-full"
active={activeOption === SideMenuOptions.star_struct}
on:click={() => selectToggle(SideMenuOptions.star_struct)}
/>
<MenuButton label="Made by tea" icon="tea-logo-iconasset-1"
active={activeOption === SideMenuOptions.made_by_tea}
on:click={() => selectToggle(SideMenuOptions.made_by_tea)}
/>
</ul>
</aside>
<style>
aside {
position: fixed;
top: 40px;
left: 0px;
height: calc(100% - 40px);
width: 190px;
}
</style>

View file

@ -76,6 +76,18 @@
"notification": {
"gui-downloading": "A new tea gui({{version}}) is being downloaded. Please don't close the app.",
"gui-downloaded": "A new tea gui({{version}}) is now available. Relaunch the app to update."
},
"side-menu-title": {
"all": "All Packages",
"installed": "Installed Packages",
"installed_updates_available": "Available Updates",
"recently_updated": "Recently Updated",
"new_packages": "New Packages",
"popular": "Popular",
"featured": "Featured",
"essentials": "Essentials",
"star_struct": "Star-struct Heavyweights",
"made_by_tea": "Made by Tea.xyz"
}
}
}

View file

@ -51,3 +51,16 @@ export interface Session {
user?: Developer;
locale?: string;
}
export enum SideMenuOptions {
all = "all",
installed = "installed",
installed_updates_available = "installed_updates_available",
recently_updated = "recently_updated",
new_packages = "new_packages",
popular = "popular",
featured = "featured",
essentials = "essentials",
star_struct = "star_struct",
made_by_tea = "made_by_tea"
}

View file

@ -3,51 +3,24 @@
import { t } from '$libs/translations';
import { navStore, packagesStore, notificationStore } from '$libs/stores';
import Packages from '$components/packages/packages.svelte';
import Checkbox from "@tea/ui/checkbox/checkbox.svelte";
import { PackageStates } from '$libs/types';
import { SideMenuOptions } from '$libs/types';
import SortingButtons from "$components/search-packages/sorting-buttons.svelte";
import SideMenu from "$components/side-menu/side-menu.svelte";
const { sideNavOpen } = navStore;
const { sideNavOpen } = navStore; // right side not left
let stateFilters = {
[PackageStates.AVAILABLE]: false,
[PackageStates.NEEDS_UPDATE]: false,
[PackageStates.INSTALLED]: false,
}
let sideMenuOption = SideMenuOptions.all;
let sortBy: "popularity" | "most recent" = "popularity";
let sortDirection: "asc" | "desc" = "desc";
const { packages } = packagesStore;
$: needsUpdateCount = $packages.filter((p) => p.state === PackageStates.NEEDS_UPDATE).length;
</script>
<div id="package-container">
<Packages stateFilters={{
...stateFilters,
[PackageStates.NEEDS_UPDATE]: needsUpdateCount ? stateFilters[PackageStates.NEEDS_UPDATE] : false,
}} {sortBy} {sortDirection}/>
<Packages packageFilter={sideMenuOption} {sortBy} {sortDirection}/>
</div>
<aside class={`border border-gray p-2 ${$notificationStore.length ? "lower": ""}`}>
<h2 class="text-xl text-primary">Search OSS</h2>
<h3 class="text-lg text-primary">Status</h3>
<ul>
<li>
<Checkbox label={"Not installed"} bind:checked={stateFilters[PackageStates.AVAILABLE]} />
</li>
<li>
<Checkbox label={"Installed"} bind:checked={stateFilters[PackageStates.INSTALLED]} />
</li>
{#if needsUpdateCount}
<li>
<Checkbox label={`Update Available [${needsUpdateCount}]`} bind:checked={stateFilters[PackageStates.NEEDS_UPDATE]} />
</li>
{/if}
</ul>
</aside>
<SideMenu bind:activeOption={sideMenuOption}/>
<header class={`transition-all px-2 flex justify-between items-center align-middle ${$sideNavOpen ? "min": ""} ${$notificationStore.length ? "lower": ""}`}>
<h1 class="text-primary mt-4 text-2xl font-bold">{$t("home.all-packages")}</h1>
<h1 class="text-primary mt-4 text-2xl font-bold">{$t(`side-menu-title.${sideMenuOption}`)}</h1>
<section class="border-gray mt-4 mr-4 h-10 w-48 border rounded-sm">
<SortingButtons onSort={(prop, dir) => {
sortBy = prop;
@ -63,22 +36,12 @@
margin-left: 200px;
}
aside {
position: fixed;
top: 100px;
left: 10px;
height: calc(100% - 110px);
width: 190px;
}
aside.lower {
top: 140px;
}
header {
position: fixed;
top: 40px;
left: 0px;
left: 190px;
height: 50px;
width: 100%;
width: calc(100% - 190px);
background-image: linear-gradient(black, rgba(0,0,0,0.6), rgba(0,0,0,0));
}
@ -87,6 +50,6 @@
}
header.min {
width: 75%;
width: calc(75% - 190px);
}
</style>

View file

@ -41,4 +41,10 @@
<glyph glyph-name="check-circle" unicode="&#70;" d="M403 302c0 6-1 10-5 13l-26 26c-3 4-8 6-13 6-5 0-9-2-12-6l-117-116-65 64c-3 4-7 6-12 6-5 0-10-2-13-6l-26-25c-4-4-5-8-5-13 0-6 1-10 5-13l103-104c4-3 8-5 13-5 5 0 10 2 13 5l155 155c4 4 5 8 5 13z m72-46c0-40-9-77-29-110-20-34-46-60-80-80-33-20-70-29-110-29-40 0-77 9-110 29-34 20-60 46-80 80-20 33-29 70-29 110 0 40 9 77 29 110 20 34 46 60 80 80 33 20 70 29 110 29 40 0 77-9 110-29 34-20 60-46 80-80 20-33 29-70 29-110z"/>
<glyph glyph-name="tea-x-btn" unicode="&#71;" d="M512 463l-49 49-207-207-207 207-49-49 207-207-207-207 49-49 207 207 207-207 49 49-207 207z"/>
<glyph glyph-name="world" unicode="&#72;" d="M248 512c-137 0-248-111-248-248 0-137 111-248 248-248 137 0 248 111 248 248 0 137-111 248-248 248z m216-240l-96 0c-1 35-8 69-19 100 22 9 42 21 60 35 32-36 53-83 55-135z m-225-224c-26 23-49 51-65 85 21 6 43 10 66 11l0-96c0 0-1 0-1 0z m18 432c30-26 55-59 71-98-23-8-47-13-72-14l0 112c0 0 1 0 1 0z m26-3c45-8 84-28 115-58-17-13-35-24-55-32-14 35-35 65-60 90z m-43 3l0-112c-25 1-49 6-72 14 16 39 41 72 71 98 0 0 1 0 1 0z m-87-93c-20 8-38 19-55 32 31 30 70 50 115 58-25-25-46-55-60-90z m9-20c24-9 51-14 78-15l0-80-96 0c1 34 7 66 18 95z m78-111l0-96c-25-1-50-5-73-13-13 33-22 70-23 109z m-27-205c-40 7-76 24-105 49 16 11 33 20 51 27 14-29 32-54 54-76z m43-3l0 96c23-1 45-5 66-11-16-34-39-62-65-85 0 0-1 0-1 0z m81 79c18-7 35-16 51-27-29-25-65-42-105-49 22 22 40 47 54 76z m-8 20c-23 8-48 12-73 13l0 96 96 0c-1-39-10-76-23-109z m-73 125l0 80c27 1 54 6 78 15 11-29 17-62 18-95l-96 0z m-169 135c18-14 38-26 60-35-11-31-18-65-19-100l-96 0c2 52 23 99 55 135z m-55-151l96 0c1-41 10-79 24-114-20-8-39-19-56-31-38 37-62 88-64 145z m368-145c-17 12-36 23-56 31 14 35 23 73 24 114l96 0c-2-57-26-108-64-145z"/>
<glyph glyph-name="update" unicode="&#73;" d="M320 277l0 235-107 0 0-235-84 0 136-135 135 135z m110 86l-67 0 0-43 67 0c12 0 18 0 18-12l0-160c0-18-11-41-29-41l-326 0c-18 0-29 23-29 41l0 160c0 12 6 12 18 12l67 0 0 43-67 0c-35 0-61-20-61-55l0-235c0-35 26-73 61-73l348 0c35 0 61 38 61 73l0 235c0 35-26 55-61 55z m18-290c0-11-6-30-18-30l-348 0c-12 0-18 19-18 30l0 33c0-7 17-21 29-21l326 0c12 0 29 14 29 21z"/>
<glyph glyph-name="back-in-time" unicode="&#74;" d="M288 466c58 0 107-21 148-62 40-40 61-90 61-148 0-58-21-108-61-148-41-41-90-62-148-62-47 0-90 15-129 45 0 0 36 39 36 39 28-20 59-31 93-31 43 0 80 16 110 46 31 31 46 68 46 111 0 44-15 81-46 112-30 30-67 46-110 46-43 0-79-15-109-44-31-30-47-66-48-108 0 0 73 0 73 0 0 0-94-105-94-105 0 0-95 105-95 105 0 0 64 0 64 0 1 57 22 105 63 145 40 39 89 59 146 59m-19-97c0 0 36 0 36 0 0 0 0-105 0-105 0 0 67-66 67-66 0 0-26-26-26-26 0 0-77 77-77 77 0 0 0 120 0 120"/>
<glyph glyph-name="bar-chart" unicode="&#75;" d="M146 256l0-146-73 0 0 146z m110 146l0-292-73 0 0 292z m293-329l0-36-586 0 0 438 37 0 0-402z m-183 256l0-219-73 0 0 219z m109 110l0-329-73 0 0 329z"/>
<glyph glyph-name="lightbulb" unicode="&#76;" d="M411 415l0 0 0 0c3 3 3 8 0 11l-10 10c-3 3-8 3-11 0l0 0-45-45c-3-3-3-7 0-10l11-11 0 0c2-3 7-3 10 0z m-162-2l0 0 14 0 0 0c4 0 8 3 8 7l0 0 0 64c0 5-3 8-8 8l0 0-14 0 0 0c-5 0-8-3-8-8l0-64 0 0c0-4 4-7 8-7z m220-106c0 4-3 7-7 8l0 0-64 0c-4 0-8-4-8-8l0-15c0-4 4-7 8-7l64 0 0 0c4 0 7 3 7 7z m-213 81c-60 0-109-49-109-109 0-23 8-45 20-63l0 0c17-25 27-59 27-96 2-2 4-4 7-4 0 0 0 0 1 0l0 0 108 0 0 0c0 0 1 0 1 0 3 0 5 2 7 5 0 38 12 73 29 99 11 17 18 37 18 59 0 60-49 109-109 109z m55-336c0 0-1 0-1 0l0 0-108 0 0 0c-1 0-1 0-1 0-4 0-8-3-8-7l0-17c0-5 4-8 8-8 0 0 0 0 1 0l0 0 108 0 0 0c0 0 1 0 1 0 4 0 7 3 7 8l0 17c0 4-3 7-7 7z m0 49c0 0-1 0-1 0l0 0-108 0 0 0c-1 0-1 0-1 0-4 0-7-4-8-8 0 0 0 0 0 0l0-17c0-4 4-8 8-8 0 0 0 0 1 1l0-1 108 0 0 1c0-1 1-1 1-1 4 0 7 4 7 8l0 17c0 4-3 8-7 8z m-197 208l0 0-64 0c-4 0-7-3-7-8l0-14c0-5 3-8 7-8l64 0 0 0c4 0 8 4 8 8l0 14c0 4-4 8-8 8z m-11 109l46-46 0 0c3-2 7-2 10 1l0 0 11 10c2 3 2 8 0 10l0 0-46 46c-2 3-7 3-10 0l-11-11c-2-3-2-7 0-10z"/>
<glyph glyph-name="square" unicode="&#77;" d="M238 219l0-109c0-10-4-19-11-26-7-7-16-11-26-11l-146 0c-10 0-19 4-26 11-7 7-11 16-11 26l0 109c0 10 4 19 11 26 7 7 16 11 26 11l146 0c10 0 19-4 26-11 7-7 11-16 11-26z m0 220l0-110c0-10-4-18-11-26-7-7-16-10-26-10l-146 0c-10 0-19 3-26 10-7 8-11 16-11 26l0 110c0 10 4 18 11 26 7 7 16 10 26 10l146 0c10 0 19-3 26-10 7-8 11-16 11-26z m256-220l0-109c0-10-4-19-11-26-7-7-16-11-26-11l-146 0c-10 0-19 4-26 11-7 7-11 16-11 26l0 109c0 10 4 19 11 26 7 7 16 11 26 11l146 0c10 0 19-4 26-11 7-7 11-16 11-26z m0 220l0-110c0-10-4-18-11-26-7-7-16-10-26-10l-146 0c-10 0-19 3-26 10-7 8-11 16-11 26l0 110c0 10 4 18 11 26 7 7 16 10 26 10l146 0c10 0 19-3 26-10 7-8 11-16 11-26z"/>
<glyph glyph-name="birthday-cake" unicode="&#78;" d="M512 110l0-110-512 0 0 110c9 0 17 1 24 4 8 2 14 5 17 8 4 2 8 6 14 10 5 5 10 9 14 11 4 2 10 3 16 3 7 0 12-1 16-3 4-2 9-6 15-11 6-4 10-8 14-11 3-2 9-5 16-7 8-3 16-4 25-4 8 0 17 1 24 4 8 3 13 5 17 8 3 2 8 6 13 10 4 4 8 6 10 8 2 2 5 3 9 4 3 2 7 2 12 2 7 0 12-1 16-3 4-2 9-6 15-11 5-4 10-8 13-10 4-3 10-6 17-8 8-3 16-4 24-4 9 0 17 1 25 4 7 2 13 5 17 8 3 2 8 6 13 10 6 5 11 9 15 11 4 2 9 3 16 3 6 0 12-1 16-3 4-2 9-6 14-11 6-4 10-8 14-10 3-3 9-6 17-8 7-3 15-4 24-4z m0 91l0-55c-7 0-12 1-16 3-4 3-9 6-15 11-5 5-10 9-13 11-4 3-9 5-17 8-7 3-16 4-24 4-9 0-17-1-25-4-7-3-13-5-16-8-4-2-8-6-14-11-4-3-7-6-9-7-2-2-5-3-9-5-4-1-8-2-13-2-6 0-12 1-16 3-4 3-9 6-14 11-6 5-10 9-14 11-3 3-9 5-16 8-8 3-16 4-25 4-9 0-17-2-24-4-8-3-13-6-17-8-3-2-8-6-14-11-4-3-7-6-9-7-2-2-5-3-9-5-3-1-8-2-12-2-7 0-12 1-16 3-4 3-9 6-15 11-5 5-10 8-13 11-4 3-10 5-17 8-8 3-16 4-25 4-8 0-17-1-24-4-8-3-13-5-17-8-3-2-8-6-13-11-6-5-11-8-15-11-4-2-9-3-16-3l0 55c0 15 5 28 16 39 11 11 24 16 39 16l18 0 0 128 73 0 0-128 73 0 0 128 74 0 0-128 73 0 0 128 73 0 0-128 18 0c15 0 28-5 39-16 11-11 16-24 16-39z m-366 247c0-15-3-26-10-34-7-8-16-12-26-12-10 0-19 4-26 11-7 7-11 16-11 26 0 5 1 10 3 14 2 5 4 8 7 10 2 2 5 5 8 8 4 3 7 6 9 9 3 3 5 7 7 13 2 5 3 12 3 19 7 0 15-7 23-21 9-14 13-29 13-43z m147 0c0-15-4-26-11-34-7-8-15-12-26-12-10 0-19 4-26 11-7 7-11 16-11 26 0 5 1 10 3 14 2 5 4 8 7 10 3 2 5 5 9 8 3 3 6 6 9 9 2 3 4 7 6 13 2 5 3 12 3 19 7 0 15-7 24-21 8-14 13-29 13-43z m146 0c0-15-4-26-10-34-7-8-16-12-27-12-10 0-18 4-26 11-7 7-10 16-10 26 0 5 1 10 2 14 2 5 4 8 7 10 3 2 6 5 9 8 3 3 6 6 9 9 3 3 5 7 7 13 1 5 2 12 2 19 8 0 15-7 24-21 9-14 13-29 13-43z"/>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -139,3 +139,21 @@
.icon-world:before {
content: "\48";
}
.icon-update:before {
content: "\49";
}
.icon-back-in-time:before {
content: "\4a";
}
.icon-bar-chart:before {
content: "\4b";
}
.icon-lightbulb:before {
content: "\4c";
}
.icon-square:before {
content: "\4d";
}
.icon-birthday-cake:before {
content: "\4e";
}

View file

@ -63,6 +63,7 @@ importers:
lorem-ipsum: ^2.0.8
mixpanel-browser: ^2.45.0
mkdirp: ^2.1.3
moment: ^2.29.4
postcss: ^8.4.19
prettier: ^2.7.1
prettier-plugin-svelte: ^2.7.0
@ -109,6 +110,7 @@ importers:
lorem-ipsum: 2.0.8
mixpanel-browser: 2.45.0
mkdirp: 2.1.3
moment: 2.29.4
pushy-electron: 1.0.11
renderer: link:@types/electron/renderer
semver: 7.3.8
@ -10031,6 +10033,10 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
/moment/2.29.4:
resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
dev: false
/mqtt-packet/6.10.0:
resolution: {integrity: sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==}
dependencies: