Commit a30fc769 authored by StreatCodes's avatar StreatCodes
Browse files

Add static text

fix crash when a static/check can't be found
Render static content
parent d239feb9
......@@ -5,6 +5,9 @@ import { useEffect, useReducer } from 'preact/hooks';
import { SidePanelChecks, CheckSettings } from './check-settings';
import { SidePanelStatics, StaticSettings } from './static-settings';
import { CardElement } from './elements/card';
import { removeParam } from './util';
import { StaticText } from './statics/text';
//Manage dashboard state
const dashboardReducer = (state, action) => {
......@@ -79,6 +82,10 @@ export function Editor({slug, selectedCheckId, selectedStaticId}) {
}
const selectedCheck = selectedCheckId ? dashboard.checks[selectedCheckId] : null;
if(typeof selectedCheck === 'undefined') {
removeParam('selectedCheckId');
return
}
const updateCheck = check => {
dashboardDispatch({
type: 'updateCheck',
......@@ -88,6 +95,10 @@ export function Editor({slug, selectedCheckId, selectedStaticId}) {
}
const selectedStatic = selectedStaticId ? dashboard.statics[selectedStaticId] : null;
if(typeof selectedStatic === 'undefined') {
removeParam('selectedStaticId');
return
}
const updateStatic = s => {
dashboardDispatch({
type: 'updateStatic',
......@@ -98,7 +109,8 @@ export function Editor({slug, selectedCheckId, selectedStaticId}) {
return <Fragment>
<DashboardView slug={slug} dashboard={dashboard} dashboardDispatch={dashboardDispatch}
selectedCheckId={selectedCheckId ? Number(selectedCheckId) : null} />
selectedCheckId={selectedCheckId ? Number(selectedCheckId) : null}
selectedStaticId={selectedStaticId ? Number(selectedStaticId) : null} />
<div class="editor">
<div class="options">
......@@ -211,9 +223,8 @@ function TransformableElement({rect, updateRect, children, glow}) {
</div>
}
//The actual dashboard being rendered
function DashboardView({dashboard, dashboardDispatch, selectedCheckId, slug}) {
const checks = dashboard.checks.map((check, index) => {
function DashboardChecks({dashboardDispatch, selectedCheckId, checks}) {
return checks.map((check, index) => {
const updateRect = rect => {
dashboardDispatch({
type: 'updateCheck',
......@@ -234,11 +245,37 @@ function DashboardView({dashboard, dashboardDispatch, selectedCheckId, slug}) {
}
return <TransformableElement rect={check.rect} updateRect={updateRect}
checkId={check.id} glow={selectedCheckId === index}>
glow={selectedCheckId === index}>
{element}
</TransformableElement>
});
}
function DashboardStatics({dashboardDispatch, selectedStaticId, statics}) {
return statics.map((static_, index) => {
const updateRect = rect => {
dashboardDispatch({
type: 'updateStatic',
staticIndex: index,
static: {
...static_,
rect: rect
}
});
}
let element = null;
if(static_.type === 'text') { element = <StaticText options={static_.options}/> }
return <TransformableElement rect={static_.rect} updateRect={updateRect}
glow={selectedStaticId === index}>
{element}
</TransformableElement>
});
}
//The actual dashboard being rendered
function DashboardView({dashboard, dashboardDispatch, selectedCheckId, selectedStaticId, slug}) {
const saveDashboard = async e => {
console.log(dashboard);
try {
......@@ -263,7 +300,10 @@ function DashboardView({dashboard, dashboardDispatch, selectedCheckId, slug}) {
<button onClick={saveDashboard}>Save Dashboard</button>
</div>
<div class="dashboard" style={{backgroundImage: backgroundImage}}>
{checks}
<DashboardStatics statics={dashboard.statics} selectedStaticId={selectedStaticId}
dashboardDispatch={dashboardDispatch} />
<DashboardChecks checks={dashboard.checks} selectedCheckId={selectedCheckId}
dashboardDispatch={dashboardDispatch} />
</div>
</div>
}
......
......@@ -4,6 +4,7 @@ import { useState, useEffect } from 'preact/hooks';
import { svgList } from './svg-list';
import { routeParam, removeParam } from './util';
import { route } from 'preact-router';
import { StaticTextOptions } from './statics/text';
function StaticListPanel({statics, addStatic}) {
if(statics.length < 1) {
......@@ -24,18 +25,6 @@ function StaticListPanel({statics, addStatic}) {
</div>
}
function TextOptions({options, updateOptions}) {
return <Fragment>
<label for="text">Text</label>
<input id="text" name="text" type="text" value={options.text}
onInput={e => updateOptions({text: e.currentTarget.value})}/>
<label for="font-size">Font Size</label>
<input id="font-size" name="font-size" type="number" min="0" value={options.statusFontSize}
onInput={e => updateOptions({statusFontSize: e.currentTarget.value})}/>
</Fragment>
}
function SVGOptions({options, updateOptions}) {
const svgOptions = svgList.map(svgName => <option>{svgName}</option>)
......@@ -77,7 +66,7 @@ export function StaticSettings({selectedStatic, updateStatic}) {
}
const staticTypeOptions = {
'text': <TextOptions updateOptions={updateOptions} options={selectedStatic.options} />,
'text': <StaticTextOptions updateOptions={updateOptions} options={selectedStatic.options} />,
'svg': <SVGOptions updateOptions={updateOptions} options={selectedStatic.options} />,
'image': <ImageOptions updateOptions={updateOptions} options={selectedStatic.options} />,
}
......
import { h, Fragment } from 'preact';
import { useState, useEffect } from 'preact/hooks';
export function StaticTextOptions({options, updateOptions}) {
return <Fragment>
<label for="text">Text</label>
<textarea id="text" name="text" value={options.text}
onInput={e => updateOptions({text: e.currentTarget.value})}>
</textarea>
<label for="font-size">Font Size</label>
<input id="font-size" name="font-size" type="number" min="0" value={options.fontSize}
onInput={e => updateOptions({fontSize: e.currentTarget.value})}/>
<label>Text Alignment</label>
<div class="selection" style="margin-bottom: 5px;">
<button class={`selector ${options.textAlign === 'start' ? 'active' : ''}`}
onClick={e => updateOptions({textAlign: 'start'})}>Left</button>
<button class={`selector ${options.textAlign === 'center' ? 'active' : ''}`}
onClick={e => updateOptions({textAlign: 'center'})}>Center</button>
<button class={`selector ${options.textAlign === 'end' ? 'active' : ''}`}
onClick={e => updateOptions({textAlign: 'end'})}>Right</button>
</div>
<div class="selection spacer">
<button class={`selector ${options.textVerticalAlign === 'start' ? 'active' : ''}`}
onClick={e => updateOptions({textVerticalAlign: 'start'})}>Top</button>
<button class={`selector ${options.textVerticalAlign === 'center' ? 'active' : ''}`}
onClick={e => updateOptions({textVerticalAlign: 'center'})}>Middle</button>
<button class={`selector ${options.textVerticalAlign === 'end' ? 'active' : ''}`}
onClick={e => updateOptions({textVerticalAlign: 'end'})}>Bottom</button>
</div>
<label for="font-color">Font Color</label>
<div class="lefty-righty spacer">
<input id="font-color" name="font-color" type="color" value={options.fontColor}
onInput={e => updateOptions({fontColor: e.currentTarget.value})}/>
<input type="text" value={options.fontColor} disabled/>
</div>
<label for="background-color">Background Color</label>
<div class="lefty-righty spacer">
<input id="background-color" name="background-color" type="color" value={options.backgroundColor}
onInput={e => updateOptions({backgroundColor: e.currentTarget.value})}/>
<input type="text" value={options.backgroundColor} disabled/>
</div>
</Fragment>
}
export function StaticText({options}) {
let styles = '';
if(typeof options.fontSize !== 'undefined') {
styles += `font-size: ${options.fontSize}px; `;
}
if(typeof options.backgroundColor !== 'undefined') {
styles += `background-color: ${options.backgroundColor}; `;
}
if(typeof options.fontColor !== 'undefined') {
styles += `color: ${options.fontColor}; `;
}
if(typeof options.textAlign !== 'undefined') {
styles += `justify-content: ${options.textAlign}; `;
}
if(typeof options.textVerticalAlign !== 'undefined') {
styles += `align-items: ${options.textVerticalAlign}; `;
}
return <div class="check-content text" style={styles}>
{options.text}
</div>
}
\ No newline at end of file
......@@ -169,7 +169,7 @@ label {
font-weight: bold;
}
label~input, label~select {
label~input, label~select, label~textarea {
margin-bottom: 15px;
}
......@@ -227,7 +227,7 @@ div.small.loading::before {
height: 10px;
}
input, select {
input, select, textarea {
width: 100%;
padding: 8px;
border-radius: 3px;
......@@ -235,6 +235,11 @@ input, select {
transition: 300ms border-color;
}
textarea {
resize: vertical;
min-height: 80px;
}
input:focus, select:focus {
border-color: var(--color-blue);
}
......@@ -261,6 +266,42 @@ input::placeholder {
opacity: 1;
}
div.selection {
display: flex;
font-size: 15px;
}
label~div.selection {
margin-bottom: 15px;
}
div.selection > .selector {
padding: 4px 8px;
background-color: white;
border: solid 1.5px var(--color-gray);
border-left: 0;
cursor: pointer;
color: var(--color-black);
border-radius: 0;
}
div.selection > .selector:hover {
background-color: #eee;
}
div.selection > .selector.active {
background-color: var(--color-light-orange);
color: white;
}
div.selection > .selector:first-child {
border-radius: 3px 0 0 3px;
border: solid 1.5px var(--color-gray);
}
div.selection > .selector:last-child {
border-radius: 0 3px 3px 0;
}
/* COPY SELECTION BOX */
div.copy-box {
position: relative;
......@@ -461,6 +502,11 @@ div.editor {
height: 100%;
}
.check > .text {
white-space: pre;
display: flex;
}
.check > .card {
padding: 6px 10px;
text-align: center;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment