1
0

nightly commit

This commit is contained in:
2021-01-23 18:37:12 +08:00
parent db96ec11a5
commit e4bc3f686f
18 changed files with 473 additions and 119 deletions

View File

@@ -114,8 +114,8 @@ class CalendarDatabase(object):
))
return token
else:
# return empty string to indicate fail to login
return ''
# throw a exception to indicate fail to login
raise Exception()
@SafeDatabaseOperation
def common_webLogin(self, username, password):
@@ -130,23 +130,20 @@ class CalendarDatabase(object):
))
return token
else:
# return empty string to indicate fail to login
return ''
# throw a exception to indicate fail to login
raise Exception()
@SafeDatabaseOperation
def common_logout(self, token):
username = self.get_username_from_token(token)
self.cursor.execute('UPDATE user SET [ccn_tokenExpireOn] = 0 WHERE [ccn_name] = ?;', (username, ))
return True
return None
@SafeDatabaseOperation
def common_tokenValid(self, token):
# get user name have check the validation, don't do anything more.
try:
self.get_username_from_token(token)
return True
except:
return False
self.get_username_from_token(token)
return None
@SafeDatabaseOperation
def common_isAdmin(self, token):
@@ -194,13 +191,14 @@ class CalendarDatabase(object):
username = self.get_username_from_token(token)
newuuid = utils.GenerateUUID()
lastupdate = utils.GenerateUUID()
self.cursor.execute('INSERT INTO todo VALUES (?, ?, ?, ?);', (
returnedData = (
newuuid,
username,
'',
lastupdate,
))
return newuuid
)
self.cursor.execute('INSERT INTO todo VALUES (?, ?, ?, ?);', returnedData)
return returnedData
@SafeDatabaseOperation
def todo_update(self, token, uuid, data, lastChange):
@@ -212,14 +210,16 @@ class CalendarDatabase(object):
lastChange
))
if len(self.cursor.fetchall()) == 0:
return False
raise Exception()
# update
self.cursor.execute('UPDATE todo SET [ccn_data] = ? WHERE [ccn_uuid] = ?;', (
newLastChange = utils.GenerateUUID()
self.cursor.execute('UPDATE todo SET [ccn_data] = ?, [ccn_lastChange] = ? WHERE [ccn_uuid] = ?;', (
data,
newLastChange,
uuid
))
return True
return newLastChange
@SafeDatabaseOperation
def todo_delete(self, token, uuid, lastChange):
@@ -231,11 +231,11 @@ class CalendarDatabase(object):
lastChange
))
if len(self.cursor.fetchall()) == 0:
return False
raise Exception()
# delete
self.cursor.execute('DELETE FROM todo WHERE [ccn_uuid] = ?;', (uuid, ))
return True
return None
# =============================== admin

View File

@@ -192,27 +192,69 @@ def api_collection_getSharedHandle():
@app.route('/api/todo/getFull', methods=['POST'])
def api_todo_getFullHandle():
pass
result = (False, None)
if (CheckParameter(('token', ))):
db = get_database()
result = db.todo_getFull(request.form['token'])
return ConstructResponseBody(result)
@app.route('/api/todo/getList', methods=['POST'])
def api_todo_getListHandle():
pass
result = (False, None)
if (CheckParameter(('token', ))):
db = get_database()
result = db.todo_getList(request.form['token'])
return ConstructResponseBody(result)
@app.route('/api/todo/getDetail', methods=['POST'])
def api_todo_getDetailHandle():
pass
result = (False, None)
if (CheckParameter(('token', 'uuid'))):
db = get_database()
result = db.todo_getDetail(
request.form['token'],
request.form['uuid']
)
return ConstructResponseBody(result)
@app.route('/api/todo/add', methods=['POST'])
def api_todo_addHandle():
pass
result = (False, None)
if (CheckParameter(('token', ))):
db = get_database()
result = db.todo_add(request.form['token'])
return ConstructResponseBody(result)
@app.route('/api/todo/update', methods=['POST'])
def api_todo_updateHandle():
pass
result = (False, None)
if (CheckParameter(('token', 'uuid', 'data', 'lastChange'))):
db = get_database()
result = db.todo_update(
request.form['token'],
request.form['uuid'],
request.form['data'],
request.form['lastChange']
)
return ConstructResponseBody(result)
@app.route('/api/todo/delete', methods=['POST'])
def api_todo_deleteHandle():
pass
result = (False, None)
if (CheckParameter(('token', 'uuid', 'lastChange'))):
db = get_database()
result = db.todo_delete(
request.form['token'],
request.form['uuid'],
request.form['lastChange']
)
return ConstructResponseBody(result)
# ================================ admin

