Skip to content

Commit

Permalink
tag support in scene history page
Browse files Browse the repository at this point in the history
show tags in the collections page. Add search input to navbar
  • Loading branch information
sdumetz committed Jul 5, 2024
1 parent 3867e8d commit 75af170
Show file tree
Hide file tree
Showing 12 changed files with 560 additions and 114 deletions.
31 changes: 25 additions & 6 deletions source/ui/MainView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,39 @@ import "./composants/navbar/NavLink";
import "./composants/navbar/Navbar";
import "./composants/navbar/UserButton";
import "./composants/navbar/ChangeLocale";
import "./composants/Modal";

import "./screens/List";
import "./screens/Admin";
import "./screens/SceneHistory";
import "./screens/FileHistory";
import "./screens/UserSettings";
import "./screens/Home"
import "./composants/Modal";
import "./screens/Home";
import "./screens/Tags";


import Notification from "./composants/Notification";

import { updateLogin, withUser } from './state/auth';
import Modal from './composants/Modal';
import i18n from './state/translate';
import { route, router } from './state/router';
import { navigate, route, router } from './state/router';


@customElement("ecorpus-main")
export default class MainView extends router(i18n(withUser(LitElement))){
@route()
static "/ui/" =({search})=> html`<home-page .compact=${(search as URLSearchParams).has("compact")}></home-page>`;
@route()
static "/ui/scenes/" =({search})=> html`<corpus-list .compact=${(search as URLSearchParams).has("compact")}></corpus-list>`;
static "/ui/tags/" = ()=>html`<tags-screen></tags-screen>`;
@route()
static "/ui/scenes/" =({search: qs})=> html`<corpus-list .match=${(qs as URLSearchParams).get("search")} .compact=${(qs as URLSearchParams).has("compact")}></corpus-list>`;
@route()
static "/ui/user/" = ()=> html`<user-settings></user-settings>`
@route()
static "/ui/admin/.*" = ()=> html`<admin-panel></admin-panel>`;
@route()
static "/ui/scenes/:id/" = ({parent, params}) => html`<scene-history name="${params.id}"></scene-history>`;
static "/ui/scenes/:id/" = ({params}) => html`<scene-history name="${params.id}"></scene-history>`;

connectedCallback(): void {
super.connectedCallback();
Expand All @@ -48,11 +53,25 @@ export default class MainView extends router(i18n(withUser(LitElement))){
});
}

onSearch = (e:Event)=>{
e.preventDefault();
e.stopPropagation();
const value = (e.target as HTMLInputElement).value;
navigate(this,"/ui/scenes/", {search: value});
}

render() {

return html`
<corpus-navbar>
<nav-link .selected=${this.isActive("/ui/scenes/")} href="/ui/scenes/">Collection</nav-link>
<form class="form-item" style="display:flex; padding-right: 10px;display:flex;align-items: center" >
<span style="height:24px;width:24px;">
<ui-icon style="fill: var(--color-highlight);pointer-events: none;" name="search"></ui-icon>
</span>
<input style="height:calc(100% - 6px);margin-left:-24px; padding-left: 24px" class="search-box-input" name="search" type="search" id="model-search" @input=${this.onSearch} placeholder=${this.t("ui.searchScene")} >
</form>
<nav-link .selected=${this.isActive("/ui/tags/")} href="/ui/tags/">Collections</nav-link>
${(this.user?.isAdministrator)?html`<nav-link .selected=${this.isActive("/ui/admin/")} href="/ui/admin/">${this.t("ui.administration")}</nav-link>`:""}
<div class="divider"></div>
<user-button .selected=${this.isActive("/ui/user/")} .user=${this.user}></user-button>
Expand Down
6 changes: 3 additions & 3 deletions source/ui/composants/Icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ Icon.add("grid", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 5
Icon.add("list", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M64 144a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zM64 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm48-208a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" ></path></svg>`)

