Skip to content

Commit 98c9dff

Browse files
committed
WIP
1 parent 9eee4e2 commit 98c9dff

File tree

12 files changed

+191
-68
lines changed

12 files changed

+191
-68
lines changed

app/app.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ const start = async function () {
179179
};
180180

181181
const hocuspocusServer = HocuspocusServer.configure({
182-
port: 8081,
182+
address: Config.crdt_backend_host,
183+
port: Config.crdt_backend_port,
183184
debounce: 3000,
184185
onStoreDocument(data) {
185186
storeDocument(data);

app/controller/data/data.controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const data = function (req, res) {
88
title: 'MicroDraw::Data',
99
loginMethods : req.appConfig.loginMethods || [],
1010
params: JSON.stringify(req.query),
11-
user : req.user
11+
loggedUser: JSON.stringify(req.user || null)
1212
});
1313
};
1414

app/controller/user/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ router.get('/json/:userName', controller.validator, controller.api_user);
88
router.get('/json/:userName/files', controller.validator, controller.api_userFiles);
99
router.get('/json/:userName/atlas', controller.validator, controller.api_userAtlas);
1010
router.get('/json/:userName/projects', controller.validator, controller.api_userProjects);
11+
router.post('/delete', controller.deleteProfile);
1112
router.get('/:userName', controller.validator, controller.user);
1213

1314
module.exports = router;

app/controller/user/user.controller.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ const { AccessControlService } = require('neuroweblab');
88

99
const validator = function (req, res, next) {
1010
// UserName can be an ip address (for anonymous users)
11+
const username = req.params.userName;
1112

12-
/*
13-
req.checkParams('userName', 'incorrect user name').isAlphanumeric();
14-
var errors = req.validationErrors();
15-
console.log(errors);
16-
if (errors) {
17-
res.send(errors).status(403).end();
18-
} else {
19-
return next();
20-
}
21-
*/
22-
next();
13+
req.appConfig.db.queryUser({username})
14+
.then((result) => {
15+
if (result && result.disabled) {
16+
res.status(404);
17+
18+
return res.render('disabledUser');
19+
}
20+
next();
21+
22+
});
2323
};
2424

2525
const user = function (req, res) {
@@ -187,12 +187,28 @@ const api_userProjects = function (req, res) {
187187
});
188188
};
189189

190+
const deleteProfile = async function(req, res) {
191+
const loggedUser = req.user;
192+
if (!loggedUser) {
193+
res.status(401);
194+
}
195+
try {
196+
const userInfo = await req.appConfig.db.queryUser({username: loggedUser.username});
197+
console.log({userInfo});
198+
await req.appConfig.db.updateUser({ ...userInfo, disabled: true });
199+
res.redirect('/logout');
200+
} catch(err) {
201+
console.log(err);
202+
}
203+
};
204+
190205
module.exports = {
191206
validator,
192207
api_user,
193208
api_userAll,
194209
api_userFiles,
195210
api_userAtlas,
196211
api_userProjects,
212+
deleteProfile,
197213
user
198214
};

app/views/data.mustache

Lines changed: 8 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,57 +3,20 @@
33

44
<head>
55
{{> partials/header }}
6-
<link rel="stylesheet" href="css/data-style.css" type="text/css" />
6+
<link rel="stylesheet" href="/css/ui.css" type="text/css" />
7+
<link rel="stylesheet" href="/css/data-style.css" type="text/css" />
8+
<link rel="stylesheet" href="/css/project-style.css" type="text/css" />
79
<link href='https://fonts.googleapis.com/css?family=Roboto:100' rel='stylesheet' type='text/css'>
810
</head>
911

12+
<script>
13+
const loggedUser={{{loggedUser}}};
14+
</script>
1015
<body>
1116

