Commit b489e3c5 authored by François Billioud's avatar François Billioud

implement multi-user and multi-storage

parent 3f423885
...@@ -215,7 +215,7 @@ div.header-right div.input a { ...@@ -215,7 +215,7 @@ div.header-right div.input a {
border: 1px solid #D1D1D1; border: 1px solid #D1D1D1;
display: none; display: none;
} }
.action_menu ul li ul hover { .action_menu ul li ul:hover {
display: block; display: block;
} }
.action_menu ul li ul li:hover { .action_menu ul li ul li:hover {
...@@ -330,7 +330,7 @@ div.gadget-action input#upload { ...@@ -330,7 +330,7 @@ div.gadget-action input#upload {
border: 1px solid #BBBBBB; border: 1px solid #BBBBBB;
border-radius: 4px 4px 4px 4px; border-radius: 4px 4px 4px 4px;
color: #333333; color: #333333;
left: 1em; left: 0.5em;
position: relative; position: relative;
top: 0.1em; top: 0.1em;
} }
...@@ -409,12 +409,46 @@ button.delete { ...@@ -409,12 +409,46 @@ button.delete {
margin-left: 6px; margin-left: 6px;
margin-top: 6px; margin-top: 6px;
} }
/* navigation buttons */
div.listbox-navigation { div.listbox-navigation {
float: right; float: right;
font-size: 13px; font-size: 13px;
margin-right: 5px; margin-right: 5px;
margin-top: 6px; margin-top: 0;
min-width: 10%; min-width: 10%;
display: none;
}
div.listbox-navigation input {
margin-top: 0.3em;
height: 18px;
width: 20px;
}
div.listbox-navigation button.listbox_first_page {
background-image: url("../images/ung/first_page.png");
}
div.listbox-navigation button.listbox_previous_page {
background-image: url("../images/ung/previous_page.png");
}
div.listbox-navigation button.listbox_next_page {
background-image: url("../images/ung/next_page.png");
}
div.listbox-navigation button.listbox_last_page {
background-image: url("../images/ung/last_page.png");
}
div.listbox-navigation button.listbox_previous_page, div.listbox-navigation button.listbox_next_page {
margin: 0;
width: 12px;
}
div.listbox-navigation button {
position: relative;
top: -0.2em;
background-repeat: no-repeat;
border: 0 none;
height: 20px;
display: none;
}
div.listbox-navigation button:hover {
cursor: pointer;
} }
/* header */ /* header */
...@@ -558,6 +592,10 @@ div#advertisement img{ ...@@ -558,6 +592,10 @@ div#advertisement img{
height: 10em; height: 10em;
} }
/* login table */ /* login table */
span#id_provider_details {
font-size: 8px;
float: left;
}
table#field_table, table#new-account-table, table#create-new-user { table#field_table, table#new-account-table, table#create-new-user {
border: 1px solid #C3D9FF; border: 1px solid #C3D9FF;
width: 78%; width: 78%;
...@@ -606,6 +644,23 @@ div.footer a { ...@@ -606,6 +644,23 @@ div.footer a {
margin-right: 0.5em; margin-right: 0.5em;
} }
/**********************************************************
******************** tooltip area *********************/
span.tooltipElement {
cursor: pointer;
color: #0099CC;
}
div.toolLocation{
visibility: hidden;
position: absolute;
border-radius: 10px 10px 10px 10px;
border: 1px solid Black;
padding: 10px;
font-family: Verdana, Arial;
font-size: 10px;
background-color: #FFFFCC;
}
/********************************************************** /**********************************************************
******************* dialog box ************************/ ******************* dialog box ************************/
div.ui-dialog { div.ui-dialog {
...@@ -624,9 +679,6 @@ div.ui-dialog-titlebar { ...@@ -624,9 +679,6 @@ div.ui-dialog-titlebar {
border-radius: 1px 1px 1px 1px; border-radius: 1px 1px 1px 1px;
height: 15px; height: 15px;
} }
div.ui-dialog-titlebar {
height: 15px;
}
span#ui-dialog-title-edit_document, span#ui-dialog-title-upload_document, span#ui-dialog-title-gadget-listbox { span#ui-dialog-title-edit_document, span#ui-dialog-title-upload_document, span#ui-dialog-title-gadget-listbox {
color: #222222 !important; color: #222222 !important;
font: bold 12pt Arial,Sans-serif; font: bold 12pt Arial,Sans-serif;
......
* Decision of JS pattern used for Prototypical Inheritance
* Desicion: Why meta-data should be inside the data of the file
** I had two choices about meta data:
*** Let the meta-data stay inside the data itself i.e. your data on file will contain the meta data too.
**** Advantage is that the ability to store meta-data is not needed or is dependednt on the type of storage
**** We have more control over the meta data and how it is interfaced.
**** Thus, currently meta-data in DAV is stored along with data, this way the hash returns the sum of both meta-data and data
**** This might be desirable or undesirable but good thing is that decision is in our hand
**** Other software must know how JIO stores the meta-data
*** Let the meta-data be separate from the data so that the server can take care of meta-data in meaningful way
**** This way, meta-data interface has to be written for every backend separately
**** We just work on the data, the hash is returned for only the data part. encryption (or other transformations) are done for only the data part
**** Many backend like ObjStore won't have meta-data handling in an intutive way
**** server will handle the meta-data
**** This facilitates JIO interaction with other services (eg: in Google Doc, if you use its API to do the meta-data, even Google Doc can use that information)
*** Decision
Meta-data with file data for now. Since JIO is open standard, we will publish our meta-data storing syntax. This way JIO can be used uniformally on All backends
The consequence of this is that we don't see meta-data as a different data, it is part of the document
* Object based Storage
** The basic idea is to let a object represent the entire tree of the
virtual file system
** The such objects can be nested inside each other. Hence to create
an entire filesystem is possible.
** Each object can be either a document (as are files in Unix) or a
collection (as are directory in Unix)
** We can then encapsulate the entire filesystem tree in as a single
object.
** The good part is that we can run JSON stringify on this object to
convert it into pure string and thus serialize it.
** The design should be such that these objects must be pluggable
inside other objects.
** Should be able to store Metadata
** Design
*** Each Object contain two basic information : doc_id, content
*** doc_id is basically the name of the resource (resource is a general term used for a collection or a document)
*** In a given collection, all the containing collections and document should have unique doc_id (i.e. you can't have a collection and a document named `foo' inside on collection)
*** Identification of if the resource is a collection or document is done by noting the type of the content, if it is an array, then the given resource is a collection, document otherwise
*** Any resource is identified by it's doc_id and parent object (or parent's doc_id, which itself is identified by using its parents doc_id)
***
** If the loadDocument requests a directory, (aka collection), return the hash is the sum of all the content inside that collection and let the data be an array with the docid of all the child documents.
** Implementing
** Current implmentation doesn't enjoy much of code-reuse, I think I can use more inheritance core-reuse, will have to refactor the code. But the basic design of JIO will facilitate that
This diff is collapsed.
...@@ -92,7 +92,7 @@ List.prototype.load({ ...@@ -92,7 +92,7 @@ List.prototype.load({
return this.tail().get(i-1); return this.tail().get(i-1);
}, },
set: function(i,element) { set: function(i,element) {
if(i>=this.size()) {error("set out of bounds, "+i+" : "+this.size(),this);return} if(i>=this.size()) {errorMessage("set out of bounds, "+i+" : "+this.size(),this);return}
if(i==0) { if(i==0) {
this.headElement=element; this.headElement=element;
} else { } else {
...@@ -100,7 +100,7 @@ List.prototype.load({ ...@@ -100,7 +100,7 @@ List.prototype.load({
} }
}, },
remove: function(i) { remove: function(i) {
if(i>=this.size()) {error("remove out of bounds, "+i+" : "+this.size(),this);return}//particular case if(i>=this.size()) {errorMessage("remove out of bounds, "+i+" : "+this.size(),this);return}//particular case
if(i==0) {this.pop();return}//particular case if(i==0) {this.pop();return}//particular case
if(i==1) {//init if(i==1) {//init
this.previous = this.tail().tail(); this.previous = this.tail().tail();
...@@ -110,7 +110,7 @@ List.prototype.load({ ...@@ -110,7 +110,7 @@ List.prototype.load({
this.length--; this.length--;
}, },
pop: function() { pop: function() {
if(this.isEmpty()) {error("pop on empty list",this);return null;} if(this.isEmpty()) {errorMessage("pop on empty list",this);return null;}
var h = this.head(); var h = this.head();
this.load(this.tail()) this.load(this.tail())
return h; return h;
...@@ -128,7 +128,7 @@ List.prototype.load({ ...@@ -128,7 +128,7 @@ List.prototype.load({
}, },
contains: function(object) {if(this.isEmpty()) {return false} else {return object===this.head() ? true : this.tail().contains(object)}}, contains: function(object) {if(this.isEmpty()) {return false} else {return object===this.head() ? true : this.tail().contains(object)}},
insert: function(element,i) { insert: function(element,i) {
if(i>this.size()) {error("insert out of bounds, "+i+" : "+this.size(),this);return}//particular case if(i>this.size()) {errorMessage("insert out of bounds, "+i+" : "+this.size(),this);return}//particular case
if(i==0) {//init if(i==0) {//init
this.add(element); this.add(element);
} else {//recursion } else {//recursion
...@@ -137,7 +137,7 @@ List.prototype.load({ ...@@ -137,7 +137,7 @@ List.prototype.load({
} }
}, },
replace: function(oldElement,newElement) { replace: function(oldElement,newElement) {
if(this.isEmpty()) {error("<<element not found>> when trying to replace",this);return}//init-false if(this.isEmpty()) {errorMessage("<<element not found>> when trying to replace",this);return}//init-false
if(oldElement===this.head()) { if(oldElement===this.head()) {
this.set(0,newElement);//init-true this.set(0,newElement);//init-true
} else { } else {
...@@ -155,34 +155,6 @@ List.prototype.load({ ...@@ -155,34 +155,6 @@ List.prototype.load({
} }
}); });
error: function(message,object) {
errorObject = object;
console.log(message);
}
/**
* returns the current date
*/
currentTime = function() {return (new Date()).toUTCString();}
// save
saveXHR = function(address) {
$.ajax({
url: address,
type: "PUT",
headers: {
Authorization: "Basic "+btoa("smik:asdf")},
fields: {
withCredentials: "true"
},
data: JSON.stringify(getCurrentDocument()),
success: function(){alert("saved");},
error: function(xhr) { alert("error while saving");}
});
};
/** /**
* load a public file with a basic ajax request * load a public file with a basic ajax request
* @param address : the address of the document * @param address : the address of the document
...@@ -199,55 +171,6 @@ loadFile = function(address, type, instruction) { ...@@ -199,55 +171,6 @@ loadFile = function(address, type, instruction) {
}); });
} }
// save
saveFile = function(address, content, instruction) {
$.ajax({
url: address,
type: "PUT",
dataType: "json",
data: JSON.stringify(content),
headers: { Authorization: "Basic "+btoa("smik:asdf")},
fields: { withCredentials: "true" },
success: instruction,
error: function(type) {
if(type.status==201 || type.status==204) {instruction();}//ajax thinks that 201 is an error...
}
});
}
deleteFile = function(address, instruction) {
$.ajax({
url: address,
type: "DELETE",
headers: { Authorization: "Basic "+btoa("smik:asdf")},
fields: { withCredentials: "true" },
success: instruction,
error: function(type) {
alert(type.status);//ajax thinks that 201 is an error...
}
});
}
// load
loadXHR = function(address) {
$.ajax({
url: address,
type: "GET",
dataType: "json",
cache:false,
headers: {
Authorization: "Basic "+btoa("smik:asdf")},
fields: {
withCredentials: "true"
},
success: function(data){
var cDoc = getCurrentDocument();
cDoc.load(data);
cDoc.setAsCurrentDocument();
}
});
}
/* /*
* wait an event before execute an action * wait an event before execute an action
* @param required : function we are waiting for a result * @param required : function we are waiting for a result
...@@ -273,7 +196,7 @@ tryUntilSucceed = function(func) { ...@@ -273,7 +196,7 @@ tryUntilSucceed = function(func) {
var nb = 2;//avoid to test too much times var nb = 2;//avoid to test too much times
var execute = function() { var execute = function() {
try {func.call();} try {func.call();}
catch(e) {if(nb<100) {setTimeout(execute,nb*200);} console.log(e);} catch(e) {if(nb<100) {setTimeout(execute,nb*200);}console.log(e);}
nb*=nb; nb*=nb;
} }
execute(); execute();
...@@ -287,4 +210,43 @@ var resize = function() { ...@@ -287,4 +210,43 @@ var resize = function() {
$("div.main-right").width($(window).width()-$("div.main-left").width()); $("div.main-right").width($(window).width()-$("div.main-left").width());
} }
/**
* Used to debug
*/
errorMessage = function(message,object) {
errorObject = object;
console.log(message);
}
/**
* returns the current date
*/
currentTime = function() {return (new Date()).toUTCString();}
/**
* Paste a toolkit at the mouse position
*/
Tooltip = function() {
this.visible=false; // La variable i nous dit si la bulle est visible ou non
}
Tooltip.prototype = {
isVisible: function() {return this.visible;},
move: function(e) {$("div.toolLocation").css("left",e.pageX+5+"px").css("top",e.pageY + 10+"px");},
show: function(text) {
if(!this.isVisible()) {
$("div.toolLocation")
.css("display","inline")
.css("visibility","visible")
.html(text);
this.visible = true;
}
},
hide: function() {
if(this.isVisible()) {
$("div.toolLocation")
.css("display","none")
.css("visibility","hidden");
this.visible = false;
}
}
}
This diff is collapsed.
...@@ -30,26 +30,24 @@ ...@@ -30,26 +30,24 @@
href="images/ung/favicon.ico" /> href="images/ung/favicon.ico" />
<script type="text/javascript"> <script type="text/javascript">
var initUser = function() {
var user = getCurrentUser();
user.setAsCurrentUser();
}
var init = function() { var init = function() {
//delete localStorage.documentList;//delete the list for tests //delete localStorage.documentList;//delete the list for tests
setCurrentPage(new Page());//provide methods on the page setCurrentPage(new Page("ung"));//provide methods on the page
initUser();//initialize the user getCurrentStorage().getUser().setAsCurrentUser();//initialize the user
if(getCurrentDocumentID()&&getDocumentList().get(getCurrentDocumentID())) { if(getCurrentDocumentID()&&getDocumentList().get(getCurrentDocumentID())) {
/* update the list with the modifications of the last edited document /* update the list with the modifications of the last edited document
* (this method has to been rewritten if using multi users) */ * (this method has to been rewritten if using multi users) */
getDocumentList().update(getCurrentDocumentID()); getDocumentList().updateDocumentInformation(getCurrentDocumentID());
delete localStorage.currentDocumentID; delete localStorage.currentDocumentID;
} }
waitBeforeSucceed(//display the list of documents waitBeforeSucceed(//display the list of documents
function(){return Line.loadHTML()},function() { function(){return Line.loadHTML()},function() {
getDocumentList().resetSelectionList(); getDocumentList().resetSelectionList();
getDocumentList().display();} getDocumentList().updateDisplayInformation();
getDocumentList().display();
resize();}
); );
resize(); resize();
...@@ -124,9 +122,9 @@ ...@@ -124,9 +122,9 @@
<a id="right_message">Not Implemented yet</a> <a id="right_message">Not Implemented yet</a>
<div id="preference_dialog" title="UNG Preferences"></div> <div id="preference_dialog" title="UNG Preferences"></div>
<a id="userName">Unknown</a> <a id="userName">Unknown</a>
| <a id="settings" href="#">Settings</a> | <a id="settings" href="">Settings</a>
| <a id="help" href="#">Help</a> | <a id="help" href="">Help</a>
| <a href="..WebSite_logout">Sign out</a> | <a id="sign_out" href="" onclick="signOut()">Sign out</a>
</div></div> </div></div>
...@@ -174,8 +172,7 @@ ...@@ -174,8 +172,7 @@
<div class="main"> <div class="main">
<!-- Each aggregate of groups is a div wrapper -- <!-- Each aggregate of groups is a div wrapper -->
<table class="wrapper" id="wrapper_main"><tr>-->
<div class="wrapper" id="wrapper_main"> <div class="wrapper" id="wrapper_main">
<!--<td class=" main-left">--> <!--<td class=" main-left">-->
<div class=" main-left"> <div class=" main-left">
...@@ -465,24 +462,26 @@ ...@@ -465,24 +462,26 @@
onclick="getDocumentList().deleteSelectedDocuments()">Delete onclick="getDocumentList().deleteSelectedDocuments()">Delete
</button> </button>
<button name="#" class="change_state">Change State</button> <button name="#" class="change_state">Change State</button>
</div>
</div></div>
<div class="listbox-navigation">
<button class="listbox_first_page your_listbox_first_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<button class="listbox_previous_page your_listbox_previous_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<input class="listbox_set_page your_listbox_set_page" value="1" size="1" onkeypress="if(event.keyCode==13){getDocumentList().changePage(event)}" />
/<span class="listbox_last_page">1</span>
<button class="listbox_next_page your_listbox_next_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
<button class="listbox_last_page your_listbox_last_page" onclick="getDocumentList().changePage(event)">
<span class="image"> </span>
</button>
</div> </div>
<div class="field" title="">
<label> Document List </label>
<div class="input">
<div class="listbox-container">
<div class="listbox-content listbox-content-fixed-width">
<div class="listbox-head"> <div class="listbox-head">
<div class="listbox-head-spacer"></div> <div class="listbox-head-spacer"></div>
<div class="listbox-head-content"> <div class="listbox-head-content">
<!-- Listbox head (in left) --> <!-- Listbox head (in left) -->
...@@ -496,10 +495,6 @@ ...@@ -496,10 +495,6 @@
<span>Document List</span></a> <span>Document List</span></a>
</div> </div>
</div> </div>
<!-- Number of rows in ERP5 mode -->
<!-- List style display mode -->
</div> </div>
<!-- Listbox nagivation (in right) --> <!-- Listbox nagivation (in right) -->
...@@ -533,6 +528,22 @@ ...@@ -533,6 +528,22 @@
</div> </div>
</div>
</div></div>
</div>
<div class="field" title="">
<label> Document List </label>
<div class="input">
<div class="listbox-container">
<div class="listbox-content listbox-content-fixed-width">
<div class="listbox-body"> <div class="listbox-body">
<table class="listbox your_listbox your_listbox-table"> <table class="listbox your_listbox your_listbox-table">
......
This diff is collapsed.
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