feat: add common view module
This commit is contained in:
9
gallery/easel/route/view/common/__init__.py
Normal file
9
gallery/easel/route/view/common/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import FastAPI
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
|
||||
def mount(app: FastAPI):
|
||||
base_dir = Path(__file__).parent
|
||||
app.mount("/static/common", StaticFiles(directory=base_dir / "static"))
|
||||
BIN
gallery/easel/route/view/common/static/favicon.ico
Normal file
BIN
gallery/easel/route/view/common/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
76
gallery/easel/route/view/common/static/style.css
Normal file
76
gallery/easel/route/view/common/static/style.css
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
base
|
||||
*/
|
||||
body {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
/*
|
||||
table
|
||||
*/
|
||||
table {
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table,
|
||||
th,
|
||||
td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.1rem 0.4rem;
|
||||
}
|
||||
|
||||
/*
|
||||
a.button
|
||||
*/
|
||||
a.button {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.button.disabled {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
color: gray;
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
/*
|
||||
app
|
||||
*/
|
||||
.app-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
ul.app-list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul.app-list > li {
|
||||
border: 1px solid lightgrey;
|
||||
}
|
||||
|
||||
ul.app-list > li > a {
|
||||
display: block;
|
||||
padding: 0.5rem 2rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul.app-list > li:hover {
|
||||
border-color: blue;
|
||||
}
|
||||
|
||||
ul.app-list > li:hover > a {
|
||||
color: blue;
|
||||
}
|
||||
57
gallery/easel/route/view/common/util.py
Normal file
57
gallery/easel/route/view/common/util.py
Normal file
@@ -0,0 +1,57 @@
|
||||
import datetime
|
||||
from enum import Enum
|
||||
from typing import NamedTuple
|
||||
|
||||
|
||||
class TagType(str, Enum):
|
||||
DAY = "day"
|
||||
DAYS = "days"
|
||||
|
||||
|
||||
class Tag(NamedTuple):
|
||||
type: TagType
|
||||
date: datetime.date
|
||||
days: int = 1
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.type == TagType.DAY:
|
||||
today = datetime.date.today()
|
||||
day = (self.date - today).days
|
||||
return f"day-{day}"
|
||||
elif self.type == TagType.DAYS:
|
||||
return f"days-{self.days}"
|
||||
else:
|
||||
raise ValueError(self.type)
|
||||
|
||||
|
||||
class TagUtil:
|
||||
@classmethod
|
||||
def parse_tag(cls, tag: str) -> Tag:
|
||||
if tag == "today":
|
||||
return Tag(TagType.DAY, datetime.date.today())
|
||||
elif tag == "tomorrow":
|
||||
return Tag(TagType.DAY, datetime.date.today() + datetime.timedelta(days=1))
|
||||
elif tag.startswith("day-"):
|
||||
days = int(tag.split("-")[-1])
|
||||
return Tag(
|
||||
TagType.DAY,
|
||||
datetime.date.today() + datetime.timedelta(days=days),
|
||||
)
|
||||
elif tag.startswith("days-"):
|
||||
days = int(tag.split("-")[-1])
|
||||
return Tag(TagType.DAYS, datetime.date.today(), days)
|
||||
raise ValueError(tag)
|
||||
|
||||
@classmethod
|
||||
def create_tag(
|
||||
cls,
|
||||
tag_type: TagType,
|
||||
date: datetime.date,
|
||||
day: int = 0,
|
||||
days: int = 10,
|
||||
) -> Tag:
|
||||
if tag_type == TagType.DAY:
|
||||
return Tag(tag_type, date + datetime.timedelta(days=day))
|
||||
if tag_type == TagType.DAYS:
|
||||
return Tag(tag_type, date, days)
|
||||
raise ValueError(tag_type)
|
||||
Reference in New Issue
Block a user