Skip to content

Commit

Permalink
Merge pull request #13 from UNDP-Accelerator-Labs/pipe-groups
Browse files Browse the repository at this point in the history
Pipe groups
  • Loading branch information
myjyby authored Nov 22, 2024
2 parents 90258ba + 707acfb commit 90b7170
Show file tree
Hide file tree
Showing 19 changed files with 526 additions and 52 deletions.
3 changes: 3 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ app.post('/updateMatrix', routes.matrixes.update);
app.post('/updateMatrixes', routes.matrixes.updateMulti);
app.delete('/removeMatrix', routes.matrixes.remove);

app.post('/addPipe', routes.pipes.add);
app.delete('/removePipe', routes.pipes.remove);

app.post('/addTitle', routes.addTitle);
app.post('/updateTitle', routes.updateTitle);
app.post('/removeTitle', routes.removeTitle);
Expand Down
9 changes: 8 additions & 1 deletion init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ CREATE TABLE notes (
x DOUBLE PRECISION,
y DOUBLE PRECISION,
project INT REFERENCES projects (id) ON UPDATE CASCADE ON DELETE CASCADE,
tree ltree DEFAULT text2ltree('0')
tree ltree DEFAULT text2ltree('0'),
pipe_from INT REFERENCES notes (id) ON UPDATE CASCADE ON DELETE CASCADE
);

