Compare commits
2 Commits
1d527de26f
...
f47ab32d68
| Author | SHA1 | Date | |
|---|---|---|---|
| f47ab32d68 | |||
| 396ad5b3c9 |
244
app.js
244
app.js
@ -1,32 +1,8 @@
|
|||||||
/** @import * as TYPES from "./graph/types.ts" */
|
/** @import * as TYPES from "./graph/types.ts" */
|
||||||
import * as FSHandle from "./store-directory-handle.js";
|
import * as FSHandle from "./store-directory-handle.js";
|
||||||
|
|
||||||
const {Div, DOM} = Gale({
|
import Styles from "./styles.js";
|
||||||
Title:{
|
const {DOM, Div, Tag} = Styles;
|
||||||
padding:"2rem",
|
|
||||||
background: "blue",
|
|
||||||
color:"white"
|
|
||||||
},
|
|
||||||
Plain:{},
|
|
||||||
PartGroup:{
|
|
||||||
display: `flex`,
|
|
||||||
flexWrap: `wrap`
|
|
||||||
},
|
|
||||||
Part:{
|
|
||||||
border: `1px solid black`,
|
|
||||||
borderRadius: `5px`,
|
|
||||||
padding: `1rem`
|
|
||||||
},
|
|
||||||
BlockScreen:{
|
|
||||||
position: "fixed",
|
|
||||||
zIndex: "9999",
|
|
||||||
top: "0",
|
|
||||||
left: "0",
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
background: "rgba(128, 128, 128, 0.5)"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
async function PickHandle()
|
async function PickHandle()
|
||||||
{
|
{
|
||||||
@ -44,11 +20,21 @@ async function LoadHandleFiles()
|
|||||||
const module = await import("./graph/room.js"+"?bust="+Math.random());
|
const module = await import("./graph/room.js"+"?bust="+Math.random());
|
||||||
/** @type {Record<string, TYPES.GraphParts>} */
|
/** @type {Record<string, TYPES.GraphParts>} */
|
||||||
const read = module.default();
|
const read = module.default();
|
||||||
|
|
||||||
|
for(const roomKey in read)
|
||||||
|
{
|
||||||
|
const room = read[roomKey]
|
||||||
|
for(const pass in room.Pass)
|
||||||
|
{
|
||||||
|
await room.Pass[pass].load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rooms.val = read;
|
rooms.val = read;
|
||||||
}
|
}
|
||||||
catch(_e)
|
catch(e)
|
||||||
{
|
{
|
||||||
console.log("the handle exists, but the request failed. the service work must not be ready yet.")
|
console.log("the handle exists, but the request failed. the service work must not be ready yet.", e)
|
||||||
rooms.val = {};
|
rooms.val = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,73 +57,87 @@ const loggedIn = van.state(false);
|
|||||||
|
|
||||||
const blocking = van.state(false);
|
const blocking = van.state(false);
|
||||||
|
|
||||||
const showDesks = van.state(true);
|
const showDesks = van.state(true, "desks");
|
||||||
|
|
||||||
/** @type {(inParts:Record<string, TYPES.Part>)=>HTMLElement} */
|
function Input(handler=(str)=>{})
|
||||||
function Parts(inParts)
|
|
||||||
{
|
{
|
||||||
return Div.Plain(
|
const input = DOM.textarea({style:"vertical-align:text-top; width:500px; height:200px;"});
|
||||||
Div.Plain("Parts"),
|
|
||||||
Div.PartGroup(
|
let submitButton = Div.Plain(DOM.button({onclick(){
|
||||||
|
handler(input.value);
|
||||||
|
input.value = "";
|
||||||
|
mountPoint.remove();
|
||||||
|
}}, "submit value"));
|
||||||
|
|
||||||
|
let cancelButton = DOM.button({onclick(){
|
||||||
|
input.value = "";
|
||||||
|
mountPoint.remove();
|
||||||
|
}}, "cancel")
|
||||||
|
|
||||||
|
const mountPoint = Div.Plain({onclick(e){e.stopPropagation();}}, input, cancelButton, submitButton);
|
||||||
|
return mountPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {(inParts:Record<string, TYPES.Part>, inPasses:Record<string, TYPES.Pass>)=>HTMLElement} */
|
||||||
|
function Parts(inParts, inPasses)
|
||||||
|
{
|
||||||
|
const rows = [];
|
||||||
|
|
||||||
|
const row = [DOM.th()]
|
||||||
|
for(const pass in inPasses)
|
||||||
|
{
|
||||||
|
row.push(DOM.th(inPasses[pass].name));
|
||||||
|
}
|
||||||
|
rows.push(DOM.thead(row));
|
||||||
|
|
||||||
Object.entries(inParts).map(([part_id, part])=>{
|
Object.entries(inParts).map(([part_id, part])=>{
|
||||||
|
|
||||||
const work = []
|
const row = [DOM.th(part.name)];
|
||||||
for(const [pass, data] of part.pass)
|
for(const [pass, data] of part.pass)
|
||||||
{
|
{
|
||||||
|
row.push(DOM.td.Part(data.work.map(w=>Div.Plain(w[1]) )))
|
||||||
work.push(Div.Part(
|
}
|
||||||
DOM.h5(pass.name),
|
rows.push(DOM.tr(row))
|
||||||
DOM.p(data.time),
|
|
||||||
data.work.map(([time, data, user])=>Div.Plain(
|
|
||||||
DOM.span(time),
|
|
||||||
" ",
|
|
||||||
DOM.strong(data),
|
|
||||||
)),
|
|
||||||
Div.Plain(
|
|
||||||
loggedIn.val ? DOM.button({onclick(){
|
|
||||||
blocking.val = true;
|
|
||||||
loggedIn.val && data.make(loggedIn.val, "NEW").then(()=>{
|
|
||||||
blocking.val = false;
|
|
||||||
});
|
});
|
||||||
}}, "Add work!")
|
|
||||||
: null
|
return DOM.table.GapVertical(rows);
|
||||||
)
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Div.Part(
|
const deskRender = van.state(0);
|
||||||
DOM.h3(part.name),
|
|
||||||
...work,
|
|
||||||
);
|
|
||||||
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {(inDesks:Record<string, TYPES.Desk>)=>HTMLElement} */
|
/** @type {(inDesks:Record<string, TYPES.Desk>)=>HTMLElement} */
|
||||||
function Desks(inDesks)
|
function Desks(inDesks)
|
||||||
{
|
{
|
||||||
return Div.Plain(
|
|
||||||
Div.Plain("Desks"),
|
|
||||||
Div.PartGroup(
|
|
||||||
|
return Div.PartGroup(
|
||||||
Object.entries(inDesks).map(([desk_id, desk])=>{
|
Object.entries(inDesks).map(([desk_id, desk])=>{
|
||||||
|
|
||||||
loggedIn.val;
|
loggedIn.val;
|
||||||
|
|
||||||
|
deskRender.val;
|
||||||
|
console.log("reredering desk", desk.name);
|
||||||
|
|
||||||
if (loggedIn.val)
|
if (loggedIn.val)
|
||||||
{
|
{
|
||||||
|
let userInRole = false;
|
||||||
for(const role of desk.role)
|
for(const role of desk.role)
|
||||||
{
|
{
|
||||||
if(!role.user.includes(loggedIn.val))
|
if(role.user.includes(loggedIn.val))
|
||||||
|
{
|
||||||
|
userInRole = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!userInRole)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {(part:TYPES.Part, index:number, pass:TYPES.Pass, dirty:number[])=>HTMLElement|null} */
|
|
||||||
const Iterator = (part, index, pass, dirty)=>{
|
/** @type {(part:TYPES.Part, index:number, pass:TYPES.Pass, dirty:number[], type:"need"|"make")=>HTMLElement|null} */
|
||||||
|
const Iterator = (part, index, pass, dirty, type)=>{
|
||||||
|
|
||||||
const partPass = part.pass.get(pass);
|
const partPass = part.pass.get(pass);
|
||||||
if(partPass)
|
if(partPass)
|
||||||
@ -145,11 +145,35 @@ function Desks(inDesks)
|
|||||||
const time = partPass.time;
|
const time = partPass.time;
|
||||||
const latest = partPass.work.find(t=>t[0] == time);
|
const latest = partPass.work.find(t=>t[0] == time);
|
||||||
|
|
||||||
return Div.Plain(
|
const attributes = {
|
||||||
part.name,
|
class: dirty.includes(index) ? Tag("DeskDirty") : "",
|
||||||
DOM.p( dirty.includes(index) ? "Dirty" : "Good!" ),
|
};
|
||||||
|
|
||||||
|
if(type == "make")
|
||||||
|
{
|
||||||
|
attributes.onclick=function(){
|
||||||
|
loggedIn.rawVal && van.add(this, Input((str)=>{
|
||||||
|
if(loggedIn.rawVal)
|
||||||
|
{
|
||||||
|
blocking.val = true;
|
||||||
|
partPass.make(loggedIn.rawVal, str).then(()=>{
|
||||||
|
deskRender.val++;
|
||||||
|
blocking.val = false;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DOM.td(
|
||||||
Div.Part(
|
Div.Part(
|
||||||
time, " ", latest?.[1] || ""
|
attributes,
|
||||||
|
latest?.[1] || ""
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -159,29 +183,30 @@ function Desks(inDesks)
|
|||||||
const work = [];
|
const work = [];
|
||||||
for(const [pass, dirty] of desk.pass)
|
for(const [pass, dirty] of desk.pass)
|
||||||
{
|
{
|
||||||
|
work.push(DOM.tr(
|
||||||
work.push(Div.Part(
|
DOM.td(pass.name),
|
||||||
DOM.h5(pass.name),
|
desk.need.map((part, index)=>Iterator(part, index, pass, dirty.need, "need")),
|
||||||
Div.Part(
|
DOM.td("->"),
|
||||||
DOM.h4("Need:"),
|
desk.make.map((part, index)=>Iterator(part, index, pass, dirty.make, "make"))
|
||||||
desk.need.map((part, index)=>Iterator(part, index, pass, dirty.need))
|
|
||||||
),
|
|
||||||
Div.Part(
|
|
||||||
DOM.h4("Make:"),
|
|
||||||
desk.make.map((part, index)=>Iterator(part, index, pass, dirty.make))
|
|
||||||
)
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
return Div.Part(
|
return Div.DeskContainer(
|
||||||
DOM.h3(desk.name),
|
DOM.h3(desk.name),
|
||||||
|
DOM.table.GapHorizontal(
|
||||||
|
DOM.thead(
|
||||||
|
DOM.th(),
|
||||||
|
desk.need.map((part, index)=>DOM.th(part.name)),
|
||||||
|
DOM.th(),
|
||||||
|
desk.make.map((part, index)=>DOM.th(part.name))
|
||||||
|
),
|
||||||
work
|
work
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {(room_id:string, graphParts:TYPES.GraphParts)=>HTMLElement} */
|
/** @type {(room_id:string, graphParts:TYPES.GraphParts)=>HTMLElement} */
|
||||||
@ -211,29 +236,30 @@ function Room(room_id, graphParts)
|
|||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|
||||||
Div.Plain("Passes:"),
|
|
||||||
Div.PartGroup(
|
|
||||||
Object.entries(graphParts.Pass).map(([pass_id, pass])=>{
|
|
||||||
return ()=>{
|
|
||||||
console.log("rerendering...", rerender.rawVal);
|
|
||||||
|
|
||||||
rerender.val;
|
// Div.Plain("Passes:"),
|
||||||
|
// Div.PartGroup(
|
||||||
return Div.Part(
|
// Object.entries(graphParts.Pass).map(([pass_id, pass])=>{
|
||||||
DOM.div.Plain(pass.name),
|
// return ()=>{
|
||||||
()=>{
|
// console.log("rerendering...", rerender.rawVal);
|
||||||
return DOM.button.Plain(
|
//
|
||||||
{async onclick(){
|
// rerender.val;
|
||||||
await pass[pass.live ? "dump" : "load"]();
|
//
|
||||||
rerender.val++
|
// return Div.Part(
|
||||||
}},
|
// DOM.div.Plain(pass.name),
|
||||||
pass.live ? "Dump" : "Load"
|
// ()=>{
|
||||||
)
|
// return DOM.button.Plain(
|
||||||
},
|
// {async onclick(){
|
||||||
)
|
// await pass[pass.live ? "dump" : "load"]();
|
||||||
}
|
// rerender.val++
|
||||||
})
|
// }},
|
||||||
),
|
// pass.live ? "Dump" : "Load"
|
||||||
|
// )
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// ),
|
||||||
|
|
||||||
()=>{
|
()=>{
|
||||||
return DOM.button({onclick(){
|
return DOM.button({onclick(){
|
||||||
@ -243,7 +269,7 @@ function Room(room_id, graphParts)
|
|||||||
|
|
||||||
()=>{
|
()=>{
|
||||||
rerender.val;
|
rerender.val;
|
||||||
return showDesks.val ? Desks(graphParts.Desk) : Parts(graphParts.Part);
|
return showDesks.val ? Desks(graphParts.Desk) : Parts(graphParts.Part, graphParts.Pass);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,19 @@
|
|||||||
//@ts-check
|
//@ts-check
|
||||||
import Rooms, {Room} from "../../graph/graph.js";
|
import CreateAllRooms, {Room} from "../../graph/graph.js";
|
||||||
import User from "./user.js";
|
|
||||||
|
|
||||||
export default Rooms({
|
const user = {
|
||||||
|
u1:"Seth Trowbridge",
|
||||||
|
u4:"Sarah Sharp",
|
||||||
|
u5:"Adam Marshall",
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreateAllRooms({
|
||||||
room_01:Room({
|
room_01:Room({
|
||||||
user:User,
|
user,
|
||||||
role:{
|
role:{
|
||||||
dev:["Development", "u1"],
|
dev:["Development", "u1"],
|
||||||
write:["Writing", "u2", "u3"],
|
write:["Writing", "u5"],
|
||||||
|
admin:["Admin", "u4"]
|
||||||
},
|
},
|
||||||
part:{
|
part:{
|
||||||
p1:"Page title",
|
p1:"Page title",
|
||||||
@ -15,8 +21,8 @@ export default Rooms({
|
|||||||
p3:"Page preview",
|
p3:"Page preview",
|
||||||
},
|
},
|
||||||
desk:{
|
desk:{
|
||||||
d1:["Write page metas", ["write"], "all", {}, "p1", "p2"],
|
d1:["Write page metas", ["admin", "write"], "all", {}, "p1", "p2"],
|
||||||
d2:["Build Page preview", ["dev"], "all", {p1:1, p2:1}, "p3"]
|
d2:["Build Page preview", ["admin", "dev"], "all", {p1:1, p2:1}, "p3" ]
|
||||||
},
|
},
|
||||||
pass:{
|
pass:{
|
||||||
pass_01:["January"],
|
pass_01:["January"],
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
export default {
|
|
||||||
u1:"seth",
|
|
||||||
u2:"seth2",
|
|
||||||
u3:"seth3"
|
|
||||||
}
|
|
||||||
43
styles.js
Normal file
43
styles.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
export default Gale({
|
||||||
|
Title:{
|
||||||
|
padding:"2rem",
|
||||||
|
background: "blue",
|
||||||
|
color:"white"
|
||||||
|
},
|
||||||
|
Plain:{},
|
||||||
|
PartGroup:{
|
||||||
|
display: `flex`,
|
||||||
|
flexWrap: `wrap`
|
||||||
|
},
|
||||||
|
Part:{
|
||||||
|
border: `1px solid black`,
|
||||||
|
borderRadius: `5px`,
|
||||||
|
padding: `1rem`
|
||||||
|
},
|
||||||
|
BlockScreen:{
|
||||||
|
position: "fixed",
|
||||||
|
zIndex: "9999",
|
||||||
|
top: "0",
|
||||||
|
left: "0",
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
background: "rgba(128, 128, 128, 0.5)"
|
||||||
|
},
|
||||||
|
DeskContainer:{
|
||||||
|
border: `1px solid black`,
|
||||||
|
borderRadius: `5px`,
|
||||||
|
padding: `1rem`
|
||||||
|
},
|
||||||
|
DeskDirty:{
|
||||||
|
background:"tomato",
|
||||||
|
color:"white"
|
||||||
|
},
|
||||||
|
GapHorizontal:{
|
||||||
|
borderCollapse:"separate",
|
||||||
|
borderSpacing:"0 2rem"
|
||||||
|
},
|
||||||
|
GapVertical:{
|
||||||
|
borderCollapse:"separate",
|
||||||
|
borderSpacing:"2rem 0.2rem"
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user