View File

@@ -14,6 +14,7 @@ ccn-header-language=Language
ccn-js-failToLogin=Fail to login. Please check your username or password.
ccn-js-failToLogout=Fail to logout due to unknow reason. Consider refreshing page to solve problem.
ccn-js-failToOperate=An operation failed. It may caused by your input wrong data, or system error. Refreshing page may fix system problem. Before refreshing page, please backup all your unsaved data.
ccn-home-desc=<h1 class="title">coconut-leaf</h1><p>A light, self-host calendar system.</p><p>Originally, this app is served for yyc12345 personal use.</p><br /><p>Pull request / issue / translation are welcomed.</p><p>Submit them in our <a href="https://github.com/yyc12345/coconut-leaf">GitHub project</a>.</p><p>This project source code is licensed <a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL v3</a>.</p>
@@ -21,3 +22,19 @@ ccn-login-form-username=Username
ccn-login-form-password=Password
ccn-login-form-login=Login
ccn-todo-todoList=Todo list
ccn-calendar-jump=Jump
ccn-calendar-today=Today
ccn-calendar-add=Add...
ccn-calendar-scheduleList=Schedule
ccn-calendar-tabcontrol-tabCalendar=Calendar
ccn-calendar-tabcontrol-tabShared=Shared
ccn-calendar-tabcontrol-tabSharing=Sharing
ccn-calendar-week-monday=Monday
ccn-calendar-week-tuesday=Tuesday
ccn-calendar-week-wednesday=Wednesday
ccn-calendar-week-thursday=Thursday
ccn-calendar-week-friday=Friday
ccn-calendar-week-saturday=Saturday
ccn-calendar-week-sunday=Sunday

View File

@@ -14,6 +14,7 @@ ccn-header-language=语言
ccn-js-failToLogin=登陆失败,请检查您的用户名和密码。
ccn-js-failToLogout=由于未知原因,登出失败,请考虑刷新页面解决问题。
ccn-js-failToOperate=一个操作失败了,可能是您输入了错误的参数,又或者是系统错误。刷新页面可能会解决系统错误问题。请在刷新前备份好自己的数据。
ccn-home-desc=<h1 class="title">coconut-leaf</h1><p>一个轻量的自建日历系统</p><p>原本是出于yyc12345的个人使用而制作的。</p><br /><p>欢迎提出Pull request / issue / 翻译</p><p>将他们提交到我们的<a href="https://github.com/yyc12345/coconut-leaf">GitHub项目</a>.</p><p>本工程代码使用<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL v3</a>授权。</p>
@@ -21,4 +22,19 @@ ccn-login-form-username=用户名
ccn-login-form-password=密码
ccn-login-form-login=登录
ccn-todo-todoList=待办列表
ccn-calendar-jump=转到
ccn-calendar-today=今天
ccn-calendar-add=添加...
ccn-calendar-scheduleList=日程安排
ccn-calendar-tabcontrol-tabCalendar=日历
ccn-calendar-tabcontrol-tabShared=被共享的
ccn-calendar-tabcontrol-tabSharing=共享给其他人
ccn-calendar-week-monday=星期一
ccn-calendar-week-tuesday=星期二
ccn-calendar-week-wednesday=星期三
ccn-calendar-week-thursday=星期四
ccn-calendar-week-friday=星期五
ccn-calendar-week-saturday=星期六
ccn-calendar-week-sunday=星期日

View File