12-
<!-- Header (fixed height) -->
13-
<div id="header">
14-
{{> partials/menu }}
15-
16-
<!-- Small left-top logo -->
17-
<div style="display:inline-block;margin:10px">
18-
<a href='/' style="text-decoration:none">
19-
<img style='height:28px;vertical-align:middle' src='/img/microdraw-white.svg'/>
20-
</a><span id="fontLogo">
21-
<a href='/' style="font-family: Roboto, sans-serif; font-size: 28px; font-weight:100; text-decoration:none;vertical-align:middle">MicroDraw</a>
22-
</span>
23-
</div>
24-
</div>
25-
26-
<div id="content" style="width:100%;height:calc( 100% - 48px );background:white;position:relative"></div>
17+
<div id="app"></div>
2718

28-
<script>
29-
function loadScript (path, testScriptPresent) {
30-
return new Promise((resolve, reject) => {
31-
if(testScriptPresent && testScriptPresent()) {
32-
resolve();
33-
}
34-
const s = document.createElement("script");
35-
s.src = path;
36-
s.onload=resolve;
37-
s.onerror=reject;
38-
document.body.appendChild(s);
39-
});
40-
}
41-
42-
async function attach () {
43-
const res = await fetch("/microdraw");
44-
const txt = await res.text();
45-
const parser = new DOMParser();
46-
const elem = parser.parseFromString(txt, 'text/html').documentElement;
47-
const shadow = document.querySelector("#content").attachShadow({mode: 'open'});
48-
shadow.appendChild(elem);
49-
loadScript("/js/microdraw.js")
50-
.then(() => {
51-
Microdraw.init(shadow);
52-
});
53-
}
54-
attach();
55-
</script>
19+
<script src="/js/pages/data-page.js"></script>
5620

5721
</body>
58-
5922
</html>

app/views/disabledUser.mustache

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
{{> partials/header }}
6+
<link href='https://fonts.googleapis.com/css?family=Roboto:100' rel='stylesheet' type='text/css'>
7+
</head>
8+
9+
<body>
10+
11+
<!-- Header (fixed height) -->
12+
<div id="header">
13+
<!-- Small left-top logo -->
14+
<div style="display:inline-block;margin:10px">
15+
<a href='/' style="text-decoration:none">
16+
<img style='height:28px;vertical-align:middle' src='/img/microdraw-white.svg'/>
17+
</a><span id="fontLogo">
18+
<a href='/' style="font-family: Roboto, sans-serif; font-size: 28px; font-weight:100; text-decoration:none;vertical-align:middle">MicroDraw</a>
19+
</span>
20+
</div>
21+
</div>
22+
23+
This user has removed his account. <a href="/">Back to the homepage</a>
24+
25+
26+
</body>
27+
28+
</html>
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<template>
2+
<Header v-if="!fullscreen">
3+
<span class="title">MicroDraw</span>
4+
</Header>
5+
<main :class="{ fullscreen }">
6+
<OntologySelector
7+
:ontology="ontology"
8+
:open="displayOntology"
9+
@on-close="displayOntology = false"
10+
@label-click="handleOntologyLabelClick"
11+
/>
12+
<Editor :title="title" :class="{reduced: !displayChat && !displayScript}" toolsMinHeight="300px">
13+
<template v-slot:tools>
14+
<Tools />
15+
</template>
16+
<template v-slot:content>
17+
<div id="microdraw" style="width: 100%; height: 100%"></div>
18+
</template>
19+
</Editor>
20+
</main>
21+
</template>
22+
23+
<script setup>
24+
import useVisualization from "../store/visualization";
25+
import Tools from "./Tools.vue";
26+
import {
27+
Header,
28+
Editor,
29+
OntologySelector,
30+
} from "nwl-components";
31+
import * as Vue from "vue";
32+
33+
const { baseURL } = Vue.inject('config');
34+
35+
const {
36+
title,
37+
displayChat,
38+
displayScript,
39+
displayOntology,
40+
currentLabel,
41+
ontology,
42+
currentSlice,
43+
currentFile,
44+
totalSlices,
45+
fullscreen,
46+
init: initVisualization,
47+
} = useVisualization();
48+
49+
const handleResize = () => {
50+
Microdraw.resizeAnnotationOverlay();
51+
};
52+
53+
const toggleFullScreen = () => {
54+
if (!document.fullscreenElement) {
55+
document.documentElement.requestFullscreen();
56+
} else if (document.exitFullscreen) {
57+
document.exitFullscreen();
58+
}
59+
}
60+
61+
Vue.watch(fullscreen, toggleFullScreen);
62+
63+
const _findSelectedRegion = () => {
64+
const {currentImage, region} = Microdraw;
65+
const {Regions: regions} = Microdraw.ImageInfo[currentImage];
66+
return regions.findIndex(reg => reg.uid === region.uid);
67+
};
68+
69+
const handleOntologyLabelClick = (index) => {
70+
Microdraw.currentLabelIndex = index;
71+
displayOntology.value = false;
72+
currentLabel.value = index;
73+
const regionIndex = _findSelectedRegion();
74+
if(regionIndex != null) {
75+
const { region } = Microdraw;
76+
if (region != null) {
77+
Microdraw.changeRegionName(region, Microdraw.ontology.labels[index].name);
78+
}
79+
}
80+
}
81+
82+
Vue.onMounted(async () => {
83+
await initVisualization();
84+
window.addEventListener('resize', handleResize);
85+
});
86+
</script>
87+
<style scoped>
88+
.area {
89+
height: calc(100vh - 82px);
90+
width: 100vw;
91+
}
92+
.fullscreen .area {
93+
height: 100vh;
94+
}
95+
96+
</style>

