Draw a round dashboard in the mosaic as its circle with a dot per face
DashboardSummary carries the dashboard's shape, so the list no longer lays a round dashboard's faces out at grid places they never use.
This commit is contained in:
@@ -598,6 +598,9 @@ class DashboardSummary(BaseModel):
|
||||
version: int = 1
|
||||
#: The grid `footprint` is placed in — see ``DashboardDef.columns``.
|
||||
columns: int = 12
|
||||
#: A round dashboard's widgets are faces rather than tiles, so a list
|
||||
#: draws them as a circle instead of at the grid places they carry.
|
||||
shape: Literal["rect", "round"] = "rect"
|
||||
#: Every widget's shape, so a list can draw the dashboard's outline
|
||||
#: without a document read per tile.
|
||||
footprint: list[WidgetFootprint] = Field(default_factory=list)
|
||||
@@ -666,6 +669,7 @@ class DashboardStore:
|
||||
has_draft=defn.has_draft,
|
||||
version=defn.version,
|
||||
columns=defn.columns,
|
||||
shape=defn.shape,
|
||||
footprint=defn.footprint,
|
||||
updated_at=self.updated_at(name),
|
||||
)
|
||||
|
||||
@@ -415,6 +415,7 @@ def test_a_summary_carries_the_footprint_of_the_document(store: DashboardStore):
|
||||
(summary,) = store.list()
|
||||
|
||||
assert summary.columns == saved.columns
|
||||
assert summary.shape == "rect"
|
||||
assert [(f.type, f.x, f.y, f.w, f.h) for f in summary.footprint] == [
|
||||
("chart", 2, 1, 6, 4),
|
||||
("gauge", 0, 5, 2, 2),
|
||||
@@ -422,6 +423,12 @@ def test_a_summary_carries_the_footprint_of_the_document(store: DashboardStore):
|
||||
]
|
||||
|
||||
|
||||
def test_a_summary_says_a_dashboard_is_round(store: DashboardStore):
|
||||
store.write(DashboardDef(name="knob", shape="round"))
|
||||
|
||||
assert store.list()[0].shape == "round"
|
||||
|
||||
|
||||
def test_a_summary_carries_when_the_working_copy_was_written(store: DashboardStore):
|
||||
published = store.write(default_dashboard("house"))
|
||||
document = store.root / "house" / "dashboard.json"
|
||||
|
||||
@@ -828,6 +828,12 @@ export const DashboardSummarySchema = {
|
||||
title: 'Columns',
|
||||
default: 12
|
||||
},
|
||||
shape: {
|
||||
type: 'string',
|
||||
enum: ['rect', 'round'],
|
||||
title: 'Shape',
|
||||
default: 'rect'
|
||||
},
|
||||
footprint: {
|
||||
items: {
|
||||
'$ref': '#/components/schemas/WidgetFootprint'
|
||||
|
||||
@@ -215,6 +215,7 @@ export type DashboardSummary = {
|
||||
has_draft?: boolean;
|
||||
version?: number;
|
||||
columns?: number;
|
||||
shape?: 'rect' | 'round';
|
||||
footprint?: Array<WidgetFootprint>;
|
||||
updated_at?: (string | null);
|
||||
};
|
||||
|
||||
@@ -65,6 +65,9 @@ function blocksOf(footprint: WidgetFootprint[]): {
|
||||
* dashboard. The summary carries the shapes, so it costs no request either.
|
||||
*/
|
||||
function Footprint({ dashboard }: { dashboard: DashboardSummary }) {
|
||||
if (dashboard.shape === "round") {
|
||||
return <RoundFootprint faces={dashboard.footprint ?? []} />
|
||||
}
|
||||
const { blocks, rows } = blocksOf(dashboard.footprint ?? [])
|
||||
const columns = dashboard.columns || DEFAULT_COLUMNS
|
||||
// Before the editor could place things, every widget was written at 0,0;
|
||||
@@ -112,6 +115,31 @@ function Footprint({ dashboard }: { dashboard: DashboardSummary }) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A round dashboard shows one face at a time, so its grid places mean
|
||||
* nothing: it is drawn as the circle, with a dot per face where a panel puts
|
||||
* its page dots.
|
||||
*/
|
||||
function RoundFootprint({ faces }: { faces: WidgetFootprint[] }) {
|
||||
return (
|
||||
<div
|
||||
aria-hidden
|
||||
className="flex aspect-video items-center justify-center rounded-sm bg-muted p-1"
|
||||
>
|
||||
<div className="relative aspect-square h-full rounded-full border-2 border-primary/45">
|
||||
<div className="absolute inset-x-[15%] bottom-[15%] flex flex-wrap justify-center gap-1">
|
||||
{faces.map((face, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className={cn("size-2 rounded-full", shade(face.type))}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/** One dashboard in the mosaic. */
|
||||
function Tile({
|
||||
dashboard,
|
||||
|
||||
Reference in New Issue
Block a user