Compare commits

..

No commits in common. "f47ab32d68025d6566f1f830da938a406233013d" and "1d527de26f36a90a66738971703ccc71c8626bd1" have entirely different histories.

4 changed files with 151 additions and 221 deletions

304
app.js
View File

@ -1,8 +1,32 @@
/** @import * as TYPES from "./graph/types.ts" */
import * as FSHandle from "./store-directory-handle.js";
import Styles from "./styles.js";
const {DOM, Div, Tag} = Styles;
const {Div, DOM} = 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)"
}
});
async function PickHandle()
{
@ -20,21 +44,11 @@ async function LoadHandleFiles()
const module = await import("./graph/room.js"+"?bust="+Math.random());
/** @type {Record<string, TYPES.GraphParts>} */
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;
}
catch(e)
catch(_e)
{
console.log("the handle exists, but the request failed. the service work must not be ready yet.", e)
console.log("the handle exists, but the request failed. the service work must not be ready yet.")
rooms.val = {};
}
}
@ -57,155 +71,116 @@ const loggedIn = van.state(false);
const blocking = van.state(false);
const showDesks = van.state(true, "desks");
const showDesks = van.state(true);
function Input(handler=(str)=>{})
/** @type {(inParts:Record<string, TYPES.Part>)=>HTMLElement} */
function Parts(inParts)
{
const input = DOM.textarea({style:"vertical-align:text-top; width:500px; height:200px;"});
let submitButton = Div.Plain(DOM.button({onclick(){
handler(input.value);
input.value = "";
mountPoint.remove();
}}, "submit value"));
return Div.Plain(
Div.Plain("Parts"),
Div.PartGroup(
Object.entries(inParts).map(([part_id, part])=>{
let cancelButton = DOM.button({onclick(){
input.value = "";
mountPoint.remove();
}}, "cancel")
const work = []
for(const [pass, data] of part.pass)
{
const mountPoint = Div.Plain({onclick(e){e.stopPropagation();}}, input, cancelButton, submitButton);
return mountPoint;
work.push(Div.Part(
DOM.h5(pass.name),
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 Div.Part(
DOM.h3(part.name),
...work,
);
}),
)
)
}
/** @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])=>{
const row = [DOM.th(part.name)];
for(const [pass, data] of part.pass)
{
row.push(DOM.td.Part(data.work.map(w=>Div.Plain(w[1]) )))
}
rows.push(DOM.tr(row))
});
return DOM.table.GapVertical(rows);
}
const deskRender = van.state(0);
/** @type {(inDesks:Record<string, TYPES.Desk>)=>HTMLElement} */
function Desks(inDesks)
{
return Div.Plain(
Div.Plain("Desks"),
Div.PartGroup(
Object.entries(inDesks).map(([desk_id, desk])=>{
loggedIn.val;
return Div.PartGroup(
Object.entries(inDesks).map(([desk_id, desk])=>{
loggedIn.val;
deskRender.val;
console.log("reredering desk", desk.name);
if (loggedIn.val)
{
let userInRole = false;
for(const role of desk.role)
if(loggedIn.val)
{
if(role.user.includes(loggedIn.val))
for(const role of desk.role)
{
userInRole = true;
}
}
if(!userInRole)
{
return null;
}
}
/** @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);
if(partPass)
{
const time = partPass.time;
const latest = partPass.work.find(t=>t[0] == time);
const attributes = {
class: dirty.includes(index) ? Tag("DeskDirty") : "",
};
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;
}
}));
if(!role.user.includes(loggedIn.val))
{
return null;
}
}
return DOM.td(
Div.Part(
attributes,
latest?.[1] || ""
)
);
}
return null;
}
const work = [];
for(const [pass, dirty] of desk.pass)
{
work.push(DOM.tr(
DOM.td(pass.name),
desk.need.map((part, index)=>Iterator(part, index, pass, dirty.need, "need")),
DOM.td("->"),
desk.make.map((part, index)=>Iterator(part, index, pass, dirty.make, "make"))
))
}
/** @type {(part:TYPES.Part, index:number, pass:TYPES.Pass, dirty:number[])=>HTMLElement|null} */
const Iterator = (part, index, pass, dirty)=>{
return Div.DeskContainer(
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))
),
const partPass = part.pass.get(pass);
if(partPass)
{
const time = partPass.time;
const latest = partPass.work.find(t=>t[0] == time);
return Div.Plain(
part.name,
DOM.p( dirty.includes(index) ? "Dirty" : "Good!" ),
Div.Part(
time, " ", latest?.[1] || ""
)
);
}
return null;
}
const work = [];
for(const [pass, dirty] of desk.pass)
{
work.push(Div.Part(
DOM.h5(pass.name),
Div.Part(
DOM.h4("Need:"),
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(
DOM.h3(desk.name),
work
)
)
}),
}),
)
)
}
@ -236,30 +211,29 @@ function Room(room_id, graphParts)
})
),
Div.Plain("Passes:"),
Div.PartGroup(
Object.entries(graphParts.Pass).map(([pass_id, pass])=>{
return ()=>{
console.log("rerendering...", rerender.rawVal);
// Div.Plain("Passes:"),
// Div.PartGroup(
// Object.entries(graphParts.Pass).map(([pass_id, pass])=>{
// return ()=>{
// console.log("rerendering...", rerender.rawVal);
//
// rerender.val;
//
// return Div.Part(
// DOM.div.Plain(pass.name),
// ()=>{
// return DOM.button.Plain(
// {async onclick(){
// await pass[pass.live ? "dump" : "load"]();
// rerender.val++
// }},
// pass.live ? "Dump" : "Load"
// )
// },
// )
// }
// })
// ),
rerender.val;
return Div.Part(
DOM.div.Plain(pass.name),
()=>{
return DOM.button.Plain(
{async onclick(){
await pass[pass.live ? "dump" : "load"]();
rerender.val++
}},
pass.live ? "Dump" : "Load"
)
},
)
}
})
),
()=>{
return DOM.button({onclick(){
@ -269,7 +243,7 @@ function Room(room_id, graphParts)
()=>{
rerender.val;
return showDesks.val ? Desks(graphParts.Desk) : Parts(graphParts.Part, graphParts.Pass);
return showDesks.val ? Desks(graphParts.Desk) : Parts(graphParts.Part);
},

View File

@ -1,19 +1,13 @@
//@ts-check
import CreateAllRooms, {Room} from "../../graph/graph.js";
import Rooms, {Room} from "../../graph/graph.js";
import User from "./user.js";
const user = {
u1:"Seth Trowbridge",
u4:"Sarah Sharp",
u5:"Adam Marshall",
}
export default CreateAllRooms({
export default Rooms({
room_01:Room({
user,
user:User,
role:{
dev:["Development", "u1"],
write:["Writing", "u5"],
admin:["Admin", "u4"]
write:["Writing", "u2", "u3"],
},
part:{
p1:"Page title",
@ -21,8 +15,8 @@ export default CreateAllRooms({
p3:"Page preview",
},
desk:{
d1:["Write page metas", ["admin", "write"], "all", {}, "p1", "p2"],
d2:["Build Page preview", ["admin", "dev"], "all", {p1:1, p2:1}, "p3" ]
d1:["Write page metas", ["write"], "all", {}, "p1", "p2"],
d2:["Build Page preview", ["dev"], "all", {p1:1, p2:1}, "p3"]
},
pass:{
pass_01:["January"],

View File

@ -0,0 +1,5 @@
export default {
u1:"seth",
u2:"seth2",
u3:"seth3"
}

View File

@ -1,43 +0,0 @@
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"
}
});