favorites on the sidebar

This commit is contained in:
Ruben Fiszel
2022-11-30 01:47:29 +01:00
parent 751dca0d28
commit b40f9a0475
8 changed files with 58 additions and 23 deletions
+1 -1
View File
@@ -71,5 +71,5 @@ async fn unstar(
.execute(&db)
.await?;
Ok(format!("Starred {}", path))
Ok(format!("Unstarred {}", path))
}
+3 -3
View File
@@ -72,7 +72,7 @@ async fn list_flows(
.left()
.join("favorite")
.on(
"favorite.favorite_kind = 'flow' AND favorite.path = o.path AND favorite.usr = ?"
"favorite.favorite_kind = 'flow' AND favorite.workspace_id = o.workspace_id AND favorite.path = o.path AND favorite.usr = ?"
.bind(&authed.username),
)
.order_desc("favorite.path IS NOT NULL")
@@ -94,8 +94,8 @@ async fn list_flows(
if let Some(cb) = &lq.edited_by {
sqlb.and_where_eq("edited_by", "?".bind(cb));
}
if let Some(so) = &lq.starred_only {
sqlb.and_where_eq("starred", "?".bind(so));
if lq.starred_only.unwrap_or(false) {
sqlb.and_where_is_not_null("favorite.path");
}
let sql = sqlb.sql().map_err(|e| Error::InternalErr(e.to_string()))?;
+3 -3
View File
@@ -102,7 +102,7 @@ async fn list_scripts(
.left()
.join("favorite")
.on(
"favorite.favorite_kind = 'script' AND favorite.path = o.path AND favorite.usr = ?"
"favorite.favorite_kind = 'script' AND favorite.workspace_id = o.workspace_id AND favorite.path = o.path AND favorite.usr = ?"
.bind(&authed.username),
)
.order_desc("favorite.path IS NOT NULL")
@@ -146,8 +146,8 @@ async fn list_scripts(
if let Some(k) = &lq.kind {
sqlb.and_where_eq("kind", "?".bind(&k.to_lowercase()));
}
if let Some(so) = &lq.starred_only {
sqlb.and_where_eq("starred", "?".bind(so));
if lq.starred_only.unwrap_or(false) {
sqlb.and_where_is_not_null("favorite.path");
}
let sql = sqlb.sql().map_err(|e| Error::InternalErr(e.to_string()))?;
+5 -3
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import { FavoriteService } from '$lib/gen'
import { workspaceStore } from '$lib/stores'
import { starStore, workspaceStore } from '$lib/stores'
import { sendUserToast } from '$lib/utils'
import { faStar } from '@fortawesome/free-solid-svg-icons'
import { createEventDispatcher } from 'svelte'
@@ -17,13 +17,15 @@
workspace: $workspaceStore!,
requestBody: { path, favorite_kind: kind }
})
sendUserToast('Marked as favorite, it will appear first in the list')
sendUserToast('Unstarred')
$starStore = $starStore + 1
} else {
await FavoriteService.star({
workspace: $workspaceStore!,
requestBody: { path, favorite_kind: kind }
})
sendUserToast('Marked as favorite, it will appear first in the list')
sendUserToast('Marked as favorite, it will appear first')
$starStore = $starStore + 1
}
dispatch('starred', !starred)
}
@@ -2,7 +2,6 @@
import {
faBookOpen,
faCalendar,
faCode,
faCubes,
faEye,
faHomeAlt,
@@ -10,12 +9,13 @@
faRobot,
faUsersCog,
faWallet,
faWind,
faCog
faCog,
faStar
} from '@fortawesome/free-solid-svg-icons'
import { faDiscord, faGithub } from '@fortawesome/free-brands-svg-icons'
import MenuLink from './MenuLink.svelte'
import { userStore } from '$lib/stores'
import { starStore, userStore, workspaceStore } from '$lib/stores'
import { FlowService, ScriptService } from '$lib/gen'
const mainMenuLinks = [
{ label: 'Home', href: '/', icon: faHomeAlt },
@@ -25,6 +25,8 @@
{ label: 'Resources', href: '/resources', icon: faCubes }
]
export let favoriteLinks = [] as { label: string; href: string }[]
$: secondaryMenuLinks = [
{ label: 'Groups', href: '/groups', icon: faUsersCog },
{ label: 'Audit Logs', href: '/audit_logs', icon: faEye },
@@ -53,17 +55,23 @@
<div class="flex-1 flex flex-col py-4 overflow-x-hidden scrollbar-hidden">
<nav class="h-full flex justify-between flex-col px-2">
<div class="space-y-1 pt-4">
{#each mainMenuLinks as menuLink}
{#each mainMenuLinks as menuLink (menuLink.href)}
<MenuLink class="text-lg" {...menuLink} {isCollapsed} />
{/each}
<div class="h-2" />
<div class="max-h-40 overflow-y-auto flex flex-col space-y-1.5 max-w-xs">
{#each favoriteLinks as menuLink (menuLink.href)}
<MenuLink class="text-xs max-w-xs truncate" {...menuLink} {isCollapsed} icon={faStar} />
{/each}
</div>
<div class="h-2" />
</div>
<div class="space-1-2">
{#each secondaryMenuLinks as menuLink}
{#each secondaryMenuLinks as menuLink (menuLink.href)}
<MenuLink class="text-xs" {...menuLink} {isCollapsed} />
{/each}
<div class="h-8" />
{#each thirdMenuLinks as menuLink}
{#each thirdMenuLinks as menuLink (menuLink.href)}
<MenuLink class="text-xs" {...menuLink} {isCollapsed} />
{/each}
</div>
+1
View File
@@ -20,6 +20,7 @@ export const userStore = writable<UserExt | undefined>(undefined)
export const workspaceStore = writable<string | undefined>(
persistedWorkspace ? String(persistedWorkspace) : undefined
)
export const starStore = writable(1)
export const usersWorkspaceStore = writable<UserWorkspaceList | undefined>(undefined)
export const superadmin = writable<String | false | undefined>(undefined)
export const hubScripts = writable<
+28 -4
View File
@@ -3,13 +3,13 @@
import Icon from 'svelte-awesome'
import UserMenu from '$lib/components/sidebar/UserMenu.svelte'
import { OpenAPI } from '$lib/gen'
import { FlowService, OpenAPI, ScriptService } from '$lib/gen'
import { classNames } from '$lib/utils'
import WorkspaceMenu from '$lib/components/sidebar/WorkspaceMenu.svelte'
import SidebarContent from '$lib/components/sidebar/SidebarContent.svelte'
import '../app.css'
import { superadmin, userStore } from '$lib/stores'
import { starStore, superadmin, userStore, workspaceStore } from '$lib/stores'
import CenteredModal from '$lib/components/CenteredModal.svelte'
import { beforeNavigate, goto } from '$app/navigation'
import UserSettings from '$lib/components/UserSettings.svelte'
@@ -34,6 +34,30 @@
let innerWidth = window.innerWidth
let favoriteLinks = [] as { label: string; href: string }[]
$: $workspaceStore && $starStore && loadFavorites()
async function loadFavorites() {
const scripts = await ScriptService.listScripts({
workspace: $workspaceStore ?? '',
starredOnly: true
})
const flows = await FlowService.listFlows({
workspace: $workspaceStore ?? '',
starredOnly: true
})
favoriteLinks = [
...scripts.map((s) => ({
label: s.summary || s.path,
href: `/scripts/run/${s.hash}`
})),
...flows.map((f) => ({
label: f.summary || f.path,
href: `/flows/run/${f.path}`
}))
]
}
$: innerWidth < 1248 && innerWidth >= 768 && (isCollapsed = true)
$: (innerWidth >= 1248 || innerWidth < 768) && (isCollapsed = false)
</script>
@@ -116,7 +140,7 @@
/>
</div>
<SidebarContent {isCollapsed} />
<SidebarContent {favoriteLinks} {isCollapsed} />
</div>
</div>
</div>
@@ -155,7 +179,7 @@
{isCollapsed}
/>
</div>
<SidebarContent {isCollapsed} />
<SidebarContent {favoriteLinks} {isCollapsed} />
<div class="flex-shrink-0 flex px-4 pb-3.5 pt-3 border-t border-gray-300">
<button
+1 -1
View File
@@ -334,7 +334,7 @@
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2 mt-2 w-full">
{#if !loading}
{#each filter != '' ? filteredItems : preFilteredItems as item (item.path)}
{#each filter != '' ? filteredItems : preFilteredItems as item (item.type + item.path)}
{#if item.type == 'script'}
<ScriptBox
starred={item.starred}