CREATE TABLE cards (
Expand Down Expand Up @@ -64,6 +65,12 @@ CREATE TABLE datasources (
project INT REFERENCES projects (id) ON UPDATE CASCADE ON DELETE CASCADE
);

CREATE TABLE pipes (
"from" INT REFERENCES groups (id) ON UPDATE CASCADE ON DELETE CASCADE,
"to" INT UNIQUE REFERENCES groups (id) ON UPDATE CASCADE ON DELETE CASCADE
);


CREATE TABLE session (
sid varchar NOT NULL COLLATE "default",
sess json NOT NULL,
Expand Down
59 changes: 49 additions & 10 deletions public/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ h1, h2 {
h2 small {
font-size: .5em;
}
.deactivate {
pointer-events: none;
}
div.overlay {
position: absolute;
display: flex;
Expand Down Expand Up @@ -125,6 +128,9 @@ div.origin::after {
div.dragging {
z-index: 1000 !important;
}
div.dragging *:not(.sticky-area) {
pointer-events: none;
}
div.matrix {
position: absolute;
display: grid;
Expand All @@ -133,6 +139,10 @@ div.matrix {
margin: 0 2rem 2rem 0;
z-index: 50;
}
div.matrix > div.sticky-area {
grid-column: span 2;
background-color: rgba(51,51,51,.1);
}
div.matrix table {
resize: both;
border-collapse: collapse;
Expand Down Expand Up @@ -178,7 +188,7 @@ div.group {
position: absolute;
border: 1px solid rgba(51,51,51,.25);
background-color: rgba(225,225,225,.25);
padding: 4rem 0rem 2rem 2rem;
padding: 0 0 2rem 2rem;
margin: 0 2rem 2rem 0;
z-index: 50;
resize: both;
Expand All @@ -202,14 +212,40 @@ div.matrix table th.sticky-area input[type=text] {
margin-bottom: 0;
text-align: center;
}
div.group button.pipe {
position: absolute;
width: 2rem;
height: 2rem;
min-height: 30px;
min-width: 30px;
right: 100%;
top: -1px;
z-index: 1001;
padding: 0;
}
/*div.group button.pipe.connected {
height: 100% !important;
}
button.pipe.connected span.flip {
transform: rotate(-90deg);
}*/
div.pipeline {
position: absolute;
background-color: rgba(51,51,51,.7);
width: 1px;
height: 5px;
border-radius: 5px;
transform-origin: top left;
z-index: 1000;
}
div.note {
background-color: yellow;
font-family: Comic Sans MS;
display: inline-block;
position: absolute;
min-width: 100px;
min-height: 100px;
padding: 2rem;
/* padding-top: 2rem;*/
border: 1px solid rgba(51,51,51,.05);
z-index: 100;
transform-origin: top center;
Expand Down Expand Up @@ -292,8 +328,8 @@ div.hit {
padding: 2rem;
}*/
div.sticky-area {
width: calc(100% + 4rem);
margin: -2rem 0 0 -2rem;
width: 100%;
/* margin: -2rem 0 0 -2rem;*/
min-height: 30px;
height: 30px;
max-height: 120px;
Expand All @@ -302,7 +338,7 @@ div.sticky-area {
}
div.group > div.sticky-area {
width: calc(100% + 2rem);
margin: -4rem 0 1rem -2rem;
margin: 0 0 1rem -2rem;
}
div.note div.color-swatches {
/*width: 150px;*/
Expand Down Expand Up @@ -337,11 +373,12 @@ div.card.dragging div.sticky-area {
}
textarea {
font-family: Comic Sans MS;
display: block;
outline: none;
border: none;
width: calc(100% - 2rem);
margin: 1rem 0 0 1rem;
min-height: calc(100px - 1rem);
width: 100%;
/* margin: 1rem 0 0 1rem;*/
min-height: 200px;
background-color: transparent;
min-width: 100px;
font-size: 1rem;
Expand All @@ -350,10 +387,12 @@ textarea {
/*align-items: center;*/
/*justify-content: center;*/
text-align: center;
resize: none;
position: absolute;
resize: both;
padding: 1rem 2rem 2rem 2rem;
/* position: absolute;*/
left: 0;
overflow: hidden;
box-sizing: border-box;
}
div.title {
/*padding: 2rem;*/
Expand Down
7 changes: 6 additions & 1 deletion public/js/canvas/zoom.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ function zooming () {
.style('transform', d => `scale(${1 / d.k})`);

d3.selectAll('div.sticky-area:not(.immutable)')
.style('height', `${30 * 1 / t.k / 2}px`);
.style('height', `${Math.min(75, 30 * 1 / t.k / 2)}px`);
d3.selectAll('button.pipe')
.styles({
'width': `${Math.min(75, 30 * 1 / t.k / 2)}px`,
'height': `${Math.min(75, 30 * 1 / t.k / 2)}px`,
});
d3.selectAll('div.note, div.card, div.group, div.matrix')
.style('border-width', `${1 / t.k / 2}px`);
}
Expand Down
47 changes: 40 additions & 7 deletions public/js/elements/drag.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,15 @@ function dragStart (d) {
d.x = 0;
d.y = 0;
}
// DEACTIVATE ALL textareas AND inputs
d3.select('div.canvas').selectAll('textarea, input')
.classed('deactivate', true);
} else {
sel.classed('dragging', false);
// REACTIVATE ALL textareas AND inputs
d3.select('div.canvas').selectAll('textarea, input')
.classed('deactivate', false);
}
else sel.classed('dragging', false);
}

let object;
Expand Down Expand Up @@ -110,9 +117,16 @@ async function dragEnd (d) {

const sel = d3.select(this)
.classed('dragging', false);
// REACTIVATE ALL textareas AND inputs
d3.select('div.canvas').selectAll('textarea, input')
.classed('deactivate', false);

const parent = d3.select(this.parentNode);
const otree = d.tree;

const hit = d3.select('div.hit');
let pipes = [];

if (hit.node()) {
// 1- CHECK IF THE HIT IS AN EXISTING GROUP
// OTHERWISE CREATE THE GROUP
Expand All @@ -123,13 +137,13 @@ async function dragEnd (d) {
groupping = hit;
d.x = null;
d.y = null;
const { id: gid, tree: gtree } = hit.datum();
// d.tree = tree.rebase(d.tree, gid, gtree);
const { id: gid, tree: gtree, pipe_to } = hit.datum();
d.tree = tree.build(gtree, gid);

if (Array.isArray(pipe_to) && pipe_to?.length) pipes = [ ...pipes, ...pipe_to ];

} else if (hit.classed('note') || hit.classed('card')) {
// IF THE HIT IS A NOTE OR CARD, CREATE A GROUP
const { x, y, tree: ntree } = hit.datum();
const { x, y, tree: ntree, piped_from } = hit.datum();

groupping = await Group.add({
parent: d3.select(hit.node().parentNode),
Expand All @@ -141,8 +155,26 @@ async function dragEnd (d) {
d.x = null;
d.y = null;
const { id: gid, tree: gtree } = groupping.datum();
// d.tree = tree.rebase(d.tree, gid, gtree);
d.tree = tree.build(gtree, gid);

// IF THE hit note IS INSIDE A PIPED GROUP, PIPE THE dragged NOTE
if (tree.getDepth(d.tree) > 1) {
// CHECK ALL THE PARENT GROUPS FOR PIPING
const nodes = tree.getNodes(d.tree);
let i = nodes.length - 1;

while (i >= 0) {
const group = d3.selectAll('div.group')
.filter(d => d.id === +nodes[i]);

if (group.node()) {
const { pipe_to } = group.datum();
if (Array.isArray(pipe_to) && pipe_to?.length) pipes = [ ...pipes, ...pipe_to ];
}
i--;
}

}
}
hit.classed('hit', false);
} else { // THE OBJECT IS MOVED OUT OF ALL GROUPS
Expand All @@ -155,8 +187,9 @@ async function dragEnd (d) {
if (sel.classed('note')) {
await Note.update({
note: sel,
datum: d,
datum: { ...d, ...{ pipe_from: null } },
bcast: true,
group_pipes: pipes,
});
} else if (sel.classed('card')) {
await Card.update({
Expand Down
7 changes: 7 additions & 0 deletions public/js/elements/groups.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Card } from './cards.mjs';
import { Matrix } from './matrixes.mjs';
import { POST, DELETE, wallId, tree, computeAbsCoordinates } from '../helpers/index.mjs';
import { drag } from './drag.mjs';
import { pipe } from './pipe.mjs';
import { broadcast } from '../websocket/index.mjs';

export const Group = {
Expand Down Expand Up @@ -42,6 +43,12 @@ export const Group = {
'transform': d => (![null, undefined].includes(d.x) && ![null, undefined].includes(d.y)) ? `translate(${d.x}px, ${d.y}px)` : null,
'grid-column-start': d => d.matrix_index ? +tree.getLeaf(d.matrix_index) + 2 : null,
});

// ADD AN OPTION TO PIPE GROUPS
group.addElems('button', 'btn pipe')
.html('@')
.call(pipe);

// ADD A STICKY AREA TO MOVE THE GROUP AROUND
if (!immutable) {
group.addElems('div', 'sticky-area');
Expand Down
6 changes: 5 additions & 1 deletion public/js/elements/matrixes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export const Matrix = {
'transform': d => (![null, undefined].includes(d.x) && ![null, undefined].includes(d.y)) ? `translate(${d.x}px, ${d.y}px)` : null,
// 'grid-template-columns': d => `.5fr, repeat(${d.cols.length}, 1fr)`,
});
// ADD GLOBAL STICKY AREA TO MOVE THE MATRIX AROUND
matrix.addElems('div', 'sticky-area');
const table = matrix.addElems('table');
// ADD STICKY AREAS TO EACH COLUMN HEADER TO MOVE THE MATRIX AROUND
const thead = table.addElems('tr', 'head');
Expand Down Expand Up @@ -228,7 +230,9 @@ export const Matrix = {
matrix.each(d => {
if (!d.cells) d.cells = [];
d.cells.push(group.datum());
})
});
// TO DO: INVESTIGATE THIS
// LIKELY WHERE THE DISPATCH ISSUE IS COMING FROM
}
}
}
Expand Down
Loading

0 comments on commit 90b7170

Please sign in to comment.