Icon.add("edit", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960"><path d="M794 390 666 262l42-42q17-17 42.5-16.5T793 221l43 43q17 17 17 42t-17 42l-42 42ZM150 936q-13 0-21.5-8.5T120 906v-86q0-6 2-11t7-10l495-495 128 128-495 495q-5 5-10 7t-11 2h-86Z"/></svg>`)
Icon.add("admin", html`<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M480.172 606Q537 606 577 565.828q40-40.171 40-97Q617 412 576.828 372q-40.171-40-97-40Q423 332 383 372.172q-40 40.171-40 97Q343 526 383.172 566q40.171 40 97 40ZM480 913q60-20 108-59.5t83-90.5q-44.668-21.022-92.972-32.011Q529.724 720 479.862 720 430 720 381.79 730.989 333.581 741.978 289 763q35 51 83 90.5T480 913Zm0 59q-5.32 0-9.88-1-4.56-1-9.12-3-139-47-220-168.5t-81-266.606V337q0-19.257 10.875-34.662Q181.75 286.932 199 280l260-97q11-4 21-4t21 4l260 97q17.25 6.932 28.125 22.338Q800 317.743 800 337v195.894Q800 678 719 799.5T499 968q-4.56 2-9.12 3t-9.88 1Z"/></svg>`)
Icon.add("search", html`<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M761 929 526 695q-29 22.923-68.459 35.962Q418.082 744 372 744q-115.162 0-195.081-80Q97 584 97 471t80-193q80-80 193.5-80t193 80Q643 358 643 471.15q0 44.85-12.5 83.35Q618 593 593 627l237 235q14 14.442 14 33.721 0 19.279-14.913 33.192Q814.711 944 794.633 944q-20.077 0-33.633-15ZM371.353 650q74.897 0 126.272-52.25T549 471q0-74.5-51.522-126.75T371.353 292q-75.436 0-127.895 52.25Q191 396.5 191 471t52.311 126.75Q295.623 650 371.353 650Z"/></svg>`)
Icon.add("restore", html`<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 96 960 960" width="48"><path d="M477 936q-149 0-253-105.5T120 575h60q0 125 86 213t211 88q127 0 215-89t88-216q0-124-89-209.5T477 276q-68 0-127.5 31T246 389h105v60H142V241h60v106q52-61 123.5-96T477 216q75 0 141 28t115.5 76.5Q783 369 811.5 434T840 574q0 75-28.5 141t-78 115Q684 879 618 907.5T477 936Zm128-197L451 587V373h60v189l137 134-43 43Z"/></svg>`)
Icon.add("admin", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960"><path d="M480.172 606Q537 606 577 565.828q40-40.171 40-97Q617 412 576.828 372q-40.171-40-97-40Q423 332 383 372.172q-40 40.171-40 97Q343 526 383.172 566q40.171 40 97 40ZM480 913q60-20 108-59.5t83-90.5q-44.668-21.022-92.972-32.011Q529.724 720 479.862 720 430 720 381.79 730.989 333.581 741.978 289 763q35 51 83 90.5T480 913Zm0 59q-5.32 0-9.88-1-4.56-1-9.12-3-139-47-220-168.5t-81-266.606V337q0-19.257 10.875-34.662Q181.75 286.932 199 280l260-97q11-4 21-4t21 4l260 97q17.25 6.932 28.125 22.338Q800 317.743 800 337v195.894Q800 678 719 799.5T499 968q-4.56 2-9.12 3t-9.88 1Z"/></svg>`)
Icon.add("search", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960"><path d="M761 929 526 695q-29 22.923-68.459 35.962Q418.082 744 372 744q-115.162 0-195.081-80Q97 584 97 471t80-193q80-80 193.5-80t193 80Q643 358 643 471.15q0 44.85-12.5 83.35Q618 593 593 627l237 235q14 14.442 14 33.721 0 19.279-14.913 33.192Q814.711 944 794.633 944q-20.077 0-33.633-15ZM371.353 650q74.897 0 126.272-52.25T549 471q0-74.5-51.522-126.75T371.353 292q-75.436 0-127.895 52.25Q191 396.5 191 471t52.311 126.75Q295.623 650 371.353 650Z"/></svg>`)
Icon.add("restore", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960"><path d="M477 936q-149 0-253-105.5T120 575h60q0 125 86 213t211 88q127 0 215-89t88-216q0-124-89-209.5T477 276q-68 0-127.5 31T246 389h105v60H142V241h60v106q52-61 123.5-96T477 216q75 0 141 28t115.5 76.5Q783 369 811.5 434T840 574q0 75-28.5 141t-78 115Q684 879 618 907.5T477 936Zm128-197L451 587V373h60v189l137 134-43 43Z"/></svg>`)

Icon.add("stats", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960"><path d="M80 926v-60h800v60H80Zm40-120V536h100v270H120Zm206 0V336h100v470H326Zm207 0V456h100v350H533Zm207 0V216h100v590H740Z"/></svg>`)
Icon.add("users", html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 96 960 960"><path d="m667 936-10-66q-17-5-34.5-14.5T593 834l-55 12-25-42 47-44q-2-9-2-25t2-25l-47-44 25-42 55 12q12-12 29.5-21.5T657 600l10-66h54l10 66q17 5 34.5 14.5T795 636l55-12 25 42-47 44q2 9 2 25t-2 25l47 44-25 42-55-12q-12 12-29.5 21.5T731 870l-10 66h-54ZM80 892v-94q0-35 17.5-63t50.5-43q72-32 133.5-46T400 632h23q-21 51-19 134.5T438 892H80Zm614-77q36 0 58-22t22-58q0-36-22-58t-58-22q-36 0-58 22t-22 58q0 36 22 58t58 22ZM400 571q-66 0-108-42t-42-108q0-66 42-108t108-42q66 0 108 42t42 108q0 66-42 108t-108 42Z"/></svg>`)
Expand Down
27 changes: 20 additions & 7 deletions source/ui/composants/SceneCard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import { AccessType, AccessTypes, Scene } from "../state/withScenes";
let explorer = `/ui/scenes/${encodeURIComponent(this.name)}/view`;
let story = `/ui/scenes/${encodeURIComponent(this.name)}/edit`;
return html`
<div class="scene-card-inner ${this.cardStyle == "list" ? "scene-card-inner-list": ""}" }>
<div class="scene-card-inner ${this.cardStyle == "list" ? "scene-card-inner-list": ""}">
<div style="display:flex; flex:auto; align-items:center;">
<a href="${explorer}">
${this.thumb? html`<img src="${this.thumb}"/>`: html`<img style="background:radial-gradient(circle, #103040 0, #0b0b0b 100%);" src="${defaultSprite}" />`}
Expand All @@ -71,9 +71,18 @@ import { AccessType, AccessTypes, Scene } from "../state/withScenes";
</div>
</div>
<div class="tools">
${this.can("read")? html`<a href="${explorer}"><ui-icon name="eye"></ui-icon>${this.t("ui.view")}</a>`:null}
${this.can("write")? html`<a class="tool-link" href="${story}"><ui-icon name="edit"></ui-icon>${this.t("ui.edit")}</a>`:null}
${this.can("admin")? html`<a class="tool-properties" href="/ui/scenes/${this.name}/" title="propriétés de l'objet"><ui-icon name="admin"></ui-icon>${this.t("ui.admin")}</a>`:null}
${this.can("read")? html`<a href="${explorer}">
<ui-icon name="eye"></ui-icon>
<span class="tool-text">${this.t("ui.view")}</span>
</a>`:null}
${this.can("write")? html`<a class="tool-link" href="${story}">
<ui-icon name="edit"></ui-icon>
<span class="tool-text">${this.t("ui.edit")}</span>
</a>`:null}
${this.can("admin")? html`<a class="tool-properties" href="/ui/scenes/${this.name}/" title="propriétés de l'objet">
<ui-icon name="admin"></ui-icon>
<span class="tool-text">${this.t("ui.admin")}</span>
</a>`:null}
</div>
</div>
${(this.onChange? html`<span class="pill">
Expand All @@ -91,12 +100,13 @@ import { AccessType, AccessTypes, Scene } from "../state/withScenes";
.scene-card-inner{
background-color: var(--color-element);
box-sizing: border-box;
padding: 1rem;
padding: .5rem;
width: 100%;
height: 100%;
border-radius: 4px;
border: 2px solid var(--color-highlight);
transition: background 0.2s;
overflow: hidden;
}
.scene-card-inner:hover{
Expand Down Expand Up @@ -134,23 +144,26 @@ import { AccessType, AccessTypes, Scene } from "../state/withScenes";
}
.tools{
max-width: 100%;
margin-top: 0.5rem;
display:flex;
justify-content: space-around;
overflow: hidden;
}
.scene-card-inner-list .tools{
margin: 0rem;
}
.tools a{
width: 100%;
margin: 2px;
color: #eee;
text-decoration: none;
padding: 0 0.5rem;
min-width: 24px;
display: flex;
justify-content: center;
padding: 0 0.5rem;
flex-wrap: wrap;
}
.tools a:hover{
color: var(--color-secondary-light);
Expand Down
131 changes: 131 additions & 0 deletions source/ui/composants/TagList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { LitElement, css, customElement, html, property } from "lit-element";




@customElement("tag-list")
export default class TagList extends LitElement{
/** List of tag names to display */
@property({attribute: false})
tags :string[] = [];

/** show add/remove elements */
@property({attribute: true, reflect: true, type: Boolean})
editable :boolean;

@property({attribute: false, type: Number})
selected :number;

private onAdd = (e:Event)=>{
e.preventDefault();
e.stopPropagation();
const target = (e.target as HTMLFormElement);
const data = new FormData(target);
this.dispatchEvent(new CustomEvent("add", {detail: data.get("tag")}));
target.reset();
}


private onRemove = (e:Event)=>{
this.dispatchEvent(new CustomEvent("remove", {detail:(e.target as HTMLButtonElement).name}));
}

private onClick = (index :number, ev :Event)=>{
ev.preventDefault();
ev.stopPropagation();
this.dispatchEvent(new CustomEvent("click", {detail: this.tags[index]}));
}

render(){
return html`<div class="tags-list">
${this.tags.map((t, index)=>html`<span @click=${this.onClick.bind(this, index)} class="tag${this.selected=== index?" selected":""}">
<span class="tag-name">${t}</span>
${this.editable? html`<button name=${t} class="tag-delete" @click=${this.onRemove}>×</button>`:null}
</span>`)}
${this.editable? html`<form class="add-tag" @submit=${this.onAdd}>
<input type="text" name="tag" placeholder="add tag" required minlength="1" maxlength="20">
<input type="submit" value="✓">
</form>`: null}
</div>`
}

static styles = css`
.tags-list{
display: flex;
gap: 2px;
}
.tag, .add-tag{
color: white;
padding: .125em;
border-radius: .75em;
border: 1px solid var(--color-secondary);
background: var(--color-highlight);
}
.tag:hover, .tag.selected{
background-color: var(--color-secondary);
}
.tag .tag-name{
padding-left: .375em;
cursor: pointer;
}
.tag .tag-name:last-child{
padding-right: .375em;
}
.tag .tag-delete{
display: inline;
background-color: var(--color-highlight);
color: white;
border: 1px solid transparent;
border-radius: .75em;
padding: 1px 4.5px;
margin: 1px;
box-sizing: border-box;
cursor: pointer;
transition: background-color .1s ease;
}
.tag .tag-delete:hover{
background-color: var(--color-secondary);
border-color: var(--color-secondary-light);
}
.add-tag{
position: relative;
}
.add-tag input{
color: inherit;
border: none;
background: none;
height: 100%;
box-sizing: border-box;
}
.add-tag input:focus-visible{
outline: none;
}
.add-tag input[type="text"]{
max-width:12ch;
}
.add-tag input[type="submit"]{
cursor: pointer;
opacity: 0;
}
.add-tag:valid input[type="submit"]{
opacity: 1;
}
.add-tag input[type="submit"]:hover{
color: var(--color-success);
background-color: var(--color-secondary);
border-radius: .75em;
}
`;
}
2 changes: 1 addition & 1 deletion source/ui/composants/navbar/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ nav {
align-items: stretch;
flex-basis: auto;
justify-content: end;
::slotted(.btn), ::slotted(.nav-link){
::slotted(.btn), ::slotted(.nav-link), ::slotted(.form-item){
height:100%;
flex: 0 0 auto;
box-sizing: border-box;
Expand Down
Loading

0 comments on commit 75af170

Please sign in to comment.