@@ -49,6 +49,8 @@ function cnn_api_common_login(_username, password) {
}
*/
// ====================================================== common
function cnn_api_common_webLogin(_username, password) {
var gotten_data = undefined;
$.ajax({
@@ -63,7 +65,7 @@ function cnn_api_common_webLogin(_username, password) {
gotten_data = data;
}
});
if (IsResponseOK(gotten_data) && gotten_data['data'] != '') {
if (IsResponseOK(gotten_data)) {
SetApiToken(gotten_data['data']);
return true;
} else return false;
@@ -84,7 +86,7 @@ function cnn_api_common_logout() {
}
});
if (IsResponseOK(gotten_data) && gotten_data['data']) {
if (IsResponseOK(gotten_data)) {
SetApiToken('');
return true;
} return false;
@@ -109,9 +111,106 @@ function cnn_api_common_tokenValid() {
}
});
if (IsResponseOK(gotten_data) && gotten_data['data']) return true;
if (IsResponseOK(gotten_data)) return true;
else {
SetApiToken('');
return false;
}
}
}
// ====================================================== calendar
// ====================================================== collection
// ====================================================== todo
function cnn_api_todo_getFull() {
// return data or undefined
var gotten_data = undefined;
$.ajax({
url: '/api/todo/getFull',
type: "POST",
async: false,
data: {
token: GetApiToken()
},
success: function (data) {
gotten_data = data;
}
});
if (IsResponseOK(gotten_data)) return gotten_data['data'];
else return undefined;
}
function cnn_api_todo_add() {
// return data or undefined
var gotten_data = undefined;
$.ajax({
url: '/api/todo/add',
type: "POST",
async: false,
data: {
token: GetApiToken()
},
success: function (data) {
gotten_data = data;
}
});
if (IsResponseOK(gotten_data)) return gotten_data['data'];
else return undefined;
}
function cnn_api_todo_update(_uuid, _data, _lastChange) {
// return data or undefined
var gotten_data = undefined;
$.ajax({
url: '/api/todo/update',
type: "POST",
async: false,
data: {
token: GetApiToken(),
uuid: _uuid,
data: _data,
lastChange: _lastChange
},
success: function (data) {
gotten_data = data;
}
});
if (IsResponseOK(gotten_data)) return gotten_data['data'];
else return undefined;
}
function cnn_api_todo_delete(_uuid, _lastChange) {
// return true or false
var gotten_data = undefined;
$.ajax({
url: '/api/todo/delete',
type: "POST",
async: false,
data: {
token: GetApiToken(),
uuid: _uuid,
lastChange: _lastChange
},
success: function (data) {
gotten_data = data;
}
});
return IsResponseOK(gotten_data);
}
// ====================================================== admin

View File

