diff --git a/source/ui/screens/List.ts b/source/ui/screens/List.ts index a3f6ed60..5e861094 100644 --- a/source/ui/screens/List.ts +++ b/source/ui/screens/List.ts @@ -14,19 +14,12 @@ import { UserSession, withUser } from "../state/auth"; import { repeat } from "lit-html/directives/repeat"; import "../composants/TaskButton"; -import { withScenes, Scene } from "../state/withScenes"; +import { withScenes, Scene, sorts, OrderBy } from "../state/withScenes"; interface Upload{ name :string; } -type SortOrder = "alphabet"|"ctime"|"mtime"; -const sorts:Record[0]> = { - ctime: (a, b) => new Date(b.ctime).valueOf() - new Date(a.ctime).valueOf(), - alphabet: (a, b) => a.name.localeCompare(b.name), - mtime: (a, b) => new Date(b.mtime).valueOf() - new Date(a.mtime).valueOf(), -}; -const sortNames = Object.keys(sorts) as SortOrder[]; /** * Main UI view for the Voyager Explorer application. @@ -48,8 +41,6 @@ const sortNames = Object.keys(sorts) as SortOrder[]; @property({type: Array, attribute: false}) selection = []; - @property({type: String, reflect: true}) - sort:SortOrder = sortNames[0]; get isUser(){ return (this.user && !this.user.isDefaultUser); @@ -89,7 +80,7 @@ const sortNames = Object.keys(sorts) as SortOrder[]; } this.uploads = {...this.uploads, [sceneName]: {progress:0, done: false}}; - this.sort = "ctime"; + this.orderBy = "mtime"; (async ()=>{ let xhr = new XMLHttpRequest(); xhr.onload = function onUploadDone(){ @@ -143,11 +134,23 @@ const sortNames = Object.keys(sorts) as SortOrder[]; } let mode = (this.user?"write":"read"); - if(!this.list){ - return html`
`; - } + let listContent = html` + ${(this.list?.length == 0 && Object.keys(this.uploads).length == 0)? + html`

No scenes available

`: + repeat([ + ...Object.keys(this.uploads).map(name=>({ + key: name, + name: `Uploading ${name}: ${this.uploads[name].progress}%`, + thumb: spinnerImage, + })), + ...(this.list ??[]), + ],(i)=>(i as any).key ?? i.name , (scene)=>this.renderScene(mode, scene)) + } + ${this.list? null: html`
`} + `; + + - let sortedList = this.list.sort(sorts[this.sort]); return html`
@@ -179,22 +182,12 @@ const sortNames = Object.keys(sorts) as SortOrder[];
${this.t("ui.sortBy")}
- ${(sortedList.length == 0 && Object.keys(this.uploads).length == 0)? - html`

No scenes available

`: - repeat([ - ...Object.keys(this.uploads).map(name=>({ - key: name, - name: `Uploading ${name}: ${this.uploads[name].progress}%`, - thumb: spinnerImage, - })), - ...sortedList, - ],(i)=>(i as any).key ?? i.name , (scene)=>this.renderScene(mode, scene)) - } + ${listContent} ${this.dragover ?html`
Drop item here
`:""}
@@ -246,7 +239,8 @@ const sortNames = Object.keys(sorts) as SortOrder[]; } onSelectOrder = (ev)=>{ + console.log("Select order : ", ev.target.value); let value = ev.target.value; - this.sort = value as SortOrder; + this.orderBy = value as OrderBy; } } \ No newline at end of file diff --git a/source/ui/state/strings.ts b/source/ui/state/strings.ts index 926dcd2e..103bbf7f 100644 --- a/source/ui/state/strings.ts +++ b/source/ui/state/strings.ts @@ -187,7 +187,7 @@ export default { fr: "renommer", en: "rename" }, - alphabet:{ + name:{ fr: "ordre alphabethique", en: "alphabetical" }, diff --git a/source/ui/state/withScenes.ts b/source/ui/state/withScenes.ts index 564309b8..c0e7cf7d 100644 --- a/source/ui/state/withScenes.ts +++ b/source/ui/state/withScenes.ts @@ -33,11 +33,19 @@ export const AccessTypes = [ export type AccessType = null|"none"|"read"|"write"|"admin"; +export const sorts = ["mtime", "name", "ctime"] as const; +export type OrderBy = typeof sorts[number]; + +export const directions = ["desc", "asc"] as const; +export type OrderDirection = typeof directions[number]; + export declare class SceneView{ list : Scene[]; access ?:Array; match ?:string; + orderBy :OrderBy; + orderDirection :OrderDirection; fetchScenes():Promise; } @@ -50,19 +58,45 @@ export function withScenes>(baseClass:T) : T & access ?:Array; + @property({type: String, reflect: true}) match ?:string; + + @property({type: String, reflect: true}) + orderBy :OrderBy = sorts[0]; + + @property({type: String, reflect: true}) + orderDirection :OrderDirection = directions[0]; public connectedCallback(): void { super.connectedCallback(); this.fetchScenes(); } + protected update(changedProperties: Map): void { + if(changedProperties.has("orderBy")){ + this.orderDirection = (this.orderBy === "name" ? "asc" : "desc"); + } + + if(changedProperties.has("orderBy") || changedProperties.has("match") || changedProperties.has("orderDirection")){ + this.list = null; + this.fetchScenes(); + } + + super.update(changedProperties); + } + + async fetchScenes(){ this.#loading.abort(); this.#loading = new AbortController(); + let url = new URL("/api/v1/scenes", window.location.href); + url.searchParams.set("orderBy", this.orderBy); + url.searchParams.set("orderDirection", this.orderDirection); + if(this.match) url.searchParams.set("match", this.match); if(this.access?.length) this.access.forEach(a=>url.searchParams.append("access", a)); + url.searchParams.set("limit", "100"); fetch(url, {signal: this.#loading.signal}).then(async (r)=>{ if(!r.ok) throw new Error(`[${r.status}]: ${r.statusText}`);