app/views/scripts/components/UserPage.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,18 @@
3535
</tbody>
3636
</Table>
3737
</Tab>
38-
<Tab title="Settings">
38+
<Tab title="Settings" v-if="displaySettings">
3939
<form class="embed-preferences">
4040
<h3>Embed</h3>
4141
<p>Limit embedding of my contents to the following hosts (1 item by line):</p>
42-
<textarea placeholder="google.com" name="allowedHosts"></textarea>
42+
<textarea placeholder="example.com" name="allowedHosts"></textarea>
4343
<div class="action-buttons">
4444
<button className="push-button" type="submit">Save</button>
4545
</div>
4646
</form>
4747
<h3>Account</h3>
4848
<dialog ref="removeAccountDialog" class="removeAccountDialog">
49-
<form action="#" method="POST">
49+
<form action="/user/delete" method="POST">
5050
<p>
5151
Are you sure you want to delete your account?
5252
</p>
@@ -63,7 +63,7 @@
6363
</UserPage>
6464
</template>
6565
<script setup>
66-
import { ref, onMounted } from "vue";
66+
import { ref, onMounted, computed } from "vue";
6767
import { UserPage, Tabs, Tab, Table } from "nwl-components";
6868
const projects = ref([]);
6969
const removeAccountDialog = ref(null);
@@ -78,6 +78,8 @@
7878
projects.value.push(...res.list);
7979
}
8080
};
81+
82+
const displaySettings = computed(() => loggedUser && props.user.username === loggedUser.username);
8183
8284
onMounted(() => {
8385
fetchProjects();
@@ -140,5 +142,7 @@
140142
.embed-preferences textarea {
141143
height: 100px;
142144
width: 100%;
145+
margin-bottom: 10px;
146+
color: black;
143147
}
144148
</style>

app/views/scripts/src/data-page.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/* global loggedUser */
2+
3+
import 'nwl-components/dist/style.css';
4+
import Data from '../components/Data.vue';
5+
import config from './nwl-components-config';
6+
import { createApp } from 'vue';
7+
8+
9+
const app = createApp(Data);
10+
app.provide('config', config);
11+
app.provide('user', loggedUser);
12+
13+
app.mount('#app');

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)