@@ -34,7 +34,7 @@ function ccn_i18n_ApplyLanguage() {
language: ccn_i18n_currentLanguage,
callback: function() {
//set usual block
var cache = $(".ccn-i18n");
var cache = $("[i18n-name]");
cache.each(function() {
$(this).html($.i18n.prop($(this).attr('i18n-name')));
});

View File

@@ -8,6 +8,18 @@ $(document).ready(function() {
// process calendar it self
ccn_calendar_LoadCalendarBody();
// bind tab control switcher and set current tab
$("#tabcontrol-tab-1-1").click(function(){
ccn_tabcontrol_SwitchTab(1, 1);
});
$("#tabcontrol-tab-1-2").click(function(){
ccn_tabcontrol_SwitchTab(1, 2);
});
$("#tabcontrol-tab-1-3").click(function(){
ccn_tabcontrol_SwitchTab(1, 3);
});
ccn_tabcontrol_SwitchTab(1, 1);
// apply i18n
ccn_i18n_ApplyLanguage();
});

View File

@@ -6,13 +6,13 @@ $(document).ready(function() {
cnn_headerNav_LoggedRefresh();
// bind login event
$("#ccn-login-form-login").click(StartLogin);
$("#ccn-login-form-login").click(ccn_login_startLogin);
// apply i18n
ccn_i18n_ApplyLanguage();
});
function StartLogin() {
function ccn_login_startLogin() {
// disable all ui first
$("#ccn-login-form-login").attr("disabled",true);
$("#ccn-login-form-username").attr("disabled",true);

View File

@@ -0,0 +1,202 @@
var ccn_todo_todoListCache = [];
$(document).ready(function() {
// nav process
ccn_pages_currentPage = ccn_pages_enumPages.login;
cnn_headerNav_Insert();
cnn_headerNav_BindEvents();
cnn_headerNav_LoggedRefresh();
// refresh once
ccn_todo_Refresh();
// bind event
$("#ccn-todo-btnAdd").click(ccn_todo_Add);
$("#ccn-todo-btnRefresh").click(ccn_todo_Refresh);
// apply i18n
ccn_i18n_ApplyLanguage();
});
function ccn_todo_RefreshCacheList() {
// clean list cache first
ccn_todo_todoListCache = new Array();
var result = cnn_api_todo_getFull();
if(typeof(result) != 'undefined') {
for(var index in result) {
ccn_todo_todoListCache[result[index][0]] = result[index];
}
}
}
function ccn_todo_RenderCacheList() {
// clean list first
$("#ccn-todo-todoList").empty();
var renderdata = {
uuid: undefined,
data: undefined
};
var templates = undefined;
$.ajax({
url: $("#jsrender-tmpl-todoItem").attr('src'),
type: "GET",
async: false,
success: function (data) {
templates = $.templates(data);
}
});
var listDOM = $("#ccn-todo-todoList");
for(var index in ccn_todo_todoListCache) {
// update render data
var item = ccn_todo_todoListCache[index];
renderdata.uuid = item[0];
renderdata.data = item[2];
// render
listDOM.append(templates.render(renderdata));
// set mode
var uuid = renderdata.uuid;
ccn_todo_ChangeDisplayMode(uuid, false);
// bind event
$("#ccn-todo-todoItem-btnEdit-" + uuid).click(ccn_todo_ItemEdit);
$("#ccn-todo-todoItem-btnDelete-" + uuid).click(ccn_todo_ItemDelete);
$("#ccn-todo-todoItem-btnUpdate-" + uuid).click(ccn_todo_ItemUpdate);
$("#ccn-todo-todoItem-btnCancelUpdate-" + uuid).click(ccn_todo_ItemCancelUpdate);
}
}
function ccn_todo_ChangeDisplayMode(uuid, isEdit) {
if(isEdit) {
// 4 buttons
$("#ccn-todo-todoItem-btnEdit-" + uuid).hide();
$("#ccn-todo-todoItem-btnDelete-" + uuid).hide();
$("#ccn-todo-todoItem-btnUpdate-" + uuid).show();
$("#ccn-todo-todoItem-btnCancelUpdate-" + uuid).show();
// 2 elements
$("#ccn-todo-todoItem-p-" + uuid).hide();
$("#ccn-todo-todoItem-textarea-" + uuid).show();
} else {
$("#ccn-todo-todoItem-btnEdit-" + uuid).show();
$("#ccn-todo-todoItem-btnDelete-" + uuid).show();
$("#ccn-todo-todoItem-btnUpdate-" + uuid).hide();
$("#ccn-todo-todoItem-btnCancelUpdate-" + uuid).hide();
$("#ccn-todo-todoItem-p-" + uuid).show();
$("#ccn-todo-todoItem-textarea-" + uuid).hide();
}
}
function ccn_todo_Refresh() {
// refresh and render once
ccn_todo_RefreshCacheList();
ccn_todo_RenderCacheList();
}
function ccn_todo_Add() {
var result = cnn_api_todo_add();
if (typeof(result) == 'undefined') {
// fail
alert($.i18n.prop("ccn-js-failToOperate"));
} else {
// add into cache
ccn_todo_todoListCache[result[0]] = result;
// render
var templates = undefined;
$.ajax({
url: $("#jsrender-tmpl-todoItem").attr('src'),
type: "GET",
async: false,
success: function (data) {
templates = $.templates(data);
}
});
// render
var listDOM = $("#ccn-todo-todoList");
listDOM.append(templates.render({
uuid: result[0],
data: result[2]
}));
// set mode
var uuid = result[0];
ccn_todo_ChangeDisplayMode(uuid, false);
// bind event
$("#ccn-todo-todoItem-btnEdit-" + uuid).click(ccn_todo_ItemEdit);
$("#ccn-todo-todoItem-btnDelete-" + uuid).click(ccn_todo_ItemDelete);
$("#ccn-todo-todoItem-btnUpdate-" + uuid).click(ccn_todo_ItemUpdate);
$("#ccn-todo-todoItem-btnCancelUpdate-" + uuid).click(ccn_todo_ItemCancelUpdate);
}
}
function ccn_todo_ItemEdit() {
var uuid = $(this).attr("uuid");
// copy current data to textarea
$("#ccn-todo-todoItem-textarea-" + uuid).val(
$("#ccn-todo-todoItem-p-" + uuid).text()
);
// switch to edit mode
ccn_todo_ChangeDisplayMode(uuid, true);
}
function ccn_todo_ItemDelete() {
var uuid = $(this).attr("uuid");
var result = cnn_api_todo_delete(
uuid,
ccn_todo_todoListCache[uuid][3]
);
if(typeof(result) == 'undefined') {
// fail
alert($.i18n.prop("ccn-js-failToOperate"));
} else {
// remove body
$("#ccn-todo-todoItem-" + uuid).remove();
}
}
function ccn_todo_ItemUpdate() {
var uuid = $(this).attr("uuid");
var newData = $("#ccn-todo-todoItem-textarea-" + uuid).val();
var result = cnn_api_todo_update(
uuid,
newData,
ccn_todo_todoListCache[uuid][3]
);
if (typeof(result) == 'undefined') {
// fail
alert($.i18n.prop("ccn-js-failToOperate"));
} else {
// safely update data & lastChanged and control
ccn_todo_todoListCache[uuid][2] = newData;
ccn_todo_todoListCache[uuid][3] = result;
$("#ccn-todo-todoItem-p-" + uuid).text(newData);
// switch to normal mode
ccn_todo_ChangeDisplayMode(uuid, false);
}
}
function ccn_todo_ItemCancelUpdate() {
var uuid = $(this).attr("uuid");
// clean data
$("#ccn-todo-todoItem-textarea-" + uuid).val("");
// switch to normal mode
ccn_todo_ChangeDisplayMode(uuid, false);
}

View File

@@ -0,0 +1,10 @@
// all args are based on 1
function ccn_tabcontrol_SwitchTab(tabcontrolGroup, targetTabIndex) {
// close all panel and tab
$(".tabcontrol-tab-" + tabcontrolGroup).removeClass("is-active");
$(".tabcontrol-panel-" + tabcontrolGroup).hide();
// show specific
$("#tabcontrol-tab-" + tabcontrolGroup + "-" + targetTabIndex).addClass("is-active");
$("#tabcontrol-panel-" + tabcontrolGroup + "-" + targetTabIndex).show();
}

View File

@@ -1,3 +1,4 @@
/*
function ComputPasswordWithSalt(password, salt) {
return ComputeSHA256(ComputeSHA256(password) + salt.toString());
}
@@ -13,6 +14,7 @@ function ComputeSHA256(strl) {
var hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
return hashHex.toLowerCase();
}
*/
function IsResponseOK(data) {
if (typeof(data) == 'undefined') {

View File

@@ -14,22 +14,22 @@
<div id="navbarBasicExample" class="navbar-menu">
<div class="navbar-start">
<a i18n-name="ccn-header-nav-home" id="cnn-header-nav-home" class="navbar-item ccn-i18n" href="/web/home"></a>
<a i18n-name="ccn-header-nav-calendar" id="cnn-header-nav-calendar" class="navbar-item ccn-i18n" href="/web/calendar"></a>
<a i18n-name="ccn-header-nav-todo" id="cnn-header-nav-todo" class="navbar-item ccn-i18n" href="/web/todo"></a>
<a i18n-name="ccn-header-nav-admin" id="cnn-header-nav-admin" class="navbar-item ccn-i18n" href="/web/admin"></a>
<a i18n-name="ccn-header-nav-home" id="cnn-header-nav-home" class="navbar-item" href="/web/home"></a>
<a i18n-name="ccn-header-nav-calendar" id="cnn-header-nav-calendar" class="navbar-item" href="/web/calendar"></a>
<a i18n-name="ccn-header-nav-todo" id="cnn-header-nav-todo" class="navbar-item" href="/web/todo"></a>
<a i18n-name="ccn-header-nav-admin" id="cnn-header-nav-admin" class="navbar-item" href="/web/admin"></a>
</div>
<div class="navbar-end">
<p id="cnn-header-user-login" class="navbar-item">
<a class="button is-primary ccn-i18n" i18n-name="ccn-header-user-login" href="/web/login"></a>
<a class="button is-primary" i18n-name="ccn-header-user-login" href="/web/login"></a>
</p>
<p id="cnn-header-user-logout" class="navbar-item">
<a class="button is-primary ccn-i18n" i18n-name="ccn-header-user-logout"></a>
<a class="button is-primary" i18n-name="ccn-header-user-logout"></a>
</p>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link ccn-i18n" i18n-name="ccn-header-language"></a>
<a class="navbar-link" i18n-name="ccn-header-language"></a>
<div id="cnn-header-language" class="navbar-dropdown">
<a language="en-US" class="navbar-item">English</a>

View File

@@ -1,27 +1,20 @@
<div class="todo-item card">
<div id="ccn-todo-todoItem-{{:uuid}}" class="todo-item card">
<div class="todo-item-words">
<p>this is a
namewwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
</p>
<p id="ccn-todo-todoItem-p-{{:uuid}}">{{>data}}</p>
<textarea id="ccn-todo-todoItem-textarea-{{:uuid}}" class="textarea"></textarea>
</div>
<div class="todo-item-icon control">
<div id="ccn-todo-todoItem-btnEdit-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></button>
</div>
<div class="todo-item-icon control">
<div id="ccn-todo-todoItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-trash"></i></button>
</div>
</div>
<div class="todo-item card">
<div class="todo-item-words control">
<textarea class="textarea"></textarea>
</div>
<div class="todo-item-icon control">
<div id="ccn-todo-todoItem-btnUpdate-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></button>
</div>
<div class="todo-item-icon control">
<div id="ccn-todo-todoItem-btnCancelUpdate-{{:uuid}}" uuid="{{:uuid}}" class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-times"></i></button>
</div>
</div>

View File

@@ -20,7 +20,7 @@
<script type="text/javascript" src="/static/js/api.js"></script>
<script type="text/javascript" src="/static/js/headerNav.js"></script>
<script type="text/javascript" src="/static/js/page/login.js"></script>
<script type="text/javascript" src="/static/js/page/admin.js"></script>
<link rel="stylesheet" href="/static/css/admin.css">
</head>

View File

@@ -20,6 +20,7 @@
<script type="text/javascript" src="/static/js/utils.js"></script>
<script type="text/javascript" src="/static/js/api.js"></script>
<script type="text/javascript" src="/static/js/headerNav.js"></script>
<script type="text/javascript" src="/static/js/tabcontrol.js"></script>
<script type="text/javascript" src="/static/js/page/calendar.js"></script>
<link rel="stylesheet" href="/static/css/calendar.css">
@@ -30,14 +31,14 @@
<div class="container" style="margin-top: 20px;">
<div class="tabs">
<ul>
<li class="is-active"><a>Calendar</a></li>
<li><a>Shared</a></li>
<li><a>Sharing</a></li>
<li id="tabcontrol-tab-1-1" class="tabcontrol-tab-1"><a i18n-name="ccn-calendar-tabcontrol-tabCalendar"></a></li>
<li id="tabcontrol-tab-1-2" class="tabcontrol-tab-1"><a i18n-name="ccn-calendar-tabcontrol-tabShared"></a></li>
<li id="tabcontrol-tab-1-3" class="tabcontrol-tab-1"><a i18n-name="ccn-calendar-tabcontrol-tabSharing"></a></li>
</ul>
</div>
</div>
<div id="tabcontrol-1-1" class="container" style="margin-top: 20px; display: none;">
<div id="tabcontrol-panel-1-1" class="container tabcontrol-panel-1" style="margin-top: 20px;">
<nav class="level">
<div class="level-item">
<div class="field has-addons">
@@ -45,33 +46,33 @@
<input class="input" type="date">
</div>
<div class="control">
<button class="button is-info">Jump</button>
<button i18n-name="ccn-calendar-jump" class="button is-info"></button>
</div>
</div>
</div>
<div class="level-item control">
<a class="button is-info">Today</a>
<a i18n-name="ccn-calendar-today" class="button is-info"></a>
</div>
<div class="level-item control">
<a class="button is-primary">Add...</a>
<a i18n-name="ccn-calendar-add" class="button is-primary"></a>
</div>
</nav>
<div id="ccn-calendar-calendarBbody" class="card" style="padding: 1.25rem; display: flex; flex-flow: column;">
<div style="margin: 0 0 0.75em 0;">
<div><b>Monday</b></div>
<div><b>Tuesday</b></div>
<div><b>Wednesday</b></div>
<div><b>Thursday</b></div>
<div><b>Friday</b></div>
<div><b style="color: red;">Saturday</b></div>
<div><b style="color: red;">Sunday</b></div>
<div><b i18n-name="ccn-calendar-week-monday"></b></div>
<div><b i18n-name="ccn-calendar-week-tuesday"></b></div>
<div><b i18n-name="ccn-calendar-week-wednesday"></b></div>
<div><b i18n-name="ccn-calendar-week-thursday"></b></div>
<div><b i18n-name="ccn-calendar-week-friday"></b></div>
<div><b i18n-name="ccn-calendar-week-saturday" style="color: red;"></b></div>
<div><b i18n-name="ccn-calendar-week-sunday" style="color: red;"></b></div>
</div>
</div>
<div class="container" style="padding: 1.25rem; display: flex; flex-flow: column; margin-top: 1.25rem;">
<h1 class="title">Schedule</h1>
<h1 i18n-name="ccn-calendar-scheduleList" class="title"></h1>
<div id="schedule-list">
<div class="schedule-day container">
@@ -170,7 +171,7 @@
</div>
<div id="tabcontrol-1-2" class="container" style="margin-top: 20px; display: none;">
<div id="tabcontrol-panel-1-2" class="container tabcontrol-panel-1" style="margin-top: 20px;">
<div class="container" style="display: flex; flex-flow: column;">
<h1 class="title">Shared</h1>
@@ -211,7 +212,7 @@
</div>
<div id="tabcontrol-1-3" class="container" style="margin-top: 20px; display: none;">
<div id="tabcontrol-panel-1-3" class="container tabcontrol-panel-1" style="margin-top: 20px;">
<div class="container" style="display: flex; flex-flow: column;">
<h1 class="title">Owned</h1>

View File

@@ -24,7 +24,7 @@
<body>
<div class="container" style="margin-top: 1.25rem;">
<article class="ccn-i18n" i18n-name="ccn-home-desc">
<article i18n-name="ccn-home-desc">
</article>
</div>
</body>

View File

@@ -27,7 +27,7 @@
<div style="height: 100%; width: 100%; display: flex; justify-content: center; align-items: center;">
<div class="card" style="padding: 1.25rem;">
<div class="field">
<label class="label ccn-i18n" i18n-name="ccn-login-form-username"></label>
<label class="label" i18n-name="ccn-login-form-username"></label>
<div class="control has-icons-left has-icons-right">
<input id="ccn-login-form-username" class="input" type="text">
<span class="icon is-small is-left">
@@ -36,7 +36,7 @@
</div>
</div>
<div class="field">
<label class="label ccn-i18n" i18n-name="ccn-login-form-password"></label>
<label class="label" i18n-name="ccn-login-form-password"></label>
<p class="control has-icons-left">
<input id="ccn-login-form-password" class="input" type="password">
<span class="icon is-small is-left">
@@ -46,7 +46,7 @@
</div>
<div class="control">
<button id="ccn-login-form-login" class="button is-primary ccn-i18n" i18n-name="ccn-login-form-login"></button>
<button id="ccn-login-form-login" class="button is-primary" i18n-name="ccn-login-form-login"></button>
</div>
</div>

View File

@@ -20,66 +20,26 @@
<script type="text/javascript" src="/static/js/api.js"></script>
<script type="text/javascript" src="/static/js/headerNav.js"></script>
<script type="text/javascript" src="/static/js/page/login.js"></script>
<script type="text/javascript" src="/static/js/page/todo.js"></script>
<link rel="stylesheet" href="/static/css/todo.css">
</head>
<body>
<div class="container" style="display: flex; flex-flow: column; margin-top: 1.25rem;">
<h1 class="title">Todo list</h1>
<h1 i18n-name="ccn-todo-todoList" class="title ccn-i18n"></h1>
<div class="control-list">
<div class="control">
<div id="ccn-todo-btnAdd" class="control">
<a class="button is-primary"><span class="icon is-small"><i class="fas fa-plus"></i></span></a>
</div>
<div class="control">
<div id="ccn-todo-btnRefresh" class="control">
<a class="button is-primary">
<span class="icon is-small"><i class="fas fa-sync"></i></span>
</a>
</div>
</div>
<div style="display: flex; flex-flow: column; margin-top: 1.25rem;">
<div class="todo-item card">
<div class="todo-item-words">
<p>this is a name</p>
</div>
<div class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></button>
</div>
<div class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-trash"></i></span></button>
</div>
</div>
<div class="todo-item card">
<div class="todo-item-words">
<p>this is a
namewwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
</p>
</div>
<div class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></button>
</div>
<div class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-trash"></i></button>
</div>
</div>
<div class="todo-item card">
<div class="todo-item-words control">
<textarea class="textarea"></textarea>
</div>
<div class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></button>
</div>
<div class="todo-item-icon control">
<button class="button"><span class="icon is-small"><i class="fas fa-times"></i></button>
</div>
</div>
<div id="ccn-todo-todoList" style="display: flex; flex-flow: column; margin-top: 1.25rem;">
</div>
</div>