refactor: introduce modern frontend
This commit is contained in:
62
frontend-legacy/static/css/admin.css
Normal file
62
frontend-legacy/static/css/admin.css
Normal file
@@ -0,0 +1,62 @@
|
||||
div.user-item {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
div.user-item-words {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: flex-start;
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.user-item-icon {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
div.token-item {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
div.token-item-words {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: flex-start;
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.token-item-icon {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
div.control-list {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.control-list > * {
|
||||
margin-right: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
159
frontend-legacy/static/css/calendar.css
Normal file
159
frontend-legacy/static/css/calendar.css
Normal file
@@ -0,0 +1,159 @@
|
||||
#ccn-calendar-calendarBody > div:nth-child(n+2) > div {
|
||||
border-top: 0 solid black;
|
||||
border-left: 0 solid black;
|
||||
border-right: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
|
||||
padding: 0.75em;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: flex-start;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#ccn-calendar-calendarBody > div:nth-child(n+2) > div:nth-child(1) {
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
|
||||
#ccn-calendar-calendarBody > div:nth-child(2) > div {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
||||
#ccn-calendar-calendarBody > div > div {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#ccn-calendar-calendarBody > div > div[isCurrentMonth=false] {
|
||||
background: #d0d0d0;
|
||||
}
|
||||
|
||||
#ccn-calendar-calendarBody > div {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
div.calendarItem-eventBox {
|
||||
border: 1px solid black;
|
||||
border-radius: 2px;
|
||||
margin-top: 0.2rem;
|
||||
height: 0.75rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.calendarItem-eventBox[enableDisplay=true] {
|
||||
visibility: visible;
|
||||
}
|
||||
div.calendarItem-eventBox[enableDisplay=false] {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
div.schedule-day {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
div.schedule-day-words {
|
||||
margin-top: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
div.schedule-event-list {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
div.schedule-event-outter {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
div.schedule-event-inner {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
div.schedule-event-words {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: flex-start;
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.schedule-event-icon {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
div.schedule-event-color {
|
||||
width: 0.75rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#ccn-calendar-scheduleList div.schedule-day:nth-child(n+2) {
|
||||
border-top: 1px solid rgba(219,219,219,.5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
div.collection-item {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
div.collection-item-words {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.collection-item-icon {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
div.control-list {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.control-list > * {
|
||||
margin-right: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
34
frontend-legacy/static/css/collection.css
Normal file
34
frontend-legacy/static/css/collection.css
Normal file
@@ -0,0 +1,34 @@
|
||||
div.collection-item {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
div.collection-item-words {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.collection-item-icon {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
div.control-list {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.control-list > * {
|
||||
margin-right: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
117
frontend-legacy/static/css/datetimepicker.css
Normal file
117
frontend-legacy/static/css/datetimepicker.css
Normal file
@@ -0,0 +1,117 @@
|
||||
div.perfectTable {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
/*
|
||||
div.perfectTable > div > div:nth-child(1) {
|
||||
border-left: 1px solid black;
|
||||
}
|
||||
|
||||
div.perfectTable > div:nth-child(1) > div {
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
*/
|
||||
|
||||
div.perfectTable > div > div {
|
||||
/*border-top: 0 solid black;
|
||||
border-left: 0 solid black;
|
||||
border-right: 1px solid black;
|
||||
border-bottom: 1px solid black;
|
||||
|
||||
padding: 0.75em;*/
|
||||
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
div.perfectTable > div {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
|
||||
div.perfectTable > div > div[picked=true] {
|
||||
background: hsl(171, 100%, 41%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
div.pickerContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-flow: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
div.pickerContainer > div {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 0;
|
||||
}
|
||||
|
||||
div.pickerContainer > svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div.pickerContainer > svg > text {
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
div.pickerContainer > svg > circle[type=background] {
|
||||
stroke-width: 0;
|
||||
fill: #d0d0d0;
|
||||
}
|
||||
|
||||
div.pickerContainer > svg > circle[type=symbol] {
|
||||
stroke-width: 0;
|
||||
fill: hsl(171, 100%, 41%); /* $primary */
|
||||
}
|
||||
|
||||
div.pickerContainer > svg > line {
|
||||
stroke-width: 0.125em;
|
||||
stroke: hsl(171, 100%, 41%); /* $primary */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
header.pickerHeader {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
|
||||
flex-grow: 0;
|
||||
flex-basis: 0;
|
||||
flex-shrink: 0;
|
||||
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
header.pickerHeader > div {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
17
frontend-legacy/static/css/event.css
Normal file
17
frontend-legacy/static/css/event.css
Normal file
@@ -0,0 +1,17 @@
|
||||
div.control-list {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.control-list > * {
|
||||
margin-right: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ccn-event-eventFormBody > section {
|
||||
border-top: 1px solid rgba(219,219,219,.5);
|
||||
}
|
||||
32
frontend-legacy/static/css/todo.css
Normal file
32
frontend-legacy/static/css/todo.css
Normal file
@@ -0,0 +1,32 @@
|
||||
div.todo-item {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
div.todo-item-words {
|
||||
flex-grow: 1;
|
||||
flex-basis: 0;
|
||||
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
div.todo-item-icon {
|
||||
margin-left: 0.75rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
div.control-list {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.control-list > * {
|
||||
margin-right: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
140
frontend-legacy/static/i18n/strings_en-US.properties
Normal file
140
frontend-legacy/static/i18n/strings_en-US.properties
Normal file
@@ -0,0 +1,140 @@
|
||||
ccn-i18n-pageName-home=coconut-leaf - A light, self-host calendar system.
|
||||
ccn-i18n-pageName-collection=coconut-leaf - Collection
|
||||
ccn-i18n-pageName-calendar=coconut-leaf - Calendar
|
||||
ccn-i18n-pageName-event=coconut-leaf - Event
|
||||
ccn-i18n-pageName-todo=coconut-leaf - Todo
|
||||
ccn-i18n-pageName-admin=coconut-leaf - Admin
|
||||
ccn-i18n-pageName-login=coconut-leaf - Login
|
||||
|
||||
ccn-i18n-header-nav-home=Home
|
||||
ccn-i18n-header-nav-collection=Collection
|
||||
ccn-i18n-header-nav-calendar=Calendar
|
||||
ccn-i18n-header-nav-todo=Todo
|
||||
ccn-i18n-header-nav-admin=Admin
|
||||
ccn-i18n-header-user-login=Login
|
||||
ccn-i18n-header-user-logout=Logout
|
||||
ccn-i18n-header-language=Language
|
||||
|
||||
ccn-i18n-universal-text-year=Year
|
||||
ccn-i18n-universal-text-month=Month
|
||||
ccn-i18n-universal-text-day=Day
|
||||
ccn-i18n-universal-text-hour=Hour
|
||||
ccn-i18n-universal-text-minute=Minute
|
||||
ccn-i18n-universal-week-1=Monday
|
||||
ccn-i18n-universal-week-2=Tuesday
|
||||
ccn-i18n-universal-week-3=Wednesday
|
||||
ccn-i18n-universal-week-4=Thursday
|
||||
ccn-i18n-universal-week-5=Friday
|
||||
ccn-i18n-universal-week-6=Saturday
|
||||
ccn-i18n-universal-week-7=Sunday
|
||||
ccn-i18n-universal-month-1=January
|
||||
ccn-i18n-universal-month-2=February
|
||||
ccn-i18n-universal-month-3=March
|
||||
ccn-i18n-universal-month-4=April
|
||||
ccn-i18n-universal-month-5=May
|
||||
ccn-i18n-universal-month-6=June
|
||||
ccn-i18n-universal-month-7=July
|
||||
ccn-i18n-universal-month-8=August
|
||||
ccn-i18n-universal-month-9=September
|
||||
ccn-i18n-universal-month-10=October
|
||||
ccn-i18n-universal-month-11=November
|
||||
ccn-i18n-universal-month-12=December
|
||||
|
||||
ccn-i18n-messagebox-confirm=OK
|
||||
ccn-i18n-messagebox-title=Notification
|
||||
|
||||
ccn-i18n-datetimepicker-confirm=OK
|
||||
ccn-i18n-datetimepicker-cancel=Cancel
|
||||
|
||||
ccn-i18n-js-fail-login=Fail to login. Please check your username or password.
|
||||
ccn-i18n-js-fail-logout=Fail to logout due to unknow reason. Consider refreshing page to solve problem.
|
||||
ccn-i18n-js-fail-get=A get operation failed. It may caused by server internal error or your limited permission. Refreshing page may fix system problem. Before refreshing page, please backup all your unsaved data.
|
||||
ccn-i18n-js-fail-add=An add operation failed. It may caused by wrong arguments. Refreshing page may fix system problem. Before refreshing page, please backup all your unsaved data.
|
||||
ccn-i18n-js-fail-update=An update operation failed. It may caused by wrong arguments or lost target. Refreshing page may fix system problem. Before refreshing page, please backup all your unsaved data.
|
||||
ccn-i18n-js-fail-delete=A delete operation failed. It may caused by no matched item. Refreshing page may fix system problem. Before refreshing page, please backup all your unsaved data.
|
||||
ccn-i18n-js-success=Operation OK.
|
||||
ccn-i18n-js-fail-form=Your filled event form is not fufilled or have error. Please check it and try again.
|
||||
|
||||
ccn-i18n-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>
|
||||
|
||||
ccn-i18n-login-form-username=Username
|
||||
ccn-i18n-login-form-password=Password
|
||||
ccn-i18n-login-form-login=Login
|
||||
|
||||
ccn-i18n-todo-todoList=Todo list
|
||||
|
||||
ccn-i18n-calendar-calendar-today=Today
|
||||
ccn-i18n-calendar-calendar-add=Add...
|
||||
ccn-i18n-calendar-calendar-stripedEvents={0} items
|
||||
ccn-i18n-calendar-calendar-scheduleList=Schedule
|
||||
ccn-i18n-calendar-tabcontrol-tabCalendar=Calendar
|
||||
ccn-i18n-calendar-tabcontrol-tabCollection=Collection
|
||||
ccn-i18n-calendar-tabcontrol-tabDisplay=Display
|
||||
ccn-i18n-calendar-owned-list=My collections
|
||||
ccn-i18n-calendar-shared-list=Shared collections
|
||||
ccn-i18n-calendar-display-firstDayOfWeek=The first day of week
|
||||
ccn-i18n-calendar-display-subcalendar=Sub-Calendar
|
||||
|
||||
ccn-i18n-calendar-display-subcalendar-chineseLunisolarCalendar=Chinese Lunisolar Calendar
|
||||
|
||||
ccn-i18n-collection-owned-list=Owned
|
||||
ccn-i18n-collection-sharing-list=Sharing target
|
||||
ccn-i18n-collection-sharing-editing=Editing:
|
||||
|
||||
ccn-i18n-event-header=Edit Event
|
||||
ccn-i18n-event-title=Title
|
||||
ccn-i18n-event-description=Description
|
||||
ccn-i18n-event-color=Color
|
||||
ccn-i18n-event-collection=Collection
|
||||
ccn-i18n-event-startDateTime=Start Date Time
|
||||
ccn-i18n-event-endDateTime=Stop Date Time
|
||||
ccn-i18n-event-btnSpot=Spot
|
||||
ccn-i18n-event-btnFullDay=Full day
|
||||
ccn-i18n-event-loop=Event Loop
|
||||
ccn-i18n-event-loop-never=Never
|
||||
ccn-i18n-event-loop-day=Day
|
||||
ccn-i18n-event-loop-week=Week
|
||||
ccn-i18n-event-loop-month=Month
|
||||
ccn-i18n-event-loop-year=Year
|
||||
ccn-i18n-event-loopDay-span=Day span
|
||||
ccn-i18n-event-loopWeek-span=Week span
|
||||
ccn-i18n-event-loopWeek-option=Week options
|
||||
ccn-i18n-event-loopMonth-span=Month span
|
||||
ccn-i18n-event-loopWeek-option=Month mode
|
||||
ccn-i18n-event-loopWeek-optionA=Day {0} in month
|
||||
ccn-i18n-event-loopWeek-optionB=Day {0} from the end of the month
|
||||
ccn-i18n-event-loopWeek-optionC=Day {1} in week {0}
|
||||
ccn-i18n-event-loopWeek-optionD=Day {1} in week {0} from the end of the month
|
||||
ccn-i18n-event-loopYear-span=Year span
|
||||
ccn-i18n-event-loopStop=Event Loop Stop
|
||||
ccn-i18n-event-loopStop-forever=Forever
|
||||
ccn-i18n-event-loopStop-datetime=Date Time
|
||||
ccn-i18n-event-loopStop-times=Times
|
||||
ccn-i18n-event-timezone-title=Timezone
|
||||
ccn-i18n-event-timezone-warning=The timezone of this event is not corresponding with your current timezone. All of date and time in this page are shown as the original timezone of this event. You can choose a timezone option in follwing content. If you are not familar with this, please pick keep timezone.
|
||||
ccn-i18n-event-timezone-keep=Keep timezone
|
||||
ccn-i18n-event-timezone-replace=Use my timezone
|
||||
ccn-i18n-event-strictMode-title=Strict Mode in Event Loop
|
||||
ccn-i18n-event-strictMode-warning=You can choose strict mode or rough mode in following content. This is only effect on looped event.
|
||||
ccn-i18n-event-strictMode-strict=Strict Mode. If ordered day is not existing, skip it.
|
||||
ccn-i18n-event-strictMode-rough=Rough mode. If ordered day is not existing, choose the day closing with original day to arrange event.
|
||||
ccn-i18n-event-btnSubmit=Submit
|
||||
ccn-i18n-event-btnCancel=Cancel
|
||||
|
||||
ccn-i18n-sharedItem-sharedBy=Shared by:
|
||||
|
||||
ccn-i18n-admin-tabcontrol-tabProfile=My Profile
|
||||
ccn-i18n-admin-tabcontrol-tabToken=Manage Multi-login
|
||||
ccn-i18n-admin-tabcontrol-tabUserList=Manager User
|
||||
ccn-i18n-admin-changePassword=Change Password
|
||||
ccn-i18n-admin-manageToken=Manage multi-login
|
||||
ccn-i18n-admin-manageToken-desc=Manage the multi-login of the current account. You can forced logout some login in there.
|
||||
ccn-i18n-admin-userList=User List
|
||||
|
||||
ccn-i18n-userItem-newPassword=New Password
|
||||
ccn-i18n-userItem-isAdmin=Is Admin
|
||||
|
||||
ccn-i18n-tokenItem-ua=User Agent:
|
||||
ccn-i18n-tokenItem-ip=IP:
|
||||
ccn-i18n-tokenItem-expireOn=Expire On:
|
||||
ccn-i18n-tokenItem-isMe=This is the login credentials you are currently using.
|
||||
153
frontend-legacy/static/i18n/strings_zh-CN.properties
Normal file
153
frontend-legacy/static/i18n/strings_zh-CN.properties
Normal file
@@ -0,0 +1,153 @@
|
||||
ccn-i18n-pageName-home=coconut-leaf - 一个轻量的自建日历系统
|
||||
ccn-i18n-pageName-collection=coconut-leaf - 集合
|
||||
ccn-i18n-pageName-calendar=coconut-leaf - 日历
|
||||
ccn-i18n-pageName-event=coconut-leaf - 事件
|
||||
ccn-i18n-pageName-todo=coconut-leaf - 待办
|
||||
ccn-i18n-pageName-admin=coconut-leaf - 管理
|
||||
ccn-i18n-pageName-login=coconut-leaf - 登录
|
||||
|
||||
ccn-i18n-header-nav-home=主页
|
||||
ccn-i18n-header-nav-collection=集合
|
||||
ccn-i18n-header-nav-calendar=日历
|
||||
ccn-i18n-header-nav-todo=待办
|
||||
ccn-i18n-header-nav-admin=管理
|
||||
ccn-i18n-header-user-login=登录
|
||||
ccn-i18n-header-user-logout=登出
|
||||
ccn-i18n-header-language=语言
|
||||
|
||||
ccn-i18n-universal-text-year=年
|
||||
ccn-i18n-universal-text-month=月
|
||||
ccn-i18n-universal-text-day=日
|
||||
ccn-i18n-universal-text-hour=时
|
||||
ccn-i18n-universal-text-minute=分
|
||||
ccn-i18n-universal-week-1=星期一
|
||||
ccn-i18n-universal-week-2=星期二
|
||||
ccn-i18n-universal-week-3=星期三
|
||||
ccn-i18n-universal-week-4=星期四
|
||||
ccn-i18n-universal-week-5=星期五
|
||||
ccn-i18n-universal-week-6=星期六
|
||||
ccn-i18n-universal-week-7=星期日
|
||||
ccn-i18n-universal-month-1=1月
|
||||
ccn-i18n-universal-month-2=2月
|
||||
ccn-i18n-universal-month-3=3月
|
||||
ccn-i18n-universal-month-4=4月
|
||||
ccn-i18n-universal-month-5=5月
|
||||
ccn-i18n-universal-month-6=6月
|
||||
ccn-i18n-universal-month-7=7月
|
||||
ccn-i18n-universal-month-8=8月
|
||||
ccn-i18n-universal-month-9=9月
|
||||
ccn-i18n-universal-month-10=10月
|
||||
ccn-i18n-universal-month-11=11月
|
||||
ccn-i18n-universal-month-12=12月
|
||||
|
||||
ccn-i18n-messagebox-confirm=确认
|
||||
ccn-i18n-messagebox-title=通知
|
||||
|
||||
ccn-i18n-datetimepicker-confirm=确认
|
||||
ccn-i18n-datetimepicker-cancel=取消
|
||||
|
||||
ccn-i18n-js-fail-login=登陆失败,请检查您的用户名和密码。
|
||||
ccn-i18n-js-fail-logout=由于未知原因,登出失败,请考虑刷新页面解决问题。
|
||||
ccn-i18n-js-fail-get=一个获取操作失败了,可能是系统错误或者您的权限不足。刷新页面可能会解决问题。请在刷新页面前备份好自己的数据。
|
||||
ccn-i18n-js-fail-add=一个添加操作失败了,可能是您输入的参数有误。刷新页面可能会解决问题。请在刷新页面前备份好自己的数据。
|
||||
ccn-i18n-js-fail-update=一个更新操作失败了,可能是没有找到匹配的条目或者您的参数输入错误。刷新页面可能会解决问题。请在刷新页面前备份好自己的数据。
|
||||
ccn-i18n-js-fail-delete=一个删除操作失败了,可能是没有找到对应条目。刷新页面可能会解决问题。请在刷新页面前备份好自己的数据。
|
||||
ccn-i18n-js-success=操作成功
|
||||
ccn-i18n-js-fail-form=您所填写的事件内容存在缺漏或有错误字段,请检查后再提交。
|
||||
|
||||
ccn-i18n-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>
|
||||
|
||||
ccn-i18n-login-form-username=用户名
|
||||
ccn-i18n-login-form-password=密码
|
||||
ccn-i18n-login-form-login=登录
|
||||
|
||||
ccn-i18n-todo-todoList=待办列表
|
||||
|
||||
ccn-i18n-calendar-calendar-today=今天
|
||||
ccn-i18n-calendar-calendar-add=添加...
|
||||
ccn-i18n-calendar-calendar-stripedEvents=共{0}项
|
||||
ccn-i18n-calendar-calendar-scheduleList=日程安排
|
||||
ccn-i18n-calendar-tabcontrol-tabCalendar=日历
|
||||
ccn-i18n-calendar-tabcontrol-tabCollection=集合
|
||||
ccn-i18n-calendar-tabcontrol-tabDisplay=显示设置
|
||||
ccn-i18n-calendar-owned-list=我的集合
|
||||
ccn-i18n-calendar-shared-list=被共享的集合
|
||||
ccn-i18n-calendar-display-firstDayOfWeek=每周开始星期
|
||||
ccn-i18n-calendar-display-subcalendar=副日历
|
||||
|
||||
ccn-i18n-calendar-display-subcalendar-chineseLunisolarCalendar=中国农历
|
||||
|
||||
ccn-i18n-collection-owned-list=我的集合
|
||||
ccn-i18n-collection-sharing-list=分享目标
|
||||
ccn-i18n-collection-sharing-editing=正在编辑集合:
|
||||
|
||||
ccn-i18n-event-header=编辑事件
|
||||
ccn-i18n-event-title=标题
|
||||
ccn-i18n-event-description=描述
|
||||
ccn-i18n-event-color=颜色
|
||||
ccn-i18n-event-collection=集合
|
||||
ccn-i18n-event-startDateTime=开始时间
|
||||
ccn-i18n-event-endDateTime=结束时间
|
||||
ccn-i18n-event-btnSpot=时间点
|
||||
ccn-i18n-event-btnFullDay=全天
|
||||
ccn-i18n-event-loop=事件循环
|
||||
ccn-i18n-event-loop-never=从不
|
||||
ccn-i18n-event-loop-day=按天
|
||||
ccn-i18n-event-loop-week=按周
|
||||
ccn-i18n-event-loop-month=按月
|
||||
ccn-i18n-event-loop-year=按年
|
||||
ccn-i18n-event-loopDay-span=间隔天数
|
||||
ccn-i18n-event-loopWeek-span=间隔周数
|
||||
ccn-i18n-event-loopWeek-option=在下列这些星期上循环
|
||||
ccn-i18n-event-loopMonth-span=间隔月数
|
||||
ccn-i18n-event-loopWeek-option=月份模式
|
||||
ccn-i18n-event-loopWeek-optionA=第{0}天
|
||||
ccn-i18n-event-loopWeek-optionB=倒数第{0}天
|
||||
ccn-i18n-event-loopWeek-optionC=第{0}个星期{1}
|
||||
ccn-i18n-event-loopWeek-optionD=倒数第{0}个星期{1}
|
||||
ccn-i18n-event-loopYear-span=间隔年数
|
||||
ccn-i18n-event-loopStop=事件循环停止方式
|
||||
ccn-i18n-event-loopStop-forever=永不停止
|
||||
ccn-i18n-event-loopStop-datetime=指定时间
|
||||
ccn-i18n-event-loopStop-times=指定次数
|
||||
ccn-i18n-event-timezone-title=时区设定
|
||||
ccn-i18n-event-timezone-warning=您当前设置的事件的时区与您的时区不匹配,本页面以事件的原时区进行时间显示。您可以在下面修改您对于此事件的时区选择,如果您不熟悉时区,请选择保持原有时区。
|
||||
ccn-i18n-event-timezone-keep=保持原有时区
|
||||
ccn-i18n-event-timezone-replace=使用我现在的时区
|
||||
ccn-i18n-event-strictMode-title=循环的严格与宽松
|
||||
ccn-i18n-event-strictMode-warning=允许您在严格模式与宽松模式种进行选择,此选择只对循环事件有效。
|
||||
ccn-i18n-event-strictMode-strict=严格模式,严格遵守日期要求,如果日期不存在,就不安排。
|
||||
ccn-i18n-event-strictMode-rough=宽松模式,不在意日期要求的精确性,如果日期不存在,则找到最近的符合条件的日子安排。
|
||||
ccn-i18n-event-btnSubmit=提交
|
||||
ccn-i18n-event-btnCancel=取消
|
||||
|
||||
ccn-i18n-sharedItem-sharedBy=共享人:
|
||||
|
||||
ccn-i18n-admin-tabcontrol-tabProfile=我的资料
|
||||
ccn-i18n-admin-tabcontrol-tabToken=管理多端登录
|
||||
ccn-i18n-admin-tabcontrol-tabUserList=管理用户
|
||||
ccn-i18n-admin-changePassword=更改密码
|
||||
ccn-i18n-admin-manageToken=管理多端登录
|
||||
ccn-i18n-admin-manageToken-desc=管理当前帐号的多端登录。您可以在这里强制下线某些地方的帐号。
|
||||
ccn-i18n-admin-userList=用户列表
|
||||
|
||||
ccn-i18n-userItem-newPassword=新密码
|
||||
ccn-i18n-userItem-isAdmin=是管理员
|
||||
|
||||
ccn-i18n-tokenItem-ua=UA:
|
||||
ccn-i18n-tokenItem-ip=IP:
|
||||
ccn-i18n-tokenItem-expireOn=过期时间:
|
||||
ccn-i18n-tokenItem-isMe=这是你当前使用的登录凭据
|
||||
|
||||
ccn-i18n-datetime-loopStopRuleText-infinity=永远循环。
|
||||
ccn-i18n-datetime-loopStopRuleText-datetime=到{0}停止循环。
|
||||
ccn-i18n-datetime-loopStopRuleText-times=循环{0}次。
|
||||
ccn-i18n-datetime-loopRuleText-modeStrict=严格模式。
|
||||
ccn-i18n-datetime-loopRuleText-modeRough=宽松模式。
|
||||
ccn-i18n-datetime-loopRuleText-year=每{0}年于{1}循环一次。
|
||||
ccn-i18n-datetime-loopRuleText-monthA=每{0}月的第{1}日循环一次。
|
||||
ccn-i18n-datetime-loopRuleText-monthB=每{0}月的倒数第{1}日循环一次。
|
||||
ccn-i18n-datetime-loopRuleText-monthC=每{0}月的第{1}个星期{2}循环一次。
|
||||
ccn-i18n-datetime-loopRuleText-monthD=每{0}月的倒数第{1}个星期{2}循环一次。
|
||||
ccn-i18n-datetime-loopRuleText-week=每{0}周的{1}循环一次。
|
||||
ccn-i18n-datetime-loopRuleText-day=每{0}天循环一次。
|
||||
483
frontend-legacy/static/js/api.js
Normal file
483
frontend-legacy/static/js/api.js
Normal file
@@ -0,0 +1,483 @@
|
||||
// the api use bool to return status: fail: return false, true: return data(including true and false)
|
||||
// the api use other type to return data: fail: return undefined, true: return data(if the returned value have change be null, return undefined instaed).
|
||||
|
||||
// var cached_salt = undefined
|
||||
|
||||
/*
|
||||
function ccn_api_common_salt(_username) {
|
||||
// true or false
|
||||
// gotten salt store in cached_salt.
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: '/api/common/salt',
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: {
|
||||
username: _username
|
||||
},
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
|
||||
if (IsResponseOK(gotten_data)) {
|
||||
cached_salt = gotten_data['data'];
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
function ccn_api_common_login(_username, password) {
|
||||
// return true or false, token is managed by this js file self.
|
||||
// if cached_salt is undefined, return false directly
|
||||
if (typeof(cached_salt) == undefined) return false;
|
||||
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: '/api/common/login',
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: {
|
||||
username: _username,
|
||||
password: ComputPasswordWithSalt(password, cached_salt)
|
||||
},
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
if (IsResponseOK(gotten_data) && gotten_data['data'] != '') {
|
||||
ccn_localstorageAssist_SetApiToken(gotten_data['data']);
|
||||
cached_salt = undefined;
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
*/
|
||||
|
||||
// ============================================ template
|
||||
// all api can be implemented by these 2 function, except 3 token related func.
|
||||
// so all api func should use these 2 func except 3 token process api.
|
||||
function ccn_api_dataTemplate(_url, _data) {
|
||||
// return data or undefined
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: _url,
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: _data,
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
|
||||
if (IsResponseOK(gotten_data) && !(gotten_data['data'] === null)) return gotten_data['data'];
|
||||
else return undefined;
|
||||
}
|
||||
|
||||
function ccn_api_boolTemplate(_url, _data) {
|
||||
// return true or false
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: _url,
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: _data,
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
|
||||
return (IsResponseOK(gotten_data) && gotten_data['data']);
|
||||
}
|
||||
|
||||
// deserialize & serialize calendar description function
|
||||
|
||||
function ccn_api_serializeDescription(_description, _color) {
|
||||
var sobj = {
|
||||
description: _description,
|
||||
color: _color
|
||||
}
|
||||
return JSON.stringify(sobj);
|
||||
}
|
||||
|
||||
function ccn_api_deserializeDescription(strl) {
|
||||
try {
|
||||
return $.parseJSON(strl);
|
||||
} catch(err) {
|
||||
return {
|
||||
description: "",
|
||||
color: DefaultColor
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ====================================================== common
|
||||
|
||||
function ccn_api_common_webLogin(_username, _password) {
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: '/api/common/webLogin',
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: {
|
||||
username: _username,
|
||||
password: _password
|
||||
},
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
if (IsResponseOK(gotten_data)) {
|
||||
ccn_localstorageAssist_SetApiToken(gotten_data['data']);
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
function ccn_api_common_logout() {
|
||||
// return true or false
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: '/api/common/logout',
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: {
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
},
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
|
||||
if (IsResponseOK(gotten_data) && gotten_data['data']) {
|
||||
ccn_localstorageAssist_SetApiToken('');
|
||||
return true;
|
||||
} return false;
|
||||
}
|
||||
|
||||
function ccn_api_common_tokenValid() {
|
||||
// get from local database first, then judge it via post
|
||||
// return true or false
|
||||
var gotten_token = ccn_localstorageAssist_GetApiToken();
|
||||
if (gotten_token == '') return false;
|
||||
|
||||
var gotten_data = undefined;
|
||||
$.ajax({
|
||||
url: '/api/common/tokenValid',
|
||||
type: "POST",
|
||||
async: false,
|
||||
data: {
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
},
|
||||
success: function (data) {
|
||||
gotten_data = data;
|
||||
}
|
||||
});
|
||||
|
||||
if (IsResponseOK(gotten_data) && gotten_data['data']) return true;
|
||||
else {
|
||||
ccn_localstorageAssist_SetApiToken('');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ====================================================== calendar
|
||||
|
||||
function ccn_api_calendar_getFull(_startDateTime, _endDateTime) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/calendar/getFull',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
startDateTime: _startDateTime,
|
||||
endDateTime: _endDateTime
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_calendar_getDetail(_uuid) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/calendar/getDetail',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_calendar_update(_uuid, _belongTo, _title, _description, _eventDateTimeStart, _eventDateTimeEnd, _loopRules, _timezoneOffset, _lastChange) {
|
||||
var data = {};
|
||||
if (typeof(_belongTo) != 'undefined')
|
||||
data.belongTo = _belongTo;
|
||||
if (typeof(_title) != 'undefined')
|
||||
data.title = _title;
|
||||
if (typeof(_description) != 'undefined')
|
||||
data.description = _description;
|
||||
if (typeof(_eventDateTimeStart) != 'undefined')
|
||||
data.eventDateTimeStart = _eventDateTimeStart;
|
||||
if (typeof(_eventDateTimeEnd) != 'undefined')
|
||||
data.eventDateTimeEnd = _eventDateTimeEnd;
|
||||
if (typeof(_loopRules) != 'undefined')
|
||||
data.loopRules = _loopRules;
|
||||
if (typeof(_timezoneOffset) != 'undefined')
|
||||
data.timezoneOffset = _timezoneOffset;
|
||||
|
||||
data.token = ccn_localstorageAssist_GetApiToken();
|
||||
data.uuid = _uuid;
|
||||
data.lastChange = _lastChange;
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/calendar/update',
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_calendar_add(_belongTo, _title, _description, _eventDateTimeStart, _eventDateTimeEnd, _loopRules, _timezoneOffset) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/calendar/add',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
belongTo: _belongTo,
|
||||
title: _title,
|
||||
description: _description,
|
||||
eventDateTimeStart: _eventDateTimeStart,
|
||||
eventDateTimeEnd: _eventDateTimeEnd,
|
||||
loopRules: _loopRules,
|
||||
timezoneOffset: _timezoneOffset
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_calendar_delete(_uuid, _lastChange) {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/calendar/delete',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ====================================================== collection
|
||||
|
||||
function ccn_api_collection_getFullOwn() {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/getFullOwn',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_getDetailOwn(_uuid) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/getDetailOwn',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_addOwn(_name) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/addOwn',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
name: _name
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_updateOwn(_uuid, _name, _lastChange) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/updateOwn',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
name: _name,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_deleteOwn(_uuid, _lastChange) {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/collection/deleteOwn',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_getSharing(_uuid) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/getSharing',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_deleteSharing(_uuid, _target, _lastChange) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/deleteSharing',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
target: _target,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_addSharing(_uuid, _target, _lastChange) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/addSharing',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
target: _target,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_collection_getShared() {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/collection/getShared',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ====================================================== todo
|
||||
|
||||
function ccn_api_todo_getFull() {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/todo/getFull',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_todo_add() {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/todo/add',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_todo_update(_uuid, _data, _lastChange) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/todo/update',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
data: _data,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_todo_delete(_uuid, _lastChange) {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/todo/delete',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
uuid: _uuid,
|
||||
lastChange: _lastChange
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ====================================================== admin
|
||||
|
||||
function ccn_api_admin_get() {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/admin/get',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_admin_add(_username) {
|
||||
return ccn_api_dataTemplate(
|
||||
'/api/admin/add',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
username: _username
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_admin_update(_username, _password, _isAdmin) {
|
||||
var data = {};
|
||||
if (typeof(_password) != 'undefined')
|
||||
data.password = _password;
|
||||
if (typeof(_isAdmin) != 'undefined')
|
||||
data.isAdmin = _isAdmin;
|
||||
|
||||
if (Object.getOwnPropertyNames(data).length == 0) return false;
|
||||
data.token = ccn_localstorageAssist_GetApiToken();
|
||||
data.username = _username;
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/admin/update',
|
||||
data
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_admin_delete(_username) {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/admin/delete',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
username: _username
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// ====================================================== profile
|
||||
|
||||
function ccn_api_profile_isAdmin() {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/profile/isAdmin',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_profile_changePassword(_password) {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/profile/changePassword',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
password: _password
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_profile_getToken() {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/profile/getToken',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function ccn_api_profile_deleteToken(_deleteToken) {
|
||||
return ccn_api_boolTemplate(
|
||||
'/api/profile/deleteToken',
|
||||
{
|
||||
token: ccn_localstorageAssist_GetApiToken(),
|
||||
deleteToken: _deleteToken
|
||||
}
|
||||
);
|
||||
}
|
||||
441
frontend-legacy/static/js/datetime.js
Normal file
441
frontend-legacy/static/js/datetime.js
Normal file
@@ -0,0 +1,441 @@
|
||||
// NOTE: this file is sync with dt.py. if this file or dt.py have bugs, all code should be changed
|
||||
var ccn_datetime_monthDayCount = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
|
||||
var ccn_datetime_MIN_YEAR = 1950;
|
||||
var ccn_datetime_MAX_YEAR = 2200;
|
||||
var ccn_datetime_MIN_DATETIME = new Date(Date.UTC(ccn_datetime_MIN_YEAR, 0, 1, 0, 0, 0, 0));
|
||||
var ccn_datetime_MAX_DATETIME = new Date(Date.UTC(ccn_datetime_MAX_YEAR, 0, 1, 0, 0, 0, 0));
|
||||
var ccn_datetime_MIN_TIMESTAMP = Math.floor(ccn_datetime_MIN_DATETIME.getTime() / 60000);
|
||||
var ccn_datetime_MAX_TIMESTAMP = Math.floor(ccn_datetime_MAX_DATETIME.getTime() / 60000);
|
||||
|
||||
var ccn_datetime_DAY1_SPAN = 60 * 24;
|
||||
var ccn_datetime_DAY7_SPAN = 7 * ccn_datetime_DAY1_SPAN;
|
||||
|
||||
var ccn_datetime_precompiledLoopRules = {
|
||||
year: new RegExp(/^Y([SR]{1})([1-9]\d*)$/),
|
||||
month: new RegExp(/^M([SR]{1})([ABCD]{1})([1-9]\d*)$/),
|
||||
week: new RegExp(/^W([TF]{7})([1-9]\d*)$/),
|
||||
day: new RegExp(/^D([1-9]\d*)$/)
|
||||
};
|
||||
|
||||
var ccn_datetime_precompiledLoopStopRules = {
|
||||
infinity: new RegExp(/^F$/),
|
||||
datetime: new RegExp(/^D([1-9]\d*|0)$/),
|
||||
times: new RegExp(/^T([1-9]\d*)$/)
|
||||
}
|
||||
|
||||
/*
|
||||
return format
|
||||
[loopRules, loopStopRules] or undefined(invalid or no loop)
|
||||
|
||||
loopRules:
|
||||
year loop: [0, isStrict, yearSpan]
|
||||
month loop: [1, isStrict, monthMode, monthSpan]
|
||||
week loop: [2, 7 bool item..., weekSpan]
|
||||
day loop: [3, daySpan]
|
||||
|
||||
loopStopRules:
|
||||
infinity: [0]
|
||||
datetime: [1, timestamp]
|
||||
times: [2, times]
|
||||
*/
|
||||
function ccn_datetime_ResolveLoopRules4UI(strl) {
|
||||
if (strl == '') return undefined;
|
||||
|
||||
var sp = strl.split('-');
|
||||
if (sp.length != 2) return undefined;
|
||||
var loopRules = undefined;
|
||||
var loopStopRules = undefined;
|
||||
|
||||
if (ccn_datetime_precompiledLoopRules.year.test(sp[0])) {
|
||||
loopRules = [0, RegExp.$1 == 'S', parseInt(RegExp.$2)];
|
||||
} else if (ccn_datetime_precompiledLoopRules.month.test(sp[0])) {
|
||||
loopRules = [1, RegExp.$1 == 'S', RegExp.$2, parseInt(RegExp.$3)];
|
||||
} else if (ccn_datetime_precompiledLoopRules.week.test(sp[0])) {
|
||||
loopRules = [2];
|
||||
for (var i = 0; i < 7; i++)
|
||||
loopRules.push(RegExp.$1[i] == 'T');
|
||||
loopRules.push(parseInt(RegExp.$2));
|
||||
} else if (ccn_datetime_precompiledLoopRules.day.test(sp[0])) {
|
||||
loopRules = [3, parseInt(RegExp.$1)];
|
||||
} else return undefined;
|
||||
|
||||
|
||||
if (ccn_datetime_precompiledLoopStopRules.infinity.test(sp[1])) {
|
||||
loopStopRules = [0];
|
||||
} else if (ccn_datetime_precompiledLoopStopRules.datetime.test(sp[1])) {
|
||||
loopStopRules = [1, parseInt(RegExp.$1)];
|
||||
} else if (ccn_datetime_precompiledLoopStopRules.times.test(sp[1])) {
|
||||
loopStopRules = [2, parseInt(RegExp.$1)];
|
||||
} else return undefined;
|
||||
|
||||
return [loopRules, loopStopRules];
|
||||
}
|
||||
|
||||
// loopDateTimeStart's value is not correspond with database.
|
||||
// it is calculated by program, should be pointed to the closing
|
||||
// protential event start datetime.
|
||||
// also loopDateTimeEnd, it was clamped with the tail of legal event
|
||||
// clampStartDateTime is real clamp datetime of event start datetime.
|
||||
// loopDateTimeStart is the start datetime for detect.
|
||||
// in this section, all time should be analysed with Date((time + timezoneOffset) * 60000)
|
||||
// and use .getUTC...() functions.
|
||||
function ccn_datetime_ResolveLoopRules4Event(loopRules, loopDateTimeStart, loopDateTimeEnd, eventDateTimeStart, eventDateTimeEnd, timezoneOffset, clampStartDateTime) {
|
||||
if (loopRules == '') return [
|
||||
[Math.max(eventDateTimeStart, clampStartDateTime),
|
||||
Math.max(loopDateTimeEnd, eventDateTimeEnd)]
|
||||
];
|
||||
|
||||
var sp = loopRules.split('-');
|
||||
if (sp.length != 2) return undefined;
|
||||
var loopRules = sp[0]; // we don't need consider stop flag
|
||||
var result = new Array();
|
||||
|
||||
// compute offset and duration
|
||||
var eventDateTime = new Date((eventDateTimeStart + timezoneOffset) * 60000);
|
||||
eventDateTime.setUTCHours(0, 0, 0, 0);
|
||||
var eventOffset = eventDateTimeStart - (Math.floor(eventDateTime.getTime() / 60000) - timezoneOffset);
|
||||
var eventDuration = eventDateTimeEnd - eventDateTimeStart;
|
||||
|
||||
var detectDateTime = new Date(loopDateTimeStart * 60000);
|
||||
detectDateTime.setUTCHours(0, 0, 0, 0);
|
||||
var originalYear = eventDateTime.getUTCFullYear();
|
||||
var originalMonth = eventDateTime.getUTCMonth() + 1;
|
||||
var originalDay = eventDateTime.getUTCDate();
|
||||
|
||||
// compute event
|
||||
if (ccn_datetime_precompiledLoopRules.year.test(loopRules)) {
|
||||
var isStrict = RegExp.$1 == 'S';
|
||||
var loopSpan = parseInt(RegExp.$2);
|
||||
|
||||
var yearCount = detectDateTime.getFullYear() - originalYear;
|
||||
var isSpecial = (originalMonth == 2 && originalDay == 29);
|
||||
var realLoopSpan = (isSpecial && isStrict) ? LCM(4, loopSpan) : loopSpan;
|
||||
|
||||
//var fullSpanCount = Math.floor(yearCount / realLoopSpan);
|
||||
var remainYear = yearCount % realLoopSpan;
|
||||
//detectDateTime.setUTCFullYear(fullSpanCount + detectDateTime.getUTCFullYear(), 1, 1);
|
||||
if (remainYear != 0)
|
||||
detectDateTime.setUTCFullYear(realLoopSpan - remainYear + detectDateTime.getUTCFullYear(), 1 - 1, 1);
|
||||
|
||||
var skipFlag = false;
|
||||
while(Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset <= loopDateTimeEnd) {
|
||||
skipFlag = false;
|
||||
if (isSpecial) {
|
||||
// is special day, 29 Feb
|
||||
// try set it in 29 Feb
|
||||
if (isStrict) {
|
||||
if (ccn_datetime_IsLeapYear(detectDateTime.getUTCFullYear())) detectDateTime.setUTCMonth(2 - 1, 29);
|
||||
else skipFlag = true; // order skip
|
||||
} else {
|
||||
if (ccn_datetime_IsLeapYear(detectDateTime.getUTCFullYear())) detectDateTime.setUTCMonth(2 - 1, 29);
|
||||
else detectDateTime.setUTCMonth(2 - 1, 28);
|
||||
}
|
||||
} else detectDateTime.setUTCMonth(originalMonth - 1, originalDay);
|
||||
|
||||
if (!skipFlag) {
|
||||
result.push(
|
||||
[Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset,
|
||||
Math.floor(detectDateTime.getTime() / 60000) + eventOffset + eventDuration - timezoneOffset]
|
||||
);
|
||||
}
|
||||
|
||||
detectDateTime.setUTCFullYear(realLoopSpan + detectDateTime.getUTCFullYear());
|
||||
}
|
||||
|
||||
} else if (ccn_datetime_precompiledLoopRules.month.test(loopRules)) {
|
||||
var isStrict = RegExp.$1 == 'S';
|
||||
var loopMethod = RegExp.$2;
|
||||
var loopSpan = parseInt(RegExp.$3);
|
||||
|
||||
var monthsCount = ccn_datetime_MonthsCount(detectDateTime.getUTCFullYear(), detectDateTime.getUTCMonth() + 1) -
|
||||
ccn_datetime_MonthsCount(originalYear, originalMonth);
|
||||
|
||||
//var fullSpanCount = Math.floor(monthsCount / loopSpan);
|
||||
var remainMonth = monthsCount % loopSpan;
|
||||
//detectDateTime.setUTCMonth(fullSpanCount * loopSpan + detectDateTime.getUTCMonth(), 1);
|
||||
detectDateTime.setUTCDate(1);
|
||||
if (remainMonth != 0)
|
||||
detectDateTime.setUTCMonth(loopSpan - remainMonth + detectDateTime.getUTCMonth(), 1);
|
||||
|
||||
while(Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset <= loopDateTimeEnd) {
|
||||
var data = ccn_datetime_GetRemanagedDayInMonth(originalYear, originalMonth, originalDay, detectDateTime.getUTCFullYear(), detectDateTime.getUTCMonth() + 1, isStrict);
|
||||
var predictedDay = undefined;
|
||||
switch(loopMethod) {
|
||||
case 'A':
|
||||
if (typeof(data[0]) != 'undefined') predictedDay = data[0];
|
||||
break;
|
||||
case 'B':
|
||||
if (typeof(data[1]) != 'undefined') predictedDay = data[1];
|
||||
break;
|
||||
case 'C':
|
||||
if (typeof(data[2]) != 'undefined') predictedDay = data[2];
|
||||
break;
|
||||
case 'D':
|
||||
if (typeof(data[3]) != 'undefined') predictedDay = data[3];
|
||||
break;
|
||||
}
|
||||
if (typeof(predictedDay) != 'undefined') {
|
||||
detectDateTime.setUTCDate(predictedDay);
|
||||
result.push(
|
||||
[Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset,
|
||||
Math.floor(detectDateTime.getTime() / 60000) + eventOffset + eventDuration - timezoneOffset]
|
||||
);
|
||||
}
|
||||
|
||||
detectDateTime.setUTCMonth(loopSpan + detectDateTime.getUTCMonth(), 1);
|
||||
}
|
||||
|
||||
|
||||
} else if (ccn_datetime_precompiledLoopRules.week.test(loopRules)) {
|
||||
var loopSpan = parseInt(RegExp.$2);
|
||||
var weekOption = [];
|
||||
var weekEventCount = 0
|
||||
for (var i = 0; i < 7; i++) {
|
||||
weekOption.push(RegExp.$1[i] == 'T');
|
||||
if (RegExp.$1[i] == 'T') weekEventCount++;
|
||||
}
|
||||
|
||||
var originalWeek = ccn_datetime_DayOfWeek(originalYear, originalMonth, originalDay);
|
||||
|
||||
// try insert original event
|
||||
if (!weekOption[originalWeek]) {
|
||||
result.push(
|
||||
[eventDateTimeStart, eventDateTimeEnd]
|
||||
);
|
||||
}
|
||||
|
||||
var daysCount = ccn_datetime_DaysCount(detectDateTime.getUTCFullYear(), detectDateTime.getUTCMonth() + 1, detectDateTime.getDate()) -
|
||||
ccn_datetime_DaysCount(originalYear, originalMonth, originalDay);
|
||||
//var fullSpanCount = Math.floor(daysCount / (7 * loopSpan));
|
||||
var remainFullSpanCount = Math.floor((daysCount % (7 * loopSpan)) / 7);
|
||||
var remainDays = (daysCount % (7 * loopSpan)) % 7;
|
||||
|
||||
//detectDateTime.setUTCDate((7 * loopSpan * fullSpanCount) + detectDateTime.getUTCDate());
|
||||
if (remainFullSpanCount != 0) {
|
||||
detectDateTime.setUTCDate((loopSpan - remainFullSpanCount) * 7 + detectDateTime.getUTCDate());
|
||||
}
|
||||
var weekCounter = remainDays;
|
||||
|
||||
while(Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset <= loopDateTimeEnd) {
|
||||
if (weekOption[(weekCounter + originalWeek) % 7])
|
||||
result.push(
|
||||
[Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset,
|
||||
Math.floor(detectDateTime.getTime() / 60000) + eventOffset + eventDuration - timezoneOffset]
|
||||
);
|
||||
|
||||
weekCounter = (weekCounter + 1) % 7;
|
||||
detectDateTime.setUTCDate(detectDateTime.getUTCDate() + 1);
|
||||
if (weekCounter == 0)
|
||||
detectDateTime.setUTCDate(detectDateTime.getUTCDate() + (loopSpan - 1) * 7);
|
||||
}
|
||||
|
||||
} else if (ccn_datetime_precompiledLoopRules.day.test(loopRules)) {
|
||||
var loopSpan = parseInt(RegExp.$1);
|
||||
|
||||
var daysCount = ccn_datetime_DaysCount(detectDateTime.getUTCFullYear(), detectDateTime.getUTCMonth() + 1, detectDateTime.getUTCDate()) -
|
||||
ccn_datetime_DaysCount(originalYear, originalMonth, originalDay);
|
||||
//var fullSpanCount = Math.floor(daysCount / loopSpan);
|
||||
var remainDays = daysCount % loopSpan;
|
||||
//detectDateTime.setUTCDate(fullSpanCount * loopSpan + detectDateTime.getUTCDate());
|
||||
if (remainDays != 0)
|
||||
detectDateTime.setUTCDate(loopSpan - remainDays + detectDateTime.getUTCDate());
|
||||
|
||||
while(Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset <= loopDateTimeEnd) {
|
||||
result.push(
|
||||
[Math.floor(detectDateTime.getTime() / 60000) + eventOffset - timezoneOffset,
|
||||
Math.floor(detectDateTime.getTime() / 60000) + eventOffset + eventDuration - timezoneOffset]
|
||||
);
|
||||
detectDateTime.setUTCDate(detectDateTime.getUTCDate() + loopSpan);
|
||||
}
|
||||
} else return undefined;
|
||||
|
||||
// clamp item
|
||||
var realResult = [];
|
||||
for (var i in result) {
|
||||
var start = result[i][0];
|
||||
var end = result[i][1];
|
||||
if (end > clampStartDateTime && start <= loopDateTimeEnd)
|
||||
realResult.push([Math.max(start, clampStartDateTime), Math.min(end, loopDateTimeEnd)]);
|
||||
}
|
||||
return realResult;
|
||||
}
|
||||
|
||||
function ccn_datetime_ResolveLoopRules4Text(strl, startDateTime, timezoneOffset) {
|
||||
if (strl == '') return "";
|
||||
|
||||
var sp = strl.split('-');
|
||||
if (sp.length != 2) return "";
|
||||
var loopRules = undefined;
|
||||
var loopStopRules = undefined;
|
||||
var datetimeInstance = new Date((startDateTime + timezoneOffset) * 60000)
|
||||
|
||||
if (ccn_datetime_precompiledLoopRules.year.test(sp[0])) {
|
||||
if (RegExp.$1 == 'S')
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeStrict');
|
||||
else
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeRough');
|
||||
loopRules += $.i18n.prop('ccn-i18n-datetime-loopRuleText-year')
|
||||
.format(parseInt(RegExp.$2), datetimeInstance.toLocaleDateString(undefined, {timeZone: "UTC"}));
|
||||
} else if (ccn_datetime_precompiledLoopRules.month.test(sp[0])) {
|
||||
if (RegExp.$1 == 'S')
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeStrict');
|
||||
else
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-modeRough');
|
||||
|
||||
var dayInMonth = ccn_datetime_GetDayInMonth(
|
||||
datetimeInstance.getUTCFullYear(),
|
||||
datetimeInstance.getUTCMonth() + 1,
|
||||
datetimeInstance.getUTCDate());
|
||||
switch(RegExp.$2) {
|
||||
case 'A':
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthA')
|
||||
.format(parseInt(RegExp.$3), dayInMonth[0]);
|
||||
break;
|
||||
case 'B':
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthB')
|
||||
.format(parseInt(RegExp.$3), dayInMonth[1]);
|
||||
break;
|
||||
case 'C':
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthC')
|
||||
.format(parseInt(RegExp.$3), dayInMonth[2], dayInMonth[3]);
|
||||
break;
|
||||
case 'D':
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-monthD')
|
||||
.format(parseInt(RegExp.$3), dayInMonth[4], dayInMonth[5]);
|
||||
break;
|
||||
}
|
||||
} else if (ccn_datetime_precompiledLoopRules.week.test(sp[0])) {
|
||||
var weekOfDayCache = [];
|
||||
for (var i = 0; i < 7; i++) {
|
||||
if (RegExp.$1[i] == 'T')
|
||||
weekOfDayCache.push(ccn_i18n_UniversalGetDayOfWeek(i));
|
||||
}
|
||||
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-week')
|
||||
.format(parseInt(RegExp.$2), weekOfDayCache.join(', '));
|
||||
} else if (ccn_datetime_precompiledLoopRules.day.test(sp[0])) {
|
||||
loopRules = $.i18n.prop('ccn-i18n-datetime-loopRuleText-day')
|
||||
.format(parseInt(RegExp.$1));
|
||||
} else return "";
|
||||
|
||||
|
||||
if (ccn_datetime_precompiledLoopStopRules.infinity.test(sp[1])) {
|
||||
loopStopRules = $.i18n.prop('ccn-i18n-datetime-loopStopRuleText-infinity');
|
||||
} else if (ccn_datetime_precompiledLoopStopRules.datetime.test(sp[1])) {
|
||||
loopStopRules = $.i18n.prop('ccn-i18n-datetime-loopStopRuleText-datetime')
|
||||
.format(new Date(parseInt(RegExp.$1)).toLocaleDateString());
|
||||
} else if (ccn_datetime_precompiledLoopStopRules.times.test(sp[1])) {
|
||||
loopStopRules = $.i18n.prop('ccn-i18n-datetime-loopStopRuleText-times')
|
||||
.format(parseInt(RegExp.$1));
|
||||
} else return "";
|
||||
|
||||
return (loopRules + loopStopRules);
|
||||
}
|
||||
|
||||
function ccn_datetime_LeapYearCountEx(endYear, includeThis, baseYear, includeBase) {
|
||||
if (!includeThis) endYear--;
|
||||
if (includeBase) baseYear--;
|
||||
|
||||
var endly = Math.floor(endYear / 4);
|
||||
endly -= Math.floor(endYear / 100);
|
||||
endly += Math.floor(endYear / 400);
|
||||
|
||||
var basely = Math.floor(baseYear / 4);
|
||||
basely -= Math.floor(baseYear / 100);
|
||||
basely += Math.floor(baseYear / 400);
|
||||
|
||||
return (endly - basely);
|
||||
}
|
||||
|
||||
function ccn_datetime_DaysCount(year, month, day) {
|
||||
var ly = ccn_datetime_LeapYearCountEx(year, false, 1, true);
|
||||
var days = 365 * (year - 1);
|
||||
days += ly;
|
||||
|
||||
for(var index = 1; index < month; index++)
|
||||
days += ccn_datetime_monthDayCount[index - 1];
|
||||
|
||||
if (month > 2 && ccn_datetime_IsLeapYear(year))
|
||||
days += 1;
|
||||
|
||||
days += day - 1;
|
||||
return days;
|
||||
}
|
||||
|
||||
function ccn_datetime_MonthsCount(year, month) {
|
||||
return (year - 1) * 12 + (month - 1);
|
||||
}
|
||||
|
||||
function ccn_datetime_DayOfWeek(year, month, day) {
|
||||
return ccn_datetime_DaysCount(year, month, day) % 7;
|
||||
}
|
||||
|
||||
function ccn_datetime_GetDayInMonth(year, month, day) {
|
||||
var days = ccn_datetime_monthDayCount[month - 1] + ((month == 2 && ccn_datetime_IsLeapYear(year)) ? 1 : 0);
|
||||
var firstDayOfWeek = ccn_datetime_DayOfWeek(year, month, 1);
|
||||
var dayOfWeek = (firstDayOfWeek + day - 1) % 7;
|
||||
|
||||
var dayForwards = day;
|
||||
var dayBackwards = days - day + 1;
|
||||
|
||||
var weeksForward = Math.floor((dayForwards - 1) / 7) + 1;
|
||||
var weeksBackwards = Math.floor((dayBackwards - 1) / 7) + 1;
|
||||
|
||||
return [dayForwards, dayBackwards, weeksForward, dayOfWeek, weeksBackwards, dayOfWeek];
|
||||
}
|
||||
|
||||
function ccn_datetime_GetRemanagedDayInMonth(oldYear, oldMonth, oldDay, newYear, newMonth, isStrict) {
|
||||
var ddata = ccn_datetime_GetDayInMonth(oldYear, oldMonth, oldDay);
|
||||
var mdata = ccn_datetime_GetMonthWeekStatistics(newYear, newMonth);
|
||||
var days = ccn_datetime_monthDayCount[newMonth - 1] + ((newMonth == 2 && ccn_datetime_IsLeapYear(year)) ? 1 : 0);
|
||||
var firstDayOfWeek = ccn_datetime_DayOfWeek(newYear, newMonth, 1);
|
||||
//var lastDayOfWeek = (firstDayOfWeek + days - 1) % 7;
|
||||
|
||||
if (isStrict) {
|
||||
var methodA = ddata[0] > days ? undefined : ddata[0];
|
||||
var methodB = ddata[1] > days ? undefined : (days - ddata[1] + 1);
|
||||
} else {
|
||||
var methodA = Math.min(ddata[0], days);
|
||||
var methodB = days - Math.min(ddata[1], days) + 1;
|
||||
}
|
||||
|
||||
var methodC = undefined;
|
||||
if (ddata[2] <= mdata[ddata[3]] || !isStrict) {
|
||||
var targetWeek = Math.min(ddata[2], mdata[ddata[3]]);
|
||||
methodC = 1 + (targetWeek - 1) * 7 + ((ddata[3] + 7 - firstDayOfWeek) % 7);
|
||||
}
|
||||
|
||||
var methodD = undefined;
|
||||
if (ddata[4] <= mdata[ddata[5]] || !isStrict) {
|
||||
// convert to type c and calc
|
||||
var targetWeek = mdata[ddata[5]] - Math.min(ddata[4], mdata[ddata[5]]) + 1;
|
||||
methodD = 1 + (targetWeek - 1) * 7 + ((ddata[5] + 7 - firstDayOfWeek) % 7);
|
||||
}
|
||||
|
||||
return [methodA, methodB, methodC, methodD];
|
||||
}
|
||||
|
||||
function ccn_datetime_GetMonthWeekStatistics(year, month) {
|
||||
var days = ccn_datetime_monthDayCount[month - 1] + ((month == 2 && ccn_datetime_IsLeapYear(year)) ? 1 : 0);
|
||||
var firstDayOfWeek = ccn_datetime_DayOfWeek(year, month, 1);
|
||||
|
||||
var result = [4, 4, 4, 4, 4, 4, 4];
|
||||
var remain = days % 7;
|
||||
var week = firstDayOfWeek;
|
||||
while (remain > 0) {
|
||||
result[week % 7] += 1;
|
||||
week++;
|
||||
remain--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function ccn_datetime_IsLeapYear(year) {
|
||||
var isLeap = false;
|
||||
if (year % 4 == 0) isLeap = true;
|
||||
if (year % 100 == 0) isLeap = false;
|
||||
if (year % 400 == 0) isLeap = true;
|
||||
return isLeap;
|
||||
}
|
||||
522
frontend-legacy/static/js/datetimepicker.js
Normal file
522
frontend-legacy/static/js/datetimepicker.js
Normal file
@@ -0,0 +1,522 @@
|
||||
var ccn_datetimepicker_tabType = {
|
||||
year: 0,
|
||||
month: 1,
|
||||
day: 2,
|
||||
hour: 3,
|
||||
minute: 4
|
||||
};
|
||||
|
||||
var ccn_datetimepicker_dialPlateWidth = 200;
|
||||
var ccn_datetimepicker_dialPlateRadius = ccn_datetimepicker_dialPlateWidth / 2;
|
||||
var ccn_datetimepicker_dialPlateHourInnerPercent = 0.6;
|
||||
var ccn_datetimepicker_dialPlateHourOutterPercent = 0.8;
|
||||
var ccn_datetimepicker_dialPlateHourDistinguishPercent = 0.7;
|
||||
var ccn_datetimepicker_dialPlateMinutePercent = 0.8;
|
||||
var ccn_datetimepicker_dialPlateHourResolution = Math.PI * 2 / 12;
|
||||
var ccn_datetimepicker_dialPlateMinuteResolution = Math.PI * 2 / 60;
|
||||
|
||||
var ccn_datetimepicker_mode = undefined;
|
||||
var ccn_datetimepicker_isUTC = undefined;
|
||||
var ccn_datetimepicker_pickerIndex = undefined;
|
||||
|
||||
var ccn_datetimepicker_enableMinuteDrag = false;
|
||||
var ccn_datetimepicker_enableHourDrag = false;
|
||||
|
||||
var ccn_datetimepicker_internalDateTime = new Date();
|
||||
var ccn_datetimepicker_displayCacheDateTime = new Date();
|
||||
|
||||
// ========================================= export func
|
||||
|
||||
function ccn_datetimepicker_Insert() {
|
||||
$('body').append(ccn_template_datetimepicker.render());
|
||||
|
||||
// bind size event and trigge once
|
||||
$(window).resize(ccn_datetimepicker_RefreshSvg).resize();
|
||||
|
||||
// add data attr
|
||||
for(var i = 0; i < 3; i++) {
|
||||
for(var j = 0; j < 4; j++) {
|
||||
$('#ccn-datetimepiacker-panelMonth-table > div:nth-child({0}) > div:nth-child({1})'.format(i + 1, j + 1))
|
||||
.attr('data', i * 4 + j);
|
||||
}
|
||||
}
|
||||
|
||||
// bind header event
|
||||
$('header.pickerHeader > div').click(function() {
|
||||
ccn_datetimepicker_SwitchTab(ccn_datetimepicker_Str2TabType($(this).attr('type')));
|
||||
});
|
||||
|
||||
// bind button event
|
||||
$('#ccn-datetimepiacker-panelYear-prevBtn').click(function() {
|
||||
ccn_datetimepicker_PrevNextYear(true);
|
||||
});
|
||||
$('#ccn-datetimepiacker-panelYear-nextBtn').click(function() {
|
||||
ccn_datetimepicker_PrevNextYear(false);
|
||||
});
|
||||
$('#ccn-datetimepiacker-panelMonth-prevBtn').click(function() {
|
||||
ccn_datetimepicker_PrevNextMonth(true);
|
||||
});
|
||||
$('#ccn-datetimepiacker-panelMonth-nextBtn').click(function() {
|
||||
ccn_datetimepicker_PrevNextMonth(false);
|
||||
});
|
||||
$('#ccn-datetimepiacker-panelDay-prevBtn').click(function() {
|
||||
ccn_datetimepicker_PrevNextDay(true);
|
||||
});
|
||||
$('#ccn-datetimepiacker-panelDay-nextBtn').click(function() {
|
||||
ccn_datetimepicker_PrevNextDay(false);
|
||||
});
|
||||
|
||||
$('#ccn-datetimepiacker-panelYear-table > div > div').click(ccn_datetimepicker_ClickYear);
|
||||
$('#ccn-datetimepiacker-panelMonth-table > div > div').click(ccn_datetimepicker_ClickMonth);
|
||||
$('#ccn-datetimepiacker-panelDay-table > div:nth-child(n+1) > div').click(ccn_datetimepicker_ClickDay);
|
||||
|
||||
$('#ccn-datetimepicker-panelHour')
|
||||
.mousedown(ccn_datetimepicker_StartDragHour)
|
||||
.mousemove(ccn_datetimepicker_DraggingHour)
|
||||
.mouseup(ccn_datetimepicker_StopDragHour)
|
||||
.on('touchstart', ccn_datetimepicker_StartDragHour)
|
||||
.on('touchmove', ccn_datetimepicker_DraggingHour)
|
||||
.on('touchend', ccn_datetimepicker_StopDragHour);
|
||||
|
||||
$('#ccn-datetimepicker-panelMinute')
|
||||
.mousedown(ccn_datetimepicker_StartDragMinute)
|
||||
.mousemove(ccn_datetimepicker_DraggingMinute)
|
||||
.mouseup(ccn_datetimepicker_StopDragMinute)
|
||||
.on('touchstart', ccn_datetimepicker_StartDragMinute)
|
||||
.on('touchmove', ccn_datetimepicker_DraggingMinute)
|
||||
.on('touchend', ccn_datetimepicker_StopDragMinute);
|
||||
|
||||
$('#ccn-datetimepicker-btnConfirm').click(ccn_datetimepicker_Confirm);
|
||||
$('#ccn-datetimepicker-btnCancel').click(ccn_datetimepicker_Cancel);
|
||||
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_Modal(mode, pickerIndex, isUTC) {
|
||||
ccn_datetimepicker_mode = mode;
|
||||
ccn_datetimepicker_isUTC = isUTC;
|
||||
ccn_datetimepicker_pickerIndex = pickerIndex;
|
||||
|
||||
ccn_datetimepicker_internalDateTime = ccn_datetimepicker_Get(pickerIndex, false);
|
||||
|
||||
$('header.pickerHeader > div').hide();
|
||||
switch(mode) {
|
||||
case ccn_datetimepicker_tabType.minute:
|
||||
$('header.pickerHeader > div[type=minute]').show();
|
||||
case ccn_datetimepicker_tabType.hour:
|
||||
$('header.pickerHeader > div[type=hour]').show();
|
||||
case ccn_datetimepicker_tabType.day:
|
||||
$('header.pickerHeader > div[type=day]').show();
|
||||
case ccn_datetimepicker_tabType.month:
|
||||
$('header.pickerHeader > div[type=month]').show();
|
||||
case ccn_datetimepicker_tabType.year:
|
||||
$('header.pickerHeader > div[type=year]').show();
|
||||
break;
|
||||
}
|
||||
|
||||
$('#ccn-datetimepicker-modal').addClass('is-active');
|
||||
ccn_datetimepicker_SwitchTab(mode); // this call is set in there by design. if you don't show the dialog, the call of svg resize will fail.
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_Confirm() {
|
||||
// update and call callback func
|
||||
ccn_datetimepicker_Set(
|
||||
ccn_datetimepicker_pickerIndex,
|
||||
ccn_datetimepicker_internalDateTime,
|
||||
ccn_datetimepicker_isUTC,
|
||||
ccn_datetimepicker_mode
|
||||
);
|
||||
|
||||
$('#ccn-datetimepicker-modal').removeClass('is-active');
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_Cancel() {
|
||||
$('#ccn-datetimepicker-modal').removeClass('is-active');
|
||||
}
|
||||
|
||||
// ========================================= internal func
|
||||
|
||||
function ccn_datetimepicker_OnSvgResize(ele) {
|
||||
var scale = 200 / Math.min(ele.width(), ele.height());
|
||||
ele.css('font-size', scale + 'em');
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_SwitchTab(newTab) {
|
||||
$('div.pickerContainer > *').hide();
|
||||
|
||||
ccn_datetimepicker_displayCacheDateTime.setTime(ccn_datetimepicker_internalDateTime.getTime());
|
||||
ccn_datetimepicker_RefreshDisplay(newTab);
|
||||
|
||||
switch(newTab) {
|
||||
case ccn_datetimepicker_tabType.year:
|
||||
$('#ccn-datetimepicker-panelYear').show();
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.month:
|
||||
$('#ccn-datetimepicker-panelMonth').show();
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.day:
|
||||
$('#ccn-datetimepicker-panelDay').show();
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.hour:
|
||||
$('#ccn-datetimepicker-panelHour').show();
|
||||
ccn_datetimepicker_RefreshSvg(); // immediately trigger once svg resize
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.minute:
|
||||
$('#ccn-datetimepicker-panelMinute').show();
|
||||
ccn_datetimepicker_RefreshSvg(); // immediately trigger once svg resize
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_RefreshDisplay(tab) {
|
||||
// header should be refreshed entirely
|
||||
$('#ccn-datetimepicker-datetime-year').text(ccn_datetimepicker_internalDateTime.getFullYear());
|
||||
$('#ccn-datetimepicker-datetime-month').text(ccn_datetimepicker_internalDateTime.getMonth() + 1);
|
||||
$('#ccn-datetimepicker-datetime-day').text(ccn_datetimepicker_internalDateTime.getDate());
|
||||
$('#ccn-datetimepicker-datetime-hour').text(ccn_datetimepicker_internalDateTime.getHours());
|
||||
$('#ccn-datetimepicker-datetime-minute').text(ccn_datetimepicker_internalDateTime.getMinutes());
|
||||
|
||||
// refresh tab according to specific `tab`
|
||||
switch(tab) {
|
||||
case ccn_datetimepicker_tabType.year:
|
||||
var startYear = Math.floor((ccn_datetimepicker_displayCacheDateTime.getFullYear() - ccn_datetime_MIN_YEAR) / 12) * 12 + ccn_datetime_MIN_YEAR;
|
||||
var counter = startYear;
|
||||
for(var i = 0; i < 3; i++) {
|
||||
for(var j = 0; j < 4; j++, counter++) {
|
||||
var ele = $('#ccn-datetimepiacker-panelYear-table > div:nth-child({0}) > div:nth-child({1})'.format(i + 1, j + 1));
|
||||
if (counter < ccn_datetime_MAX_YEAR) {
|
||||
ele.attr('data', counter)
|
||||
.text(counter);
|
||||
} else {
|
||||
ele.attr('data', '')
|
||||
.html(' ');
|
||||
}
|
||||
|
||||
if (counter == ccn_datetimepicker_internalDateTime.getFullYear()) ele.attr('picked', 'true');
|
||||
else ele.attr('picked', 'false');
|
||||
}
|
||||
}
|
||||
|
||||
$('#ccn-datetimepiacker-panelYear-title')
|
||||
.text('{0} - {1}'.format(startYear, startYear + 12 < ccn_datetime_MAX_YEAR ? startYear + 12 : ccn_datetime_MAX_YEAR));
|
||||
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.month:
|
||||
$('#ccn-datetimepiacker-panelMonth-table > div > div').attr('picked', 'false');
|
||||
if (ccn_datetimepicker_internalDateTime.getFullYear() == ccn_datetimepicker_displayCacheDateTime.getFullYear()) {
|
||||
var month = ccn_datetimepicker_internalDateTime.getMonth();
|
||||
$('#ccn-datetimepiacker-panelMonth-table > div:nth-child({0}) > div:nth-child({1})'.format(Math.floor(month / 4) + 1, (month % 4) + 1))
|
||||
.attr('picked', 'true');
|
||||
}
|
||||
|
||||
$('#ccn-datetimepiacker-panelMonth-title')
|
||||
.text(ccn_datetimepicker_displayCacheDateTime.getFullYear());
|
||||
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.day:
|
||||
var gottenYear = ccn_datetimepicker_displayCacheDateTime.getFullYear();
|
||||
var gottenMonth = ccn_datetimepicker_displayCacheDateTime.getMonth() + 1;
|
||||
var counter = -ccn_datetime_DayOfWeek(gottenYear, gottenMonth, 1);
|
||||
var days = ccn_datetime_monthDayCount[gottenMonth - 1] + ((gottenMonth == 2 && ccn_datetime_IsLeapYear(gottenYear)) ? 1 : 0);
|
||||
for(var i = 0; i < 6; i++) {
|
||||
for(var j = 0; j < 7; j++, counter++) {
|
||||
var ele = $('#ccn-datetimepiacker-panelDay-table > div:nth-child({0}) > div:nth-child({1})'.format(i + 2, j + 1));
|
||||
if (counter < 0 || counter >= days) ele.attr('data', '').html(' ');
|
||||
else ele.attr('data', counter + 1).text(counter + 1);
|
||||
|
||||
if (counter + 1 == ccn_datetimepicker_internalDateTime.getDate()) ele.attr('picked', 'true');
|
||||
else ele.attr('picked', 'false');
|
||||
}
|
||||
}
|
||||
|
||||
$('#ccn-datetimepiacker-panelDay-title')
|
||||
.text('{0} - {1}'.format(
|
||||
ccn_datetimepicker_displayCacheDateTime.getFullYear(),
|
||||
ccn_i18n_UniversalGetMonth(ccn_datetimepicker_displayCacheDateTime.getMonth())
|
||||
));
|
||||
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.hour:
|
||||
var gottenHour = ccn_datetimepicker_displayCacheDateTime.getHours();
|
||||
var newX = Math.cos((3 - gottenHour) * Math.PI * 2 / 12);
|
||||
var newY = Math.sin((3 - gottenHour) * Math.PI * 2 / 12);
|
||||
var radius = ccn_datetimepicker_dialPlateRadius * (gottenHour < 12 ? ccn_datetimepicker_dialPlateHourOutterPercent : ccn_datetimepicker_dialPlateHourInnerPercent);
|
||||
newX = newX * radius + ccn_datetimepicker_dialPlateRadius;
|
||||
newY = (-newY * radius) + ccn_datetimepicker_dialPlateRadius;
|
||||
|
||||
$('#ccn-datetimepicker-panelHour > line')
|
||||
.attr('x2', newX)
|
||||
.attr('y2', newY);
|
||||
|
||||
$('#ccn-datetimepicker-panelHour > circle[type=symbol]')
|
||||
.attr('cx', newX)
|
||||
.attr('cy', newY);
|
||||
|
||||
break;
|
||||
case ccn_datetimepicker_tabType.minute:
|
||||
var gottenMinute = ccn_datetimepicker_displayCacheDateTime.getMinutes();
|
||||
var newX = Math.cos((15 - gottenMinute) * Math.PI * 2 / 60);
|
||||
var newY = Math.sin((15 - gottenMinute) * Math.PI * 2 / 60);
|
||||
var radius = ccn_datetimepicker_dialPlateRadius * ccn_datetimepicker_dialPlateMinutePercent;
|
||||
newX = newX * radius + ccn_datetimepicker_dialPlateRadius;
|
||||
newY = (-newY * radius) + ccn_datetimepicker_dialPlateRadius;
|
||||
|
||||
$('#ccn-datetimepicker-panelMinute > line')
|
||||
.attr('x2', newX)
|
||||
.attr('y2', newY);
|
||||
|
||||
$('#ccn-datetimepicker-panelMinute > circle[type=symbol]')
|
||||
.attr('cx', newX)
|
||||
.attr('cy', newY);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_RefreshSvg() {
|
||||
// svg resize only can be called when the svg is showing.
|
||||
// so call this func in window resize event or
|
||||
// displaying svg.
|
||||
$('div.pickerContainer > svg').each(function() {
|
||||
ccn_datetimepicker_OnSvgResize($(this));
|
||||
});
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_Str2TabType(strl) {
|
||||
switch(strl) {
|
||||
case 'year':
|
||||
return ccn_datetimepicker_tabType.year
|
||||
case 'month':
|
||||
return ccn_datetimepicker_tabType.month
|
||||
case 'day':
|
||||
return ccn_datetimepicker_tabType.day
|
||||
case 'hour':
|
||||
return ccn_datetimepicker_tabType.hour
|
||||
case 'minute':
|
||||
return ccn_datetimepicker_tabType.minute
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_GetUniformedXY(mouseOrTouchEvent, elements) {
|
||||
var offset = {
|
||||
left: elements.offset().left,
|
||||
top: elements.offset().top,
|
||||
halfWidth: elements.width() / 2,
|
||||
halfHeight: elements.height() / 2,
|
||||
halfSquareWidthHeight: Math.min(elements.width(), elements.height()) / 2
|
||||
}
|
||||
if(typeof(mouseOrTouchEvent.pageX) != 'undefined' && typeof(mouseOrTouchEvent.pageY) != 'undefined') {
|
||||
offset.realX = mouseOrTouchEvent.pageX;
|
||||
offset.realY = mouseOrTouchEvent.pageY;
|
||||
} else if(typeof(mouseOrTouchEvent.targetTouches) != 'undefined' && mouseOrTouchEvent.targetTouches.length >= 1) {
|
||||
offset.realX = mouseOrTouchEvent.targetTouches[0].pageX;
|
||||
offset.realY = mouseOrTouchEvent.targetTouches[0].pageY;
|
||||
} else {
|
||||
offset.realX = 0;
|
||||
offset.realY = 0;
|
||||
}
|
||||
|
||||
var _x = (offset.realX - offset.left - offset.halfWidth) / offset.halfSquareWidthHeight * ccn_datetimepicker_dialPlateRadius;
|
||||
var _y = -((offset.realY - offset.top - offset.halfHeight) / offset.halfSquareWidthHeight * ccn_datetimepicker_dialPlateRadius);
|
||||
|
||||
return {x: _x, y: _y};
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_PrevNextYear(isPrev) {
|
||||
ccn_datetimepicker_displayCacheDateTime.setFullYear(
|
||||
ccn_datetimepicker_displayCacheDateTime.getFullYear() + (isPrev ? -12 : 12));
|
||||
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_displayCacheDateTime);
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.year);
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_PrevNextMonth(isPrev) {
|
||||
ccn_datetimepicker_displayCacheDateTime.setFullYear(
|
||||
ccn_datetimepicker_displayCacheDateTime.getFullYear() + (isPrev ? -1 : 1));
|
||||
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_displayCacheDateTime);
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.month);
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_PrevNextDay(isPrev) {
|
||||
ccn_datetimepicker_displayCacheDateTime.setMonth(
|
||||
ccn_datetimepicker_displayCacheDateTime.getMonth() + (isPrev ? -1 : 1));
|
||||
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_displayCacheDateTime);
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.day);
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_ClickYear() {
|
||||
var ele = $(this);
|
||||
if (ele.attr('data') == '') return;
|
||||
|
||||
ccn_datetimepicker_internalDateTime.setFullYear(parseInt(ele.attr('data')));
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime);
|
||||
|
||||
if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.year)
|
||||
ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.month);
|
||||
else
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.year);
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_ClickMonth() {
|
||||
var ele = $(this);
|
||||
if (ele.attr('data') == '') return;
|
||||
|
||||
ccn_datetimepicker_internalDateTime.setFullYear(
|
||||
ccn_datetimepicker_displayCacheDateTime.getFullYear(),
|
||||
parseInt(ele.attr('data'))
|
||||
);
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime);
|
||||
|
||||
if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.month)
|
||||
ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.day);
|
||||
else
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.month);
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_ClickDay() {
|
||||
var ele = $(this);
|
||||
if (ele.attr('data') == '') return;
|
||||
|
||||
ccn_datetimepicker_internalDateTime.setFullYear(
|
||||
ccn_datetimepicker_displayCacheDateTime.getFullYear(),
|
||||
ccn_datetimepicker_displayCacheDateTime.getMonth(),
|
||||
parseInt(ele.attr('data'))
|
||||
);
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime);
|
||||
|
||||
if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.day)
|
||||
ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.hour);
|
||||
else
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.day);
|
||||
}
|
||||
|
||||
|
||||
function ccn_datetimepicker_StartDragHour() { ccn_datetimepicker_enableHourDrag = true; }
|
||||
function ccn_datetimepicker_DraggingHour(e) {
|
||||
if (!ccn_datetimepicker_enableHourDrag) return;
|
||||
|
||||
var offset = ccn_datetimepicker_GetUniformedXY(e, $('#ccn-datetimepicker-panelHour'));
|
||||
var x = offset.x;
|
||||
var y = offset.y;
|
||||
|
||||
var distance = Math.sqrt(x * x + y * y);
|
||||
var angle = Math.acos(x / distance);
|
||||
if (y < 0) angle = Math.PI * 2 - angle; // correct negative y axis angle
|
||||
|
||||
angle += (ccn_datetimepicker_dialPlateHourResolution / 2); // correct offset
|
||||
if (angle > Math.PI * 2)
|
||||
angle -= Math.PI * 2;
|
||||
|
||||
var number = Math.floor(angle / ccn_datetimepicker_dialPlateHourResolution);
|
||||
if (number >= 12) number = 11; // prevent unexpected result at the edge.
|
||||
number = (15 - number) % 12;
|
||||
if (distance < ccn_datetimepicker_dialPlateRadius * ccn_datetimepicker_dialPlateHourDistinguishPercent)
|
||||
number += 12;
|
||||
|
||||
// judge
|
||||
if (ccn_datetimepicker_displayCacheDateTime.getHours() != number) {
|
||||
ccn_datetimepicker_displayCacheDateTime.setHours(number);
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.hour);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
function ccn_datetimepicker_StopDragHour() {
|
||||
ccn_datetimepicker_enableHourDrag = false;
|
||||
|
||||
ccn_datetimepicker_internalDateTime.setHours(ccn_datetimepicker_displayCacheDateTime.getHours());
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime);
|
||||
|
||||
if (ccn_datetimepicker_mode != ccn_datetimepicker_tabType.hour)
|
||||
ccn_datetimepicker_SwitchTab(ccn_datetimepicker_tabType.minute);
|
||||
}
|
||||
|
||||
|
||||
function ccn_datetimepicker_StartDragMinute() { ccn_datetimepicker_enableMinuteDrag = true; }
|
||||
function ccn_datetimepicker_DraggingMinute(e) {
|
||||
if (!ccn_datetimepicker_enableMinuteDrag) return;
|
||||
|
||||
var offset = ccn_datetimepicker_GetUniformedXY(e, $('#ccn-datetimepicker-panelMinute'));
|
||||
var x = offset.x;
|
||||
var y = offset.y;
|
||||
|
||||
var distance = Math.sqrt(x * x + y * y);
|
||||
var angle = Math.acos(x / distance);
|
||||
if (y < 0) angle = Math.PI * 2 - angle; // correct negative y axis angle
|
||||
|
||||
angle += (ccn_datetimepicker_dialPlateMinuteResolution / 2); // correct offset
|
||||
if (angle > Math.PI * 2)
|
||||
angle -= Math.PI * 2;
|
||||
|
||||
var number = Math.floor(angle / ccn_datetimepicker_dialPlateMinuteResolution);
|
||||
if (number >= 60) number = 59; // prevent unexpected result at the edge.
|
||||
number = (75 - number) % 60;
|
||||
|
||||
// judge
|
||||
if (ccn_datetimepicker_displayCacheDateTime.getMinutes() != number) {
|
||||
ccn_datetimepicker_displayCacheDateTime.setMinutes(number);
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.minute);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
function ccn_datetimepicker_StopDragMinute() {
|
||||
ccn_datetimepicker_enableMinuteDrag = false;
|
||||
|
||||
ccn_datetimepicker_internalDateTime.setMinutes(ccn_datetimepicker_displayCacheDateTime.getMinutes());
|
||||
ccn_datetimepicker_ClampDateTime(ccn_datetimepicker_internalDateTime);
|
||||
|
||||
// no page need to go to
|
||||
// but we need refresh current page
|
||||
ccn_datetimepicker_RefreshDisplay(ccn_datetimepicker_tabType.minute);
|
||||
}
|
||||
|
||||
|
||||
function ccn_datetimepicker_ClampDateTime(dateObj) {
|
||||
if (dateObj < ccn_datetime_MIN_DATETIME)
|
||||
dateObj.setTime(ccn_datetime_MIN_DATETIME.getTime());
|
||||
if (dateObj >= ccn_datetime_MAX_DATETIME)
|
||||
dateObj.setTime(ccn_datetime_MAX_DATETIME.getTime());
|
||||
}
|
||||
|
||||
// ========================================================== universal function
|
||||
|
||||
function ccn_datetimepicker_Set(pickerIndex, dt, isUTC, mode) {
|
||||
var ele = $('[datetimepicker=' + pickerIndex + ']');
|
||||
while(true) {
|
||||
if (mode < ccn_datetimepicker_tabType.year) break;
|
||||
ele.attr('datetimepicker-year', isUTC ? dt.getUTCFullYear() : dt.getFullYear());
|
||||
if (mode < ccn_datetimepicker_tabType.month) break;
|
||||
ele.attr('datetimepicker-month', (isUTC ? dt.getUTCMonth() : dt.getMonth()) + 1);
|
||||
if (mode < ccn_datetimepicker_tabType.day) break;
|
||||
ele.attr('datetimepicker-day', isUTC ? dt.getUTCDate() : dt.getDate());
|
||||
if (mode < ccn_datetimepicker_tabType.hour) break;
|
||||
ele.attr('datetimepicker-hour', isUTC ? dt.getUTCHours() : dt.getHours());
|
||||
if (mode < ccn_datetimepicker_tabType.minute) break;
|
||||
ele.attr('datetimepicker-minute', isUTC ? dt.getUTCMinutes() : dt.getMinutes());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (typeof(ele.prop('funcs')) != 'undefined' && typeof(ele.prop('funcs').callback) == 'function')
|
||||
ele.prop('funcs').callback();
|
||||
}
|
||||
|
||||
function ccn_datetimepicker_Get(pickerIndex, isUTC) {
|
||||
var ele = $('[datetimepicker=' + pickerIndex + ']');
|
||||
year = ele.attr('datetimepicker-year');
|
||||
month = ele.attr('datetimepicker-month');
|
||||
day = ele.attr('datetimepicker-day');
|
||||
hour = ele.attr('datetimepicker-hour');
|
||||
minute = ele.attr('datetimepicker-minute');
|
||||
if (IsUndefinedOrEmpty(year)) year = ccn_datetime_MIN_YEAR;
|
||||
if (IsUndefinedOrEmpty(month)) month = 1;
|
||||
if (IsUndefinedOrEmpty(day)) day = 1;
|
||||
if (IsUndefinedOrEmpty(hour)) hour = 0;
|
||||
if (IsUndefinedOrEmpty(minute)) minute = 0;
|
||||
|
||||
if (isUTC) return new Date(Date.UTC(year, parseInt(month) - 1, day, hour, minute, 0, 0));
|
||||
else return new Date(year, parseInt(month) - 1, day, hour, minute, 0, 0);
|
||||
}
|
||||
61
frontend-legacy/static/js/headerNav.js
Normal file
61
frontend-legacy/static/js/headerNav.js
Normal file
@@ -0,0 +1,61 @@
|
||||
function ccn_headerNav_Insert() {
|
||||
$('body').prepend(ccn_template_headerNav.render());
|
||||
}
|
||||
|
||||
function ccn_headerNav_LoggedRefresh() {
|
||||
if (ccn_api_common_tokenValid()) {
|
||||
// logged, show all nav button and logout button
|
||||
$("#ccn-header-nav-home").show();
|
||||
$("#ccn-header-nav-collection").show();
|
||||
$("#ccn-header-nav-calendar").show();
|
||||
$("#ccn-header-nav-todo").show();
|
||||
$("#ccn-header-nav-admin").show();
|
||||
|
||||
$("#ccn-header-user-login").hide();
|
||||
$("#ccn-header-user-logout").show();
|
||||
} else {
|
||||
$("#ccn-header-nav-home").show();
|
||||
$("#ccn-header-nav-collection").hide();
|
||||
$("#ccn-header-nav-calendar").hide();
|
||||
$("#ccn-header-nav-todo").hide();
|
||||
$("#ccn-header-nav-admin").hide();
|
||||
|
||||
$("#ccn-header-user-login").show();
|
||||
$("#ccn-header-user-logout").hide();
|
||||
}
|
||||
}
|
||||
|
||||
// bind language process and internal process function such as logout and expand menu
|
||||
function ccn_headerNav_BindEvents() {
|
||||
// bind function
|
||||
$("#ccn-header-language > *").each(function(){
|
||||
$(this).click(function(){
|
||||
ccn_i18n_ChangeLanguage($(this).attr("language"));
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
});
|
||||
});
|
||||
|
||||
// bind logout
|
||||
$("#ccn-header-user-logout").click(function() {
|
||||
if (ccn_api_common_logout()) {
|
||||
// ok, logout
|
||||
// jump into home page again
|
||||
window.location.href = '/web/home';
|
||||
return;
|
||||
|
||||
} else ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-logout"));
|
||||
});
|
||||
|
||||
// bind burger menu
|
||||
// copy from bulma website
|
||||
// Check for click events on the navbar burger icon
|
||||
$(".navbar-burger").click(function() {
|
||||
|
||||
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
|
||||
$(".navbar-burger").toggleClass("is-active");
|
||||
$(".navbar-menu").toggleClass("is-active");
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
89
frontend-legacy/static/js/i18n.js
Normal file
89
frontend-legacy/static/js/i18n.js
Normal file
@@ -0,0 +1,89 @@
|
||||
var ccn_i18n_i18nSupported = ['en-US', 'zh-CN'];
|
||||
var ccn_i18n_currentLanguage = 'en-US';
|
||||
var ccn_pages_enumPages = {
|
||||
home : 0,
|
||||
calendar: 1,
|
||||
todo: 2,
|
||||
admin: 3,
|
||||
login: 4,
|
||||
collection: 5,
|
||||
event: 6
|
||||
};
|
||||
var ccn_pages_currentPage = ccn_pages_enumPages.home;
|
||||
|
||||
// judge current language
|
||||
ccn_i18n_currentLanguage = ccn_localstorageAssist_Get('ccn-i18n', 'en-US');
|
||||
if (ccn_i18n_i18nSupported.indexOf(ccn_i18n_currentLanguage) == -1){
|
||||
ccn_localstorageAssist_Set('ccn-i18n', 'en-US');
|
||||
ccn_i18n_currentLanguage = 'en-US';
|
||||
}
|
||||
|
||||
function ccn_i18n_ChangeLanguage(newLang) {
|
||||
if (ccn_i18n_i18nSupported.indexOf(newLang) == -1) return false;
|
||||
ccn_i18n_currentLanguage = newLang;
|
||||
ccn_localstorageAssist_Set('ccn-i18n', newLang);
|
||||
return true;
|
||||
}
|
||||
|
||||
function ccn_i18n_LoadLanguage() {
|
||||
$.i18n.properties({
|
||||
name: 'strings_' + ccn_i18n_currentLanguage,
|
||||
path: '/static/i18n/',
|
||||
encoding: 'utf-8',
|
||||
mode: 'map',
|
||||
async: false,
|
||||
cache: false,
|
||||
language: ccn_i18n_currentLanguage
|
||||
});
|
||||
}
|
||||
|
||||
function ccn_i18n_ApplyLanguage() {
|
||||
//set usual block
|
||||
var cache = $("[i18n-name]");
|
||||
cache.each(function() {
|
||||
$(this).html($.i18n.prop($(this).attr('i18n-name')));
|
||||
});
|
||||
|
||||
//set unusual block
|
||||
//set title
|
||||
switch(ccn_pages_currentPage) {
|
||||
case ccn_pages_enumPages.home:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-home'));
|
||||
break;
|
||||
case ccn_pages_enumPages.calendar:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-calendar'));
|
||||
break;
|
||||
case ccn_pages_enumPages.todo:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-todo'));
|
||||
break;
|
||||
case ccn_pages_enumPages.admin:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-admin'));
|
||||
break;
|
||||
case ccn_pages_enumPages.login:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-login'));
|
||||
break;
|
||||
case ccn_pages_enumPages.collection:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-collection'));
|
||||
break;
|
||||
case ccn_pages_enumPages.event:
|
||||
$('#ccn-pageName').html($.i18n.prop('ccn-i18n-pageName-event'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_i18n_ApplyLanguage2Content(ctx) {
|
||||
ctx.find("[i18n-name]").each(function() {
|
||||
$(this).html($.i18n.prop($(this).attr('i18n-name')));
|
||||
});
|
||||
}
|
||||
|
||||
// note: month is zero based
|
||||
function ccn_i18n_UniversalGetMonth(month) {
|
||||
return $.i18n.prop('ccn-i18n-universal-month-' + (month + 1));
|
||||
}
|
||||
|
||||
// note: day of week is zero based
|
||||
function ccn_i18n_UniversalGetDayOfWeek(dayOfWeek) {
|
||||
return $.i18n.prop('ccn-i18n-universal-week-' + (dayOfWeek + 1));
|
||||
}
|
||||
|
||||
21
frontend-legacy/static/js/localStorageAssist.js
Normal file
21
frontend-legacy/static/js/localStorageAssist.js
Normal file
@@ -0,0 +1,21 @@
|
||||
function ccn_localstorageAssist_Get(index, defaultValue) {
|
||||
var cache = localStorage.getItem(index);
|
||||
if (cache == null) {
|
||||
ccn_localstorageAssist_Set(index, defaultValue);
|
||||
return defaultValue;
|
||||
} else return cache;
|
||||
}
|
||||
|
||||
function ccn_localstorageAssist_Set(index, value) {
|
||||
localStorage.setItem(index, value);
|
||||
}
|
||||
|
||||
// =================================== seperated data getter setter
|
||||
|
||||
function ccn_localstorageAssist_GetApiToken() {
|
||||
return ccn_localstorageAssist_Get('ccn-token', '');
|
||||
}
|
||||
|
||||
function ccn_localstorageAssist_SetApiToken(value) {
|
||||
ccn_localstorageAssist_Set('ccn-token', value);
|
||||
}
|
||||
19
frontend-legacy/static/js/messagebox.js
Normal file
19
frontend-legacy/static/js/messagebox.js
Normal file
@@ -0,0 +1,19 @@
|
||||
function ccn_messagebox_Insert() {
|
||||
$('body').append(ccn_template_messagebox.render());
|
||||
}
|
||||
|
||||
function ccn_messagebox_Show(/*title,*/ info) {
|
||||
//$('#ccn-messagebox-title').text(title);
|
||||
$('#ccn-messagebox-body').text(info);
|
||||
|
||||
$('#ccn-messagebox-modal').addClass('is-active');
|
||||
}
|
||||
|
||||
function ccn_messagebox_BindEvent() {
|
||||
$('#ccn-messagebox-btnClose').click(ccn_messagebox_Hide);
|
||||
$('#ccn-messagebox-btnConfirm').click(ccn_messagebox_Hide);
|
||||
}
|
||||
|
||||
function ccn_messagebox_Hide() {
|
||||
$('#ccn-messagebox-modal').removeClass('is-active');
|
||||
}
|
||||
265
frontend-legacy/static/js/page/admin.js
Normal file
265
frontend-legacy/static/js/page/admin.js
Normal file
@@ -0,0 +1,265 @@
|
||||
var ccn_admin_userListCache = [];
|
||||
var ccn_admin_tokenListCache = [];
|
||||
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.admin;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// 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);
|
||||
|
||||
// load user tab according to admin status
|
||||
if(!ccn_api_profile_isAdmin())
|
||||
$('#tabcontrol-tab-1-3').hide();
|
||||
|
||||
// apply i18n
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
|
||||
// bind event
|
||||
$('#ccn-admin-profile-btnChangePassword').click(ccn_admin_profile_ChangePassword);
|
||||
$('#ccn-admin-tokenList-btnRefresh').click(ccn_admin_tokenList_Refresh);
|
||||
$('#ccn-admin-userList-btnAdd').click(ccn_admin_userList_Add);
|
||||
$('#ccn-admin-userList-btnRefresh').click(ccn_admin_userList_Refresh);
|
||||
});
|
||||
|
||||
// ================== profile
|
||||
|
||||
function ccn_admin_profile_ChangePassword() {
|
||||
var newpassword = $('#ccn-admin-profile-inputPassword').val();
|
||||
if (newpassword == "") return;
|
||||
|
||||
var result = ccn_api_profile_changePassword(newpassword);
|
||||
if(result) {
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-success"));
|
||||
$('#ccn-admin-profile-inputPassword').val('');
|
||||
} else
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-update"));
|
||||
|
||||
}
|
||||
|
||||
// ================== token
|
||||
|
||||
function ccn_admin_tokenList_Refresh() {
|
||||
ccn_admin_tokenListCache = new Array();
|
||||
var listDOM = $('#ccn-admin-tokenList');
|
||||
listDOM.empty();
|
||||
|
||||
var renderdata = {
|
||||
uuid: undefined,
|
||||
isMe: undefined,
|
||||
ua: undefined,
|
||||
ip: undefined,
|
||||
expireOn: undefined
|
||||
}
|
||||
var gottenDateTime = new Date();
|
||||
|
||||
var result = ccn_api_profile_getToken();
|
||||
if(typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
var item = result[index];
|
||||
renderdata.uuid = item[1];
|
||||
renderdata.isMe = ccn_localstorageAssist_GetApiToken() == item[1];
|
||||
renderdata.ua = item[3];
|
||||
renderdata.ip = item[4];
|
||||
gottenDateTime.setTime(item[2] * 1000);
|
||||
renderdata.expireOn = gottenDateTime.toLocaleString();
|
||||
|
||||
listDOM.append(ccn_template_tokenItem.render(renderdata));
|
||||
|
||||
// bind event
|
||||
var uuid = renderdata.uuid;
|
||||
$("#ccn-tokenItem-btnLogout-" + uuid).click(ccn_admin_tokenList_ItemDelete);
|
||||
|
||||
// add into cache
|
||||
ccn_admin_tokenListCache[uuid] = item;
|
||||
}
|
||||
|
||||
ccn_i18n_ApplyLanguage2Content(listDOM);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_admin_tokenList_ItemDelete() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
var result = ccn_api_profile_deleteToken(uuid);
|
||||
|
||||
if(!result) {
|
||||
// fail
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-delete"));
|
||||
} else {
|
||||
// remove body
|
||||
$("#ccn-tokenItem-" + uuid).remove();
|
||||
}
|
||||
}
|
||||
|
||||
// ================== user list
|
||||
|
||||
function ccn_admin_userList_RefreshCacheList() {
|
||||
ccn_admin_userListCache = new Array();
|
||||
|
||||
var result = ccn_api_admin_get();
|
||||
if(typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
ccn_admin_userListCache[index] = result[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_admin_userList_RenderItem(item, index, listDOM) {
|
||||
var renderdata = {
|
||||
uuid: index, // use index for uuid. there are no uuid for user
|
||||
username: item[0]
|
||||
}
|
||||
|
||||
// render
|
||||
listDOM.append(ccn_template_userItem.render(renderdata));
|
||||
|
||||
// set mode
|
||||
var uuid = index;
|
||||
ccn_admin_userList_ChangeDisplayMode(uuid, false, item[1])
|
||||
|
||||
// bind event
|
||||
$("#ccn-userItem-btnEdit-" + uuid).click(ccn_admin_userList_ItemEdit);
|
||||
$("#ccn-userItem-btnDelete-" + uuid).click(ccn_admin_userList_ItemDelete);
|
||||
$("#ccn-userItem-btnUpdate-" + uuid).click(ccn_admin_userList_ItemUpdate);
|
||||
$("#ccn-userItem-btnCancelUpdate-" + uuid).click(ccn_admin_userList_ItemCancelUpdate);
|
||||
}
|
||||
|
||||
function ccn_admin_userList_RenderCacheList() {
|
||||
$('#ccn-admin-userList').empty();
|
||||
|
||||
var listDOM = $('#ccn-admin-userList');
|
||||
for(var index in ccn_admin_userListCache) {
|
||||
ccn_admin_userList_RenderItem(
|
||||
ccn_admin_userListCache[index],
|
||||
index,
|
||||
listDOM
|
||||
)
|
||||
}
|
||||
|
||||
ccn_i18n_ApplyLanguage2Content(listDOM);
|
||||
}
|
||||
|
||||
function ccn_admin_userList_ChangeDisplayMode(uuid, isEdit, isAdmin) {
|
||||
if (typeof(isAdmin) != 'undefined') {
|
||||
if (isAdmin)
|
||||
$("#ccn-userItem-iconIsAdmin-" + uuid).show();
|
||||
else
|
||||
$("#ccn-userItem-iconIsAdmin-" + uuid).hide();
|
||||
}
|
||||
|
||||
if (typeof(isEdit) != 'undefined') {
|
||||
if (isEdit) {
|
||||
$("#ccn-userItem-btnEdit-" + uuid).hide();
|
||||
$("#ccn-userItem-btnDelete-" + uuid).hide();
|
||||
$("#ccn-userItem-btnUpdate-" + uuid).show();
|
||||
$("#ccn-userItem-btnCancelUpdate-" + uuid).show();
|
||||
|
||||
$("#ccn-userItem-boxPassword-" + uuid).show();
|
||||
$("#ccn-userItem-boxIsAdmin-" + uuid).show();
|
||||
} else {
|
||||
$("#ccn-userItem-btnEdit-" + uuid).show();
|
||||
$("#ccn-userItem-btnDelete-" + uuid).show();
|
||||
$("#ccn-userItem-btnUpdate-" + uuid).hide();
|
||||
$("#ccn-userItem-btnCancelUpdate-" + uuid).hide();
|
||||
|
||||
$("#ccn-userItem-boxPassword-" + uuid).hide();
|
||||
$("#ccn-userItem-boxIsAdmin-" + uuid).hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_admin_userList_Refresh() {
|
||||
// refresh and render once
|
||||
ccn_admin_userList_RefreshCacheList();
|
||||
ccn_admin_userList_RenderCacheList();
|
||||
}
|
||||
|
||||
function ccn_admin_userList_Add() {
|
||||
var username = $('#ccn-admin-userList-inputUsername').val();
|
||||
if (username == "") return;
|
||||
|
||||
var result = ccn_api_admin_add(username);
|
||||
if (typeof(result) == 'undefined') {
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-add"));
|
||||
} else {
|
||||
// render
|
||||
var index = ccn_admin_userListCache.push(result) - 1;
|
||||
var listDOM = $('#ccn-admin-userList');
|
||||
ccn_admin_userList_RenderItem(result, index, listDOM);
|
||||
ccn_i18n_ApplyLanguage2Content(listDOM);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_admin_userList_ItemEdit() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
// copy isAdmin to checkbox and clean password box
|
||||
$('#ccn-userItem-inputIsAdmin-' + uuid).prop("checked", ccn_admin_userListCache[uuid][1]);
|
||||
$('#ccn-userItem-inputPassword-' + uuid).val('');
|
||||
|
||||
// switch to edit mode
|
||||
ccn_admin_userList_ChangeDisplayMode(uuid, true, undefined);
|
||||
}
|
||||
|
||||
function ccn_admin_userList_ItemDelete() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
var result = ccn_api_admin_delete(ccn_admin_userListCache[uuid][0]);
|
||||
|
||||
if(!result) {
|
||||
// fail
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-delete"));
|
||||
} else {
|
||||
// remove body
|
||||
$("#ccn-userItem-" + uuid).remove();
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_admin_userList_ItemUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
var newpassword = $('#ccn-userItem-inputPassword-' + uuid).val();
|
||||
var isAdmin = $('#ccn-userItem-inputIsAdmin-' + uuid).prop("checked");
|
||||
|
||||
var result = ccn_api_admin_update(
|
||||
ccn_admin_userListCache[uuid][0],
|
||||
newpassword == "" ? undefined : newpassword,
|
||||
isAdmin == ccn_admin_userListCache[uuid][1] ? undefined : isAdmin);
|
||||
|
||||
if (!result) {
|
||||
// fail
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-update"));
|
||||
} else {
|
||||
// safely update data
|
||||
ccn_admin_userListCache[uuid][1] = isAdmin
|
||||
|
||||
// switch to normal mode
|
||||
ccn_admin_userList_ChangeDisplayMode(uuid, false, isAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_admin_userList_ItemCancelUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
ccn_admin_userList_ChangeDisplayMode(uuid, false, undefined);
|
||||
}
|
||||
376
frontend-legacy/static/js/page/calendar.js
Normal file
376
frontend-legacy/static/js/page/calendar.js
Normal file
@@ -0,0 +1,376 @@
|
||||
// 2 list which will store sharing and shared collection's display mode.
|
||||
// key is uuid, value is bool
|
||||
var ccn_calendar_owned_displayCache = [];
|
||||
var ccn_calendar_shared_displayCache = [];
|
||||
|
||||
// modal editing object.
|
||||
// undefined mean add
|
||||
// not undefined mean update(a copy of calendar event)
|
||||
var ccn_calendar_eventModal_editing = undefined;
|
||||
var ccn_calendar_eventModal_collectionCache = [];
|
||||
var ccn_calendar_calendar_listCache = [];
|
||||
var ccn_calendar_calendar_displayCache = [];
|
||||
var ccn_calendar_calendar_displayDateTime = 0;
|
||||
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.calendar;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// process calendar it self
|
||||
ccn_calendar_calendar_LoadCalendarBody();
|
||||
|
||||
// init datetimepicker and preset
|
||||
ccn_datetimepicker_Insert();
|
||||
var nowtime = new Date();
|
||||
ccn_datetimepicker_Set(1, nowtime, false, ccn_datetimepicker_tabType.month);
|
||||
|
||||
// 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_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
|
||||
//refresh once
|
||||
ccn_calendar_collection_Refresh();
|
||||
ccn_calendar_calendar_Refresh();
|
||||
ccn_calendar_calendar_Analyse();
|
||||
ccn_calendar_calendar_Render();
|
||||
|
||||
// bind event
|
||||
$('#ccn-calendar-collection-btnRefresh').click(ccn_calendar_collection_Refresh);
|
||||
|
||||
$('#ccn-calendar-calendar-btnJump')
|
||||
.prop('funcs', {callback: ccn_calendar_calendar_btnRefresh})
|
||||
.click(function() {
|
||||
ccn_datetimepicker_Modal(
|
||||
ccn_datetimepicker_tabType.month,
|
||||
1,
|
||||
false);
|
||||
});
|
||||
$('#ccn-calendar-calendar-btnToday').click(ccn_calendar_calendar_btnToday);
|
||||
$('#ccn-calendar-calendar-btnAdd').click(ccn_calendar_calendar_btnAdd);
|
||||
});
|
||||
|
||||
// ================== calendar
|
||||
|
||||
function ccn_calendar_calendar_LoadCalendarBody() {
|
||||
$('#ccn-calendar-calendarBody').append(ccn_template_calendarItem.render());
|
||||
}
|
||||
|
||||
// this function only refresh cache list
|
||||
function ccn_calendar_calendar_Refresh() {
|
||||
var gottenDateTime = ccn_datetimepicker_Get(1, false);
|
||||
var gottenYear = gottenDateTime.getFullYear();
|
||||
var gottenMonth = gottenDateTime.getMonth() + 1;
|
||||
$('#ccn-calendar-calendar-textMonth').text('{0} - {1}'.format(gottenYear, ccn_i18n_UniversalGetMonth(gottenMonth - 1)));
|
||||
// don't need to set anything, because its default value is enough to use.
|
||||
|
||||
var gottenWeek = ccn_datetime_DayOfWeek(gottenYear, gottenMonth, 1);
|
||||
var startTimestamp = Math.floor(gottenDateTime.getTime() / 60000) - gottenWeek * ccn_datetime_DAY1_SPAN;
|
||||
var endTimestamp = startTimestamp + ccn_datetime_DAY1_SPAN * 6 * 7 - 1;
|
||||
|
||||
ccn_calendar_calendar_listCache = new Array();
|
||||
var result = ccn_api_calendar_getFull(startTimestamp, endTimestamp);
|
||||
if (typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
ccn_calendar_calendar_listCache[result[index][0]] = result[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this function take responsibility to analyse event
|
||||
// call datetime function to resolve loop event
|
||||
// and split event if some event cross 2+ days
|
||||
function ccn_calendar_calendar_Analyse() {
|
||||
// first, we need construct ccn_calendar_calendar_displayCache
|
||||
ccn_calendar_calendar_displayCache = new Array();
|
||||
var gottenDateTime = ccn_datetimepicker_Get(1, false);
|
||||
var gottenYear = gottenDateTime.getFullYear();
|
||||
var gottenMonth = gottenDateTime.getMonth() + 1;
|
||||
var gottenWeek = ccn_datetime_DayOfWeek(gottenYear, gottenMonth, 1);
|
||||
var startTimestamp = Math.floor(gottenDateTime.getTime() / 60000) - gottenWeek * ccn_datetime_DAY1_SPAN;
|
||||
var endTimestamp = startTimestamp + ccn_datetime_DAY1_SPAN * 6 * 7 - 1;
|
||||
gottenDateTime.setTime(startTimestamp * 60000);
|
||||
for(var index = 0; index < 6 * 7; index++) {
|
||||
ccn_calendar_calendar_displayCache.push({
|
||||
month: gottenDateTime.getMonth() + 1,
|
||||
day: gottenDateTime.getDate(),
|
||||
dayOfWeek: gottenDateTime.getWeekday() + 1,
|
||||
subcalendar: "",
|
||||
isCurrentMonth: (gottenDateTime.getMonth() + 1) == gottenMonth,
|
||||
events: new Array()
|
||||
});
|
||||
gottenDateTime.setTime(gottenDateTime.getTime() + ccn_datetime_DAY1_SPAN * 60000);
|
||||
}
|
||||
|
||||
var mytimezone = -(new Date().getTimezoneOffset());
|
||||
// then analyse each event
|
||||
for(var index in ccn_calendar_calendar_listCache) {
|
||||
var item = ccn_calendar_calendar_listCache[index];
|
||||
var deserializedDescription = ccn_api_deserializeDescription(item[3]);
|
||||
|
||||
var minStartTimestamp = startTimestamp - (item[6] - item[5]);
|
||||
var result = ccn_datetime_ResolveLoopRules4Event(
|
||||
item[8],
|
||||
item[9] < minStartTimestamp ? minStartTimestamp : item[9],
|
||||
Math.min(item[10], endTimestamp),
|
||||
item[5],
|
||||
item[6],
|
||||
item[7],
|
||||
startTimestamp
|
||||
);
|
||||
if(typeof(result) != 'undefined') {
|
||||
for(var i in result) {
|
||||
var it = result[i];
|
||||
// try get event belong to which cell
|
||||
var eventDateTime = new Date(it[0] * 60000);
|
||||
var count = Math.floor((it[0] - startTimestamp) / ccn_datetime_DAY1_SPAN);
|
||||
var exitFlag = false;
|
||||
// then split event
|
||||
while(count < 6 * 7) {
|
||||
var eventItem = {
|
||||
uuid: item[0],
|
||||
belongTo: item[1],
|
||||
title: item[2],
|
||||
description: deserializedDescription.description,
|
||||
color: deserializedDescription.color,
|
||||
isVisible: true,
|
||||
isLocked: typeof(ccn_calendar_owned_displayCache[item[0]]) != 'undefined',
|
||||
loopText: ccn_datetime_ResolveLoopRules4Text(item[8], item[5], item[7]),
|
||||
timezoneWarning: mytimezone != item[7],
|
||||
start: eventDateTime.toLocaleTimeString(),
|
||||
end: undefined // filled in follwing code
|
||||
}
|
||||
eventDateTime.setHours(23, 59, 0, 0);
|
||||
if (it[1] <= Math.floor(eventDateTime.getTime() / 60000)) {
|
||||
exitFlag = true;
|
||||
eventDateTime.setTime(it[1] * 60000);
|
||||
}
|
||||
eventItem.end = eventDateTime.toLocaleTimeString();
|
||||
ccn_calendar_calendar_displayCache[count].events.push(eventItem);
|
||||
if (exitFlag) break;
|
||||
else eventDateTime.setMinutes(eventDateTime.getMinutes() + 1, 0, 0);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// just use produced ccn_calendar_calendar_displayCache
|
||||
// to re-generate ui
|
||||
function ccn_calendar_calendar_Render() {
|
||||
// todo: add / migrate subcalendar feature here
|
||||
|
||||
|
||||
// analyse visible data
|
||||
for(var i in ccn_calendar_calendar_displayCache) {
|
||||
for(var j in ccn_calendar_calendar_displayCache[i].events) {
|
||||
var gottenOwnedVisible = ccn_calendar_owned_displayCache[
|
||||
ccn_calendar_calendar_displayCache[i].events[j].belongTo
|
||||
];
|
||||
if (typeof(gottenOwnedVisible) == 'undefined') gottenOwnedVisible = false;
|
||||
var gottenSharedVisible = ccn_calendar_shared_displayCache[
|
||||
ccn_calendar_calendar_displayCache[i].events[j].belongTo
|
||||
];
|
||||
if (typeof(gottenSharedVisible) == 'undefined') gottenSharedVisible = false;
|
||||
|
||||
ccn_calendar_calendar_displayCache[i].events[j].isVisible = gottenOwnedVisible || gottenSharedVisible;
|
||||
}
|
||||
}
|
||||
|
||||
// just render them
|
||||
var listDOM = $('#ccn-calendar-scheduleList');
|
||||
listDOM.empty();
|
||||
listDOM.append(ccn_template_scheduleItem.render({renderdata: ccn_calendar_calendar_displayCache}));
|
||||
// link click event
|
||||
$('div.schedule-event-outter').click(ccn_calendar_calendar_ItemUpdate);
|
||||
|
||||
// all data has been alanysed, feedback to calendar body.
|
||||
var counter = 0;
|
||||
for(var i = 0; i < 6; i++) {
|
||||
for(var j = 0; j < 7; j++) {
|
||||
var item = ccn_calendar_calendar_displayCache[counter];
|
||||
var lenEvents = item.events.length;
|
||||
var eventsCounter = 0;
|
||||
|
||||
$('#ccn-calendarItem-' + i + '-' + j).attr('isCurrentMonth', item.isCurrentMonth ? 'true' : 'false');
|
||||
|
||||
$('#ccn-calendarItem-title-' + i + '-' + j).text(item.day);
|
||||
$('#ccn-calendarItem-desc-' + i + '-' + j).text(item.subcalendar);
|
||||
|
||||
|
||||
for(; eventsCounter < Math.min(lenEvents, 4); eventsCounter++) {
|
||||
$('#ccn-calendarItem-eventBox' + (eventsCounter + 1) + '-' + i + '-' + j)
|
||||
.css('background', item.events[eventsCounter].color)
|
||||
.attr('enableDisplay', 'true');
|
||||
}
|
||||
if (lenEvents > 4) {
|
||||
// more than 4 item, write number
|
||||
$('#ccn-calendarItem-task-' + i + '-' + j).text(
|
||||
$.i18n.prop('ccn-i18n-calendar-calendar-stripedEvents').format(lenEvents.toString())
|
||||
);
|
||||
} else {
|
||||
// otherwise, wipe out number
|
||||
$('#ccn-calendarItem-task-' + i + '-' + j).html(' ');
|
||||
// set others div are blank
|
||||
for(; eventsCounter < 4; eventsCounter++) {
|
||||
$('#ccn-calendarItem-eventBox' + (eventsCounter + 1) + '-' + i + '-' + j)
|
||||
.attr('enableDisplay', 'false');
|
||||
}
|
||||
}
|
||||
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
ccn_i18n_ApplyLanguage2Content(listDOM);
|
||||
}
|
||||
|
||||
function ccn_calendar_calendar_btnRefresh() {
|
||||
ccn_calendar_calendar_Refresh();
|
||||
ccn_calendar_calendar_Analyse();
|
||||
ccn_calendar_calendar_Render();
|
||||
}
|
||||
|
||||
function ccn_calendar_calendar_btnToday() {
|
||||
var nowtime = new Date();
|
||||
ccn_datetimepicker_Set(1, nowtime, false, ccn_datetimepicker_tabType.month);
|
||||
ccn_calendar_calendar_Refresh();
|
||||
ccn_calendar_calendar_Analyse();
|
||||
ccn_calendar_calendar_Render();
|
||||
}
|
||||
|
||||
function ccn_calendar_calendar_btnAdd() {
|
||||
window.location.href = '/web/eventAdd';
|
||||
}
|
||||
|
||||
function ccn_calendar_calendar_ItemUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
window.location.href = '/web/eventUpdate/' + uuid;
|
||||
}
|
||||
|
||||
// ============================= collection
|
||||
|
||||
function ccn_calendar_collection_Refresh() {
|
||||
ccn_calendar_owned_displayCache = new Array();
|
||||
ccn_calendar_shared_displayCache = new Array();
|
||||
|
||||
// render shared
|
||||
var result = ccn_api_collection_getShared();
|
||||
var listDOM = $('#ccn-calendar-sharedList');
|
||||
listDOM.empty();
|
||||
var renderdata = {
|
||||
uuid: undefined,
|
||||
name: undefined,
|
||||
username: undefined
|
||||
}
|
||||
if (typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
var item = result[index];
|
||||
renderdata.uuid = item[0];
|
||||
renderdata.name = item[1];
|
||||
renderdata.username = item[2];
|
||||
|
||||
listDOM.append(ccn_template_displaySharedItem.render(renderdata));
|
||||
|
||||
// change display
|
||||
var uuid = renderdata.uuid;
|
||||
ccn_calendar_shared_ChangeDisplayMode(uuid, true);
|
||||
|
||||
// push into display list
|
||||
ccn_calendar_shared_displayCache[uuid] = true;
|
||||
|
||||
// bind event
|
||||
$('#ccn-displaySharedItem-btnHide-' + uuid).click(ccn_calendar_shared_ItemSwitchDisplay);
|
||||
$('#ccn-displaySharedItem-btnShow-' + uuid).click(ccn_calendar_shared_ItemSwitchDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
ccn_i18n_ApplyLanguage2Content(listDOM);
|
||||
|
||||
// render owned
|
||||
result = ccn_api_collection_getFullOwn();
|
||||
listDOM = $('#ccn-calendar-ownedList');
|
||||
listDOM.empty();
|
||||
renderdata = {
|
||||
uuid: undefined,
|
||||
name: undefined
|
||||
}
|
||||
if (typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
var item = result[index];
|
||||
renderdata.uuid = item[0];
|
||||
renderdata.name = item[1];
|
||||
|
||||
// render
|
||||
listDOM.append(ccn_template_displayOwnedItem.render(renderdata));
|
||||
|
||||
// set mode
|
||||
var uuid = renderdata.uuid;
|
||||
ccn_calendar_owned_ChangeDisplayMode(uuid, true);
|
||||
|
||||
// push into display list
|
||||
ccn_calendar_owned_displayCache[uuid] = true;
|
||||
|
||||
// bind event
|
||||
$('#ccn-displayOwnedItem-btnHide-' + uuid).click(ccn_calendar_owned_ItemSwitchDisplay);
|
||||
$('#ccn-displayOwnedItem-btnShow-' + uuid).click(ccn_calendar_owned_ItemSwitchDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ccn_calendar_owned_ItemSwitchDisplay() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
ccn_calendar_owned_displayCache[uuid] = !(ccn_calendar_owned_displayCache[uuid]);
|
||||
ccn_calendar_owned_ChangeDisplayMode(uuid, ccn_calendar_owned_displayCache[uuid]);
|
||||
}
|
||||
|
||||
function ccn_calendar_shared_ItemSwitchDisplay() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
ccn_calendar_shared_displayCache[uuid] = !(ccn_calendar_shared_displayCache[uuid]);
|
||||
ccn_calendar_shared_ChangeDisplayMode(uuid, ccn_calendar_shared_displayCache[uuid]);
|
||||
}
|
||||
|
||||
function ccn_calendar_shared_ChangeDisplayMode(uuid, isShow) {
|
||||
if (isShow) {
|
||||
$('#ccn-displaySharedItem-btnHide-' + uuid).show();
|
||||
$('#ccn-displaySharedItem-btnShow-' + uuid).hide();
|
||||
} else {
|
||||
$('#ccn-displaySharedItem-btnHide-' + uuid).hide();
|
||||
$('#ccn-displaySharedItem-btnShow-' + uuid).show();
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_calendar_owned_ChangeDisplayMode(uuid, isShow) {
|
||||
if (isShow) {
|
||||
$('#ccn-displayOwnedItem-btnHide-' + uuid).show();
|
||||
$('#ccn-displayOwnedItem-btnShow-' + uuid).hide();
|
||||
} else {
|
||||
$('#ccn-displayOwnedItem-btnHide-' + uuid).hide();
|
||||
$('#ccn-displayOwnedItem-btnShow-' + uuid).show();
|
||||
}
|
||||
}
|
||||
288
frontend-legacy/static/js/page/collection.js
Normal file
288
frontend-legacy/static/js/page/collection.js
Normal file
@@ -0,0 +1,288 @@
|
||||
// 3 used cache list
|
||||
var ccn_collection_owned_listCache = [];
|
||||
var ccn_collection_sharing_listCache = [];
|
||||
|
||||
// current editing sharing collection
|
||||
var ccn_collection_sharing_editingOwned = undefined; // the uuid of owned collection
|
||||
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.collection;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// apply i18n
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
|
||||
//refresh once
|
||||
ccn_collection_owned_Refresh();
|
||||
|
||||
// bind event
|
||||
//$('#ccn-calendar-shared-btnRefresh').click(ccn_calendar_shared_Refresh);
|
||||
$('#ccn-collection-owned-btnAdd').click(ccn_collection_owned_Add);
|
||||
$('#ccn-collection-owned-btnRefresh').click(ccn_collection_owned_Refresh);
|
||||
$('#ccn-collection-sharing-btnAdd').click(ccn_collection_sharing_Add);
|
||||
$('#ccn-collection-sharing-btnRefresh').click(ccn_collection_sharing_Refresh);
|
||||
|
||||
});
|
||||
|
||||
|
||||
function ccn_collection_owned_Refresh() {
|
||||
ccn_collection_owned_listCache = new Array();
|
||||
ccn_collection_sharing_displayCache = new Array();
|
||||
|
||||
var result = ccn_api_collection_getFullOwn();
|
||||
if(typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
ccn_collection_owned_listCache[result[index][0]] = result[index];
|
||||
}
|
||||
}
|
||||
|
||||
// render
|
||||
var listDOM = $('#ccn-collection-ownedList');
|
||||
listDOM.empty();
|
||||
for(var index in ccn_collection_owned_listCache) {
|
||||
ccn_collection_owned_RenderItem(
|
||||
ccn_collection_owned_listCache[index],
|
||||
listDOM
|
||||
);
|
||||
}
|
||||
|
||||
// also, order sharing list clean
|
||||
ccn_collection_sharing_editingOwned = undefined;
|
||||
ccn_collection_sharing_Refresh();
|
||||
}
|
||||
|
||||
function ccn_collection_owned_RenderItem(item, listDOM) {
|
||||
var renderdata = {
|
||||
uuid: item[0],
|
||||
name: item[1]
|
||||
}
|
||||
|
||||
// render
|
||||
listDOM.append(ccn_template_ownedItem.render(renderdata));
|
||||
|
||||
// set mode
|
||||
var uuid = renderdata.uuid;
|
||||
ccn_collection_owned_ChangeDisplayMode(uuid, false);
|
||||
|
||||
// bind event
|
||||
$('#ccn-ownedItem-btnEdit-' + uuid).click(ccn_collection_owned_ItemEdit);
|
||||
$('#ccn-ownedItem-btnDelete-' + uuid).click(ccn_collection_owned_ItemDelete);
|
||||
$('#ccn-ownedItem-btnShare-' + uuid).click(ccn_collection_owned_ItemShare);
|
||||
$('#ccn-ownedItem-btnUpdate-' + uuid).click(ccn_collection_owned_ItemUpdate);
|
||||
$('#ccn-ownedItem-btnCancelUpdate-' + uuid).click(ccn_collection_owned_ItemCancelUpdate);
|
||||
|
||||
}
|
||||
|
||||
function ccn_collection_owned_ChangeDisplayMode(uuid, isEdit) {
|
||||
if (isEdit) {
|
||||
$('#ccn-ownedItem-btnEdit-' + uuid).hide();
|
||||
$('#ccn-ownedItem-btnShare-' + uuid).hide();
|
||||
$('#ccn-ownedItem-btnDelete-' + uuid).hide();
|
||||
|
||||
$('#ccn-ownedItem-btnUpdate-' + uuid).show();
|
||||
$('#ccn-ownedItem-btnCancelUpdate-' + uuid).show();
|
||||
|
||||
$('#ccn-ownedItem-textName-' + uuid).hide();
|
||||
$('#ccn-ownedItem-boxName-' + uuid).show();
|
||||
} else {
|
||||
$('#ccn-ownedItem-btnEdit-' + uuid).show();
|
||||
$('#ccn-ownedItem-btnShare-' + uuid).show();
|
||||
$('#ccn-ownedItem-btnDelete-' + uuid).show();
|
||||
|
||||
$('#ccn-ownedItem-btnUpdate-' + uuid).hide();
|
||||
$('#ccn-ownedItem-btnCancelUpdate-' + uuid).hide();
|
||||
|
||||
$('#ccn-ownedItem-textName-' + uuid).show();
|
||||
$('#ccn-ownedItem-boxName-' + uuid).hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ccn_collection_sharing_Refresh() {
|
||||
ccn_collection_sharing_listCache = new Array();
|
||||
|
||||
if (typeof(ccn_collection_sharing_editingOwned) != 'undefined') {
|
||||
var result = ccn_api_collection_getSharing(ccn_collection_sharing_editingOwned);
|
||||
if (typeof(result) != 'undefined') {
|
||||
for(var index in result) {
|
||||
ccn_collection_sharing_listCache[index] = result[index];
|
||||
// also, sharingTarget don't have uuid, use index instead
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update editing text
|
||||
$('#ccn-collection-sharing-sharingEditing').text(
|
||||
typeof(ccn_collection_sharing_editingOwned) == 'undefined' ?
|
||||
'' :
|
||||
ccn_collection_owned_listCache[ccn_collection_sharing_editingOwned][1]
|
||||
);
|
||||
|
||||
// if editing is undefined, hide container
|
||||
if (typeof(ccn_collection_sharing_editingOwned) == 'undefined')
|
||||
$('#ccn-collection-sharing-container').hide();
|
||||
else
|
||||
$('#ccn-collection-sharing-container').show();
|
||||
|
||||
|
||||
var listDOM = $('#ccn-collection-sharingList');
|
||||
listDOM.empty();
|
||||
for(var index in ccn_collection_sharing_listCache) {
|
||||
ccn_collection_sharing_RenderItem(
|
||||
ccn_collection_sharing_listCache[index],
|
||||
index,
|
||||
listDOM
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_collection_sharing_RenderItem(item, index, listDOM) {
|
||||
var renderdata = {
|
||||
uuid: index,
|
||||
username: item
|
||||
}
|
||||
|
||||
// render
|
||||
listDOM.append(ccn_template_sharingItem.render(renderdata));
|
||||
|
||||
// bind event
|
||||
var uuid = index;
|
||||
$("#ccn-sharingItem-btnDelete-" + uuid).click(ccn_collection_sharing_ItemDelete);
|
||||
}
|
||||
|
||||
// ========================= input operation
|
||||
|
||||
function ccn_collection_owned_Add() {
|
||||
var newname = $('#ccn-collection-owned-inputAdd').val();
|
||||
if (newname == "") return;
|
||||
|
||||
var result = ccn_api_collection_addOwn(newname);
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-add"));
|
||||
else {
|
||||
// second get. get detail
|
||||
result = ccn_api_collection_getDetailOwn(result);
|
||||
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-get"));
|
||||
else {
|
||||
// render
|
||||
ccn_collection_owned_listCache[result[0]] = result;
|
||||
var listDOM = $('#ccn-collection-ownedList');
|
||||
ccn_collection_owned_RenderItem(result, listDOM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_collection_owned_ItemEdit() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
// preset inputbox
|
||||
$('#ccn-ownedItem-inputName-' + uuid).val(
|
||||
ccn_collection_owned_listCache[uuid][1]
|
||||
);
|
||||
|
||||
// switch to edit mode
|
||||
ccn_collection_owned_ChangeDisplayMode(uuid, true);
|
||||
}
|
||||
|
||||
function ccn_collection_owned_ItemDelete() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
var result = ccn_api_collection_deleteOwn(
|
||||
uuid,
|
||||
ccn_collection_owned_listCache[uuid][2]
|
||||
);
|
||||
if (!result) ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-delete"));
|
||||
else {
|
||||
$('#ccn-ownedItem-' + uuid).remove();
|
||||
|
||||
// also, we should notice sharing target, and try clean it
|
||||
if (ccn_collection_sharing_editingOwned == uuid) {
|
||||
ccn_collection_sharing_editingOwned = undefined;
|
||||
ccn_collection_sharing_Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_collection_owned_ItemUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
var newname = $('#ccn-ownedItem-inputName-' + uuid).val();
|
||||
|
||||
var result = ccn_api_collection_updateOwn(uuid, newname, ccn_collection_owned_listCache[uuid][2]);
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-update"));
|
||||
else {
|
||||
// update last change
|
||||
ccn_collection_owned_listCache[uuid][2] = result;
|
||||
ccn_collection_owned_listCache[uuid][1] = newname;
|
||||
// update elements
|
||||
$('#ccn-ownedItem-textName-' + uuid).text(newname);
|
||||
// if editing, update sharing target
|
||||
if (ccn_collection_sharing_editingOwned == uuid)
|
||||
ccn_collection_sharing_Refresh();
|
||||
// back to normal mode
|
||||
ccn_collection_owned_ChangeDisplayMode(uuid, false);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_collection_owned_ItemCancelUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
ccn_collection_owned_ChangeDisplayMode(uuid, false);
|
||||
}
|
||||
|
||||
function ccn_collection_owned_ItemShare() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
ccn_collection_sharing_editingOwned = uuid;
|
||||
ccn_collection_sharing_Refresh();
|
||||
}
|
||||
|
||||
|
||||
function ccn_collection_sharing_Add() {
|
||||
var newusername = $('#ccn-collection-sharing-inputAdd').val();
|
||||
if (newusername == "" || typeof(ccn_collection_sharing_editingOwned) == 'undefined') return;
|
||||
|
||||
var result = ccn_api_collection_addSharing(
|
||||
ccn_collection_sharing_editingOwned,
|
||||
newusername,
|
||||
ccn_collection_owned_listCache[ccn_collection_sharing_editingOwned][2]
|
||||
);
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-add"));
|
||||
else {
|
||||
// add new item
|
||||
var index = ccn_collection_sharing_listCache.push(newusername) - 1;
|
||||
var listDOM = $('#ccn-collection-sharingList');
|
||||
ccn_collection_sharing_RenderItem(newusername, index, listDOM);
|
||||
// update last change
|
||||
ccn_collection_owned_listCache[ccn_collection_sharing_editingOwned][2] = result;
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_collection_sharing_ItemDelete() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
var username = ccn_collection_sharing_listCache[uuid];
|
||||
|
||||
var result = ccn_api_collection_deleteSharing(
|
||||
ccn_collection_sharing_editingOwned,
|
||||
username,
|
||||
ccn_collection_owned_listCache[ccn_collection_sharing_editingOwned][2]
|
||||
);
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-delete"));
|
||||
else {
|
||||
// remove item in ui
|
||||
$('#ccn-sharingItem-' + uuid).remove();
|
||||
// update last change
|
||||
ccn_collection_owned_listCache[ccn_collection_sharing_editingOwned][2] = result;
|
||||
}
|
||||
}
|
||||
|
||||
447
frontend-legacy/static/js/page/event.js
Normal file
447
frontend-legacy/static/js/page/event.js
Normal file
@@ -0,0 +1,447 @@
|
||||
// if it is undefined, current mode is add
|
||||
// or it is the detail data gotten from api
|
||||
var ccn_event_editingEvent = undefined;
|
||||
var ccn_event_collectionCache = [];
|
||||
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.event;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// init datetimepicker
|
||||
ccn_datetimepicker_Insert();
|
||||
|
||||
// apply i18n
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
|
||||
// bind event
|
||||
$('input[type=radio][name=loop-method]').click(ccn_event_RefreshRadioDiaplay);
|
||||
$('input[type=radio][name=loop-end]').click(ccn_event_RefreshRadioDiaplay);
|
||||
|
||||
$('#ccn-event-btnSubmit').click(ccn_event_btnSubmit);
|
||||
$('#ccn-event-btnCancel').click(ccn_event_btnCancel);
|
||||
$('#ccn-event-btnSpot').click(ccn_event_btnSpot);
|
||||
$('#ccn-event-btnFullDay').click(ccn_event_btnFullDay);
|
||||
$('#ccn-event-btnStartDateTime')
|
||||
.prop('funcs', {callback: function() {
|
||||
ccn_event_UpdateDateTimePickerButton(1);
|
||||
ccn_event_RefreshLoopMonthType();
|
||||
}})
|
||||
.click(ccn_event_btnDateTimePicker);
|
||||
$('#ccn-event-btnEndDateTime')
|
||||
.prop('funcs', {callback: function() {ccn_event_UpdateDateTimePickerButton(2);}})
|
||||
.click(ccn_event_btnDateTimePicker);
|
||||
$('#ccn-event-btnLoopStopDateTime')
|
||||
.prop('funcs', {callback: function() {ccn_event_UpdateDateTimePickerButton(3);}})
|
||||
.click(ccn_event_btnDateTimePicker);
|
||||
|
||||
// init form
|
||||
ccn_event_Init();
|
||||
|
||||
// refresh once
|
||||
ccn_event_RefreshRadioDiaplay();
|
||||
ccn_event_RefreshLoopMonthType();
|
||||
});
|
||||
|
||||
|
||||
function ccn_event_Init() {
|
||||
// we need init some elements first
|
||||
|
||||
// we need all radio and checkbox's checked is false, not undefined.
|
||||
$('input[type=radio]').prop("checked", false);
|
||||
$('input[type=checkbox]').prop("checked", false);
|
||||
|
||||
// init span picker
|
||||
$('.spanpicker').attr('max', 100)
|
||||
.attr('min', 1)
|
||||
.attr('step', 1)
|
||||
.val(1);
|
||||
|
||||
// in there, we need get uuid from meta
|
||||
var uuid = $('meta[name=uuid]').attr('content');
|
||||
if (uuid != "")
|
||||
ccn_event_editingEvent = ccn_api_calendar_getDetail(uuid);
|
||||
// if ccn_event_editingEvent is undefined, init following content with add mode
|
||||
// otherwise, init as update mode
|
||||
var isAdd = typeof(ccn_event_editingEvent) == 'undefined';
|
||||
var deserializeDescription = isAdd ? undefined : ccn_api_deserializeDescription(ccn_event_editingEvent[3]);
|
||||
|
||||
// init title and description
|
||||
$('#ccn-event-inputTitle').val(
|
||||
isAdd ? '' : ccn_event_editingEvent[2]
|
||||
);
|
||||
$('#ccn-event-inputDescription').val(
|
||||
isAdd ? '' : deserializeDescription.description
|
||||
);
|
||||
$('#ccn-event-inputColor').val(
|
||||
isAdd ? DefaultColor : deserializeDescription.color
|
||||
);
|
||||
|
||||
// init collection picker, first we need query data
|
||||
// and render it
|
||||
var collectionDOM = $('#ccn-event-inputCollection');
|
||||
collectionDOM.empty();
|
||||
ccn_event_collectionCache = new Array();
|
||||
var result = ccn_api_collection_getFullOwn();
|
||||
if (typeof(result) != 'undefined') {
|
||||
var renderdata = {
|
||||
val: undefined,
|
||||
name: undefined
|
||||
}
|
||||
|
||||
for (var index in result) {
|
||||
var item = result[index];
|
||||
ccn_event_collectionCache.push(item[0])
|
||||
renderdata.val = item[0];
|
||||
renderdata.name = item[1];
|
||||
collectionDOM.append(
|
||||
ccn_template_optionItem.render(renderdata)
|
||||
);
|
||||
}
|
||||
}
|
||||
// in add mode, set as -1, otherwise try to match original data
|
||||
// indexOf will return -1 if no matched item
|
||||
collectionDOM.val(isAdd ? '' : ccn_event_editingEvent[1]);
|
||||
|
||||
// init start and end datetime
|
||||
if (isAdd) {
|
||||
// in add mode, init 2 datetime picker as close hours based time.
|
||||
var currentDateTime = new Date();
|
||||
currentDateTime.setMilliseconds(0);
|
||||
currentDateTime.setSeconds(0);
|
||||
currentDateTime.setMinutes(0);
|
||||
ccn_datetimepicker_Set(1, currentDateTime, false);
|
||||
|
||||
// time span is 2 hours
|
||||
currentDateTime.setHours(currentDateTime.getHours() + 2);
|
||||
ccn_datetimepicker_Set(2, currentDateTime, false);
|
||||
} else {
|
||||
// in update mode, match it with original data
|
||||
var originalDateTime = new Date((ccn_event_editingEvent[5] + ccn_event_editingEvent[7]) * 60000);
|
||||
ccn_datetimepicker_Set(1, originalDateTime, true);
|
||||
|
||||
originalDateTime = new Date((ccn_event_editingEvent[6] + ccn_event_editingEvent[7]) * 60000);
|
||||
ccn_datetimepicker_Set(2, originalDateTime, true);
|
||||
}
|
||||
|
||||
// setup timezone here
|
||||
// to prevent some error
|
||||
// because following isAdd will change its meaning
|
||||
$('#ccn-event-timezone-radioKeep').prop('checked', true); // give a default value
|
||||
var nowtime = new Date();
|
||||
SmarterShowHide(
|
||||
(!isAdd) && (-nowtime.getTimezoneOffset()) != ccn_event_editingEvent[7],
|
||||
$('#ccn-event-boxTimezone')
|
||||
);
|
||||
|
||||
// ========================
|
||||
// now we need resolve loop rules and set related data
|
||||
if (!isAdd) {
|
||||
data = ccn_datetime_ResolveLoopRules4UI(ccn_event_editingEvent[8]);
|
||||
if (typeof(data) == 'undefined') isAdd = true; // init as add
|
||||
}
|
||||
|
||||
// give some value with a default value
|
||||
$('#ccn-event-loopMonth-radioA').prop('checked', true);
|
||||
$('#ccn-event-loopWeek-check' + (nowtime.getWeekday() + 1)).prop('checked', true);
|
||||
$('#ccn-event-strictMode-radioStrict').prop('checked', true);
|
||||
|
||||
// real process
|
||||
if (isAdd) {
|
||||
$('#ccn-event-radioLoopNever').prop('checked', true);
|
||||
} else {
|
||||
switch(data[0][0]) {
|
||||
case 0:
|
||||
$('#ccn-event-radioLoopYear').prop('checked', true);
|
||||
$('#ccn-event-loopYear-inputSpan').val(data[0][2]);
|
||||
if (data[0][1]) $('#ccn-event-strictMode-radioStrict').prop('checked', true);
|
||||
else $('#ccn-event-strictMode-radioRough').prop('checked', true);
|
||||
break;
|
||||
case 1:
|
||||
$('#ccn-event-radioLoopMonth').prop('checked', true);
|
||||
$('#ccn-event-loopMonth-inputSpan').val(data[0][3]);
|
||||
$('#ccn-event-loopMonth-radio' + data[0][2]).prop('checked', true);
|
||||
if (data[0][1]) $('#ccn-event-strictMode-radioStrict').prop('checked', true);
|
||||
else $('#ccn-event-strictMode-radioRough').prop('checked', true);
|
||||
break;
|
||||
case 2:
|
||||
$('#ccn-event-radioLoopWeek').prop('checked', true);
|
||||
$('#ccn-event-loopWeek-inputSpan').val(data[0][8]);
|
||||
for(var i = 1; i <= 7; i++) {
|
||||
$('#ccn-event-loopWeek-check' + i).prop('checked', data[0][i]);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
$('#ccn-event-radioLoopDay').prop('checked', true);
|
||||
$('#ccn-event-loopDay-inputSpan').val(data[0][1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// give some item a default value
|
||||
ccn_datetimepicker_Set(3, nowtime, false);
|
||||
|
||||
if (isAdd) {
|
||||
$('#ccn-event-loopStop-radioForever').prop('checked', true);
|
||||
} else {
|
||||
switch(data[1][0]) {
|
||||
case 0:
|
||||
$('#ccn-event-loopStop-radioForever').prop('checked', true);
|
||||
break;
|
||||
case 1:
|
||||
$('#ccn-event-loopStop-radioDateTime').prop('checked', true);
|
||||
var stopDatetime = new Date((data[1][1] + ccn_event_editingEvent[7]) * 60000);
|
||||
ccn_datetimepicker_Set(3, stopDatetime, true);
|
||||
break;
|
||||
case 2:
|
||||
$('#ccn-event-loopStop-radioTimes').prop('checked', true);
|
||||
$('#ccn-event-loopStop-inputTimes').val(data[1][1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// refresh some ui element according to form options
|
||||
function ccn_event_RefreshRadioDiaplay() {
|
||||
// loop method
|
||||
// note: no loop control loop stop's display
|
||||
// note: year and month loop also control strict mode display
|
||||
SmarterShowHide(!$('#ccn-event-radioLoopNever').prop('checked'), $('#ccn-event-boxLoopStop'));
|
||||
|
||||
SmarterShowHide($('#ccn-event-radioLoopDay').prop('checked'), $('#ccn-event-boxLoopDay'));
|
||||
SmarterShowHide($('#ccn-event-radioLoopWeek').prop('checked'), $('#ccn-event-boxLoopWeek'));
|
||||
SmarterShowHide($('#ccn-event-radioLoopMonth').prop('checked'), $('#ccn-event-boxLoopMonth'));
|
||||
SmarterShowHide($('#ccn-event-radioLoopYear').prop('checked'), $('#ccn-event-boxLoopYear'));
|
||||
|
||||
SmarterShowHide(
|
||||
$('#ccn-event-radioLoopMonth').prop('checked') || $('#ccn-event-radioLoopYear').prop('checked'),
|
||||
$('#ccn-event-boxStrictMode')
|
||||
);
|
||||
|
||||
// loop stop
|
||||
SmarterShowHide($('#ccn-event-loopStop-radioForever').prop('checked'), undefined);
|
||||
SmarterShowHide($('#ccn-event-loopStop-radioDateTime').prop('checked'), $('#ccn-event-boxLoopStopDateTime'));
|
||||
SmarterShowHide($('#ccn-event-loopStop-radioTimes').prop('checked'), $('#ccn-event-boxLoopStopTimes'));
|
||||
|
||||
}
|
||||
|
||||
function ccn_event_RefreshLoopMonthType() {
|
||||
var picker = ccn_datetimepicker_Get(1, false);
|
||||
var data = ccn_datetime_GetDayInMonth(picker.getFullYear(), picker.getMonth() + 1, picker.getDate());
|
||||
|
||||
$('#ccn-event-loopMonth-textA').text($.i18n.prop('ccn-i18n-event-loopWeek-optionA').format(data[0]));
|
||||
$('#ccn-event-loopMonth-textB').text($.i18n.prop('ccn-i18n-event-loopWeek-optionB').format(data[1]));
|
||||
$('#ccn-event-loopMonth-textC').text($.i18n.prop('ccn-i18n-event-loopWeek-optionC').format(data[2], data[3] + 1));
|
||||
$('#ccn-event-loopMonth-textD').text($.i18n.prop('ccn-i18n-event-loopWeek-optionD').format(data[4], data[5] + 1));
|
||||
}
|
||||
|
||||
function ccn_event_UpdateDateTimePickerButton(index) {
|
||||
switch(index) {
|
||||
case 1:
|
||||
$('#ccn-event-btnStartDateTime-text').text(
|
||||
ccn_datetimepicker_Get(1, false).toLocaleString()
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
$('#ccn-event-btnEndDateTime-text').text(
|
||||
ccn_datetimepicker_Get(2, false).toLocaleString()
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
$('#ccn-event-btnLoopStopDateTime-text').text(
|
||||
ccn_datetimepicker_Get(3, false).toLocaleDateString()
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// return undefined to indicate an error
|
||||
// or
|
||||
// [belongTo, title, description, eventDateTimeStart, eventDateTimeEnd, timezoneOffset, loopRules]
|
||||
function ccn_event_GetForm() {
|
||||
// basic
|
||||
var title = $('#ccn-event-inputTitle').val();
|
||||
if (title == '') return undefined;
|
||||
var description = $('#ccn-event-inputDescription').val();
|
||||
if (description == '') return undefined;
|
||||
var color = $('#ccn-event-inputColor').val();
|
||||
if (color == '') return undefined;
|
||||
var belongTo = $('#ccn-event-inputCollection').val();
|
||||
if (belongTo == null) return undefined; // if no selected item, val return null, not undefined
|
||||
|
||||
var isAdd = typeof(ccn_event_editingEvent) == 'undefined';
|
||||
var keepTimezone = $('#ccn-event-timezone-radioKeep').prop('checked');
|
||||
var isStrict = $('#ccn-event-strictMode-radioStrict').prop('checked');
|
||||
|
||||
// time
|
||||
var eventDateTimeStart = undefined;
|
||||
var eventDateTimeEnd = undefined;
|
||||
var timezoneOffset = undefined;
|
||||
if ((!isAdd) && (!keepTimezone)) {
|
||||
// get datetime as utc, then minus original timezone to get unix timestamp
|
||||
timezoneOffset = ccn_event_editingEvent[7]; // keep timezone
|
||||
eventDateTimeStart = Math.floor(ccn_datetimepicker_Get(1, true).getTime() / 60000) - timezoneOffset;
|
||||
eventDateTimeEnd = Math.floor(ccn_datetimepicker_Get(2, true).getTime() / 60000) - timezoneOffset;
|
||||
} else {
|
||||
// use my timezone, resolve presented data as my local time
|
||||
var cache = ccn_datetimepicker_Get(1, false);
|
||||
timezoneOffset = -cache.getTimezoneOffset();
|
||||
eventDateTimeStart = Math.floor(cache.getTime() / 60000);
|
||||
eventDateTimeEnd = Math.floor(ccn_datetimepicker_Get(2, false).getTime() / 60000);
|
||||
}
|
||||
|
||||
// loopRules
|
||||
var loopRules = undefined;
|
||||
if ($('#ccn-event-radioLoopNever').prop('checked')) {
|
||||
loopRules = "";
|
||||
} else if ($('#ccn-event-radioLoopDay').prop('checked')) {
|
||||
loopRules = "D{0}".format($('#ccn-event-loopDay-inputSpan').val());
|
||||
} else if ($('#ccn-event-radioLoopWeek').prop('checked')) {
|
||||
var cache = ""
|
||||
for(var i = 1; i < 8; i++)
|
||||
cache += $('#ccn-event-loopWeek-check' + i).prop('checked') ? 'T' : 'F';
|
||||
loopRules = 'W{0}{1}'.format(
|
||||
cache,
|
||||
$('#ccn-event-loopWeek-inputSpan').val()
|
||||
);
|
||||
} else if ($('#ccn-event-radioLoopMonth').prop('checked')) {
|
||||
var cache = undefined;
|
||||
if ($('#ccn-event-loopMonth-radioA').prop('checked')) cache='A';
|
||||
else if ($('#ccn-event-loopMonth-radioB').prop('checked')) cache='B';
|
||||
else if ($('#ccn-event-loopMonth-radioC').prop('checked')) cache='C';
|
||||
else if ($('#ccn-event-loopMonth-radioD').prop('checked')) cache='D';
|
||||
else return undefined;
|
||||
|
||||
loopRules = "M{0}{1}{2}".format(
|
||||
isStrict ? "S" : "R",
|
||||
cache,
|
||||
$('#ccn-event-loopMonth-inputSpan').val()
|
||||
);
|
||||
} else if ($('#ccn-event-radioLoopYear').prop('checked')) {
|
||||
loopRules = "Y{0}{1}".format(
|
||||
isStrict ? "S" : "R",
|
||||
$('#ccn-event-loopYear-inputSpan').val()
|
||||
);
|
||||
}
|
||||
|
||||
// no need to process stop if this is not a loop event
|
||||
if (loopRules != "") {
|
||||
loopRules += '-';
|
||||
if ($('#ccn-event-loopStop-radioForever').prop('checked')) {
|
||||
loopRules += 'F';
|
||||
} else if ($('#ccn-event-loopStop-radioDateTime').prop('checked')) {
|
||||
var timestamp = undefined;
|
||||
if ((!isAdd) && (!keepTimezone)) {
|
||||
// keep timezone
|
||||
var cache = ccn_datetimepicker_Get(3, true);
|
||||
cache.setUTCHours(23);
|
||||
cache.setUTCMinutes(59);
|
||||
timestamp = Math.floor(cache.getTime() / 60000) - timezoneOffset;
|
||||
} else {
|
||||
// use my timezone
|
||||
timestamp = Math.floor(ccn_datetimepicker_Get(3, false).getTime() / 60000);
|
||||
}
|
||||
|
||||
loopRules += 'D{0}'.format(timestamp);
|
||||
} else if ($('#ccn-event-loopStop-radioTimes').prop('checked')) {
|
||||
loopRules += 'T{0}'.format($('#ccn-event-loopStop-inputTimes').val());
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
belongTo,
|
||||
title,
|
||||
ccn_api_serializeDescription(
|
||||
description,
|
||||
color
|
||||
),
|
||||
eventDateTimeStart,
|
||||
eventDateTimeEnd,
|
||||
timezoneOffset,
|
||||
loopRules
|
||||
];
|
||||
}
|
||||
|
||||
function ccn_event_btnSpot() {
|
||||
var datetime = ccn_datetimepicker_Get(1, false);
|
||||
datetime.setMinutes(datetime.getMinutes() + 1);
|
||||
ccn_datetimepicker_Set(2, datetime, false);
|
||||
}
|
||||
|
||||
function ccn_event_btnFullDay() {
|
||||
var datetime = ccn_datetimepicker_Get(1, false);
|
||||
datetime.setMinutes(0);
|
||||
datetime.setHours(0);
|
||||
ccn_datetimepicker_Set(1, datetime, false);
|
||||
datetime.setMinutes(59);
|
||||
datetime.setHours(23);
|
||||
ccn_datetimepicker_Set(2, datetime, false);
|
||||
}
|
||||
|
||||
function ccn_event_btnDateTimePicker() {
|
||||
switch(parseInt($(this).attr('datetimepicker'))) {
|
||||
case 1:
|
||||
ccn_datetimepicker_Modal(ccn_datetimepicker_tabType.minute, 1, false);
|
||||
break;
|
||||
case 2:
|
||||
ccn_datetimepicker_Modal(ccn_datetimepicker_tabType.minute, 2, false);
|
||||
break;
|
||||
case 3:
|
||||
ccn_datetimepicker_Modal(ccn_datetimepicker_tabType.day, 3, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_event_btnCancel() {
|
||||
window.location.href = '/web/calendar';
|
||||
}
|
||||
|
||||
function ccn_event_btnSubmit() {
|
||||
var submitData = ccn_event_GetForm();
|
||||
if (typeof(submitData) == 'undefined') {
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-form"));
|
||||
return;
|
||||
}
|
||||
|
||||
var isAdd = typeof(ccn_event_editingEvent) == 'undefined';
|
||||
if (isAdd) {
|
||||
var result = ccn_api_calendar_add(
|
||||
submitData[0],
|
||||
submitData[1],
|
||||
submitData[2],
|
||||
submitData[3],
|
||||
submitData[4],
|
||||
submitData[6],
|
||||
submitData[5]
|
||||
);
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-add"));
|
||||
else window.location.href = '/web/calendar';
|
||||
} else {
|
||||
var result = ccn_api_calendar_update(
|
||||
ccn_event_editingEvent[0],
|
||||
ccn_event_editingEvent[1] == submitData[0] ? undefined : submitData[0],
|
||||
ccn_event_editingEvent[2] == submitData[1] ? undefined : submitData[1],
|
||||
ccn_event_editingEvent[3] == submitData[2] ? undefined : submitData[2],
|
||||
ccn_event_editingEvent[5] == submitData[3] ? undefined : submitData[3],
|
||||
ccn_event_editingEvent[6] == submitData[4] ? undefined : submitData[4],
|
||||
ccn_event_editingEvent[8] == submitData[6] ? undefined : submitData[6],
|
||||
ccn_event_editingEvent[7] == submitData[5] ? undefined : submitData[5],
|
||||
ccn_event_editingEvent[4]
|
||||
);
|
||||
if (typeof(result) == 'undefined') ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-update"));
|
||||
else window.location.href = '/web/calendar';
|
||||
}
|
||||
}
|
||||
|
||||
19
frontend-legacy/static/js/page/home.js
Normal file
19
frontend-legacy/static/js/page/home.js
Normal file
@@ -0,0 +1,19 @@
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.home;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// apply i18n
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
});
|
||||
58
frontend-legacy/static/js/page/login.js
Normal file
58
frontend-legacy/static/js/page/login.js
Normal file
@@ -0,0 +1,58 @@
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.login;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// apply i18n
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
|
||||
// bind login event
|
||||
$("#ccn-login-form-login").click(ccn_login_startLogin);
|
||||
});
|
||||
|
||||
function ccn_login_startLogin() {
|
||||
// disable all ui first
|
||||
$("#ccn-login-form-login").attr("disabled",true);
|
||||
$("#ccn-login-form-username").attr("disabled",true);
|
||||
$("#ccn-login-form-password").attr("disabled",true);
|
||||
|
||||
// get form data
|
||||
username = $("#ccn-login-form-username").val();
|
||||
password = $("#ccn-login-form-password").val();
|
||||
|
||||
/*
|
||||
// try get salt
|
||||
if (ccn_api_common_salt(username)) {
|
||||
// continue login
|
||||
if (ccn_api_common_login(username, password)) {
|
||||
// ok, logged
|
||||
// jump into home page again
|
||||
window.location.href = '/web/home';
|
||||
|
||||
} else ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-login"));
|
||||
} else ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-login"));
|
||||
*/
|
||||
if (ccn_api_common_webLogin(username, password)) {
|
||||
// ok, logged
|
||||
// jump into home page again
|
||||
window.location.href = '/web/home';
|
||||
return;
|
||||
|
||||
} else ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-login"));
|
||||
|
||||
// retore ui
|
||||
$("#ccn-login-form-login").removeAttr("disabled");
|
||||
$("#ccn-login-form-username").removeAttr("disabled");
|
||||
$("#ccn-login-form-password").removeAttr("disabled");
|
||||
}
|
||||
190
frontend-legacy/static/js/page/todo.js
Normal file
190
frontend-legacy/static/js/page/todo.js
Normal file
@@ -0,0 +1,190 @@
|
||||
var ccn_todo_todoListCache = [];
|
||||
|
||||
$(document).ready(function() {
|
||||
ccn_pages_currentPage = ccn_pages_enumPages.todo;
|
||||
|
||||
// template process
|
||||
ccn_template_Load();
|
||||
|
||||
// nav process
|
||||
ccn_headerNav_Insert();
|
||||
ccn_headerNav_BindEvents();
|
||||
ccn_headerNav_LoggedRefresh();
|
||||
|
||||
// messagebox process
|
||||
ccn_messagebox_Insert();
|
||||
ccn_messagebox_BindEvent();
|
||||
|
||||
// apply i18n
|
||||
ccn_i18n_LoadLanguage();
|
||||
ccn_i18n_ApplyLanguage();
|
||||
|
||||
// refresh once
|
||||
ccn_todo_Refresh();
|
||||
|
||||
// bind event
|
||||
$("#ccn-todo-btnAdd").click(ccn_todo_Add);
|
||||
$("#ccn-todo-btnRefresh").click(ccn_todo_Refresh);
|
||||
});
|
||||
|
||||
function ccn_todo_RefreshCacheList() {
|
||||
// clean list cache first
|
||||
ccn_todo_todoListCache = new Array();
|
||||
|
||||
var result = ccn_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 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 = LineBreaker2Br(item[2]);
|
||||
|
||||
// render
|
||||
listDOM.append(ccn_template_todoItem.render(renderdata));
|
||||
|
||||
// set mode
|
||||
var uuid = renderdata.uuid;
|
||||
ccn_todo_ChangeDisplayMode(uuid, false);
|
||||
|
||||
// bind event
|
||||
$("#ccn-todoItem-btnEdit-" + uuid).click(ccn_todo_ItemEdit);
|
||||
$("#ccn-todoItem-btnDelete-" + uuid).click(ccn_todo_ItemDelete);
|
||||
$("#ccn-todoItem-btnUpdate-" + uuid).click(ccn_todo_ItemUpdate);
|
||||
$("#ccn-todoItem-btnCancelUpdate-" + uuid).click(ccn_todo_ItemCancelUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_todo_ChangeDisplayMode(uuid, isEdit) {
|
||||
if(isEdit) {
|
||||
// 4 buttons
|
||||
$("#ccn-todoItem-btnEdit-" + uuid).hide();
|
||||
$("#ccn-todoItem-btnDelete-" + uuid).hide();
|
||||
$("#ccn-todoItem-btnUpdate-" + uuid).show();
|
||||
$("#ccn-todoItem-btnCancelUpdate-" + uuid).show();
|
||||
|
||||
// 2 elements
|
||||
$("#ccn-todoItem-p-" + uuid).hide();
|
||||
$("#ccn-todoItem-textarea-" + uuid).show();
|
||||
} else {
|
||||
$("#ccn-todoItem-btnEdit-" + uuid).show();
|
||||
$("#ccn-todoItem-btnDelete-" + uuid).show();
|
||||
$("#ccn-todoItem-btnUpdate-" + uuid).hide();
|
||||
$("#ccn-todoItem-btnCancelUpdate-" + uuid).hide();
|
||||
|
||||
$("#ccn-todoItem-p-" + uuid).show();
|
||||
$("#ccn-todoItem-textarea-" + uuid).hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ccn_todo_Refresh() {
|
||||
// refresh and render once
|
||||
ccn_todo_RefreshCacheList();
|
||||
ccn_todo_RenderCacheList();
|
||||
}
|
||||
|
||||
function ccn_todo_Add() {
|
||||
var result = ccn_api_todo_add();
|
||||
if (typeof(result) == 'undefined') {
|
||||
// fail
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-add"));
|
||||
} else {
|
||||
// add into cache
|
||||
ccn_todo_todoListCache[result[0]] = result;
|
||||
|
||||
// render
|
||||
var listDOM = $("#ccn-todo-todoList");
|
||||
listDOM.append(ccn_template_todoItem.render({
|
||||
uuid: result[0],
|
||||
data: LineBreaker2Br(result[2])
|
||||
}));
|
||||
|
||||
// set mode
|
||||
var uuid = result[0];
|
||||
ccn_todo_ChangeDisplayMode(uuid, false);
|
||||
|
||||
// bind event
|
||||
$("#ccn-todoItem-btnEdit-" + uuid).click(ccn_todo_ItemEdit);
|
||||
$("#ccn-todoItem-btnDelete-" + uuid).click(ccn_todo_ItemDelete);
|
||||
$("#ccn-todoItem-btnUpdate-" + uuid).click(ccn_todo_ItemUpdate);
|
||||
$("#ccn-todoItem-btnCancelUpdate-" + uuid).click(ccn_todo_ItemCancelUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_todo_ItemEdit() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
// copy current data to textarea
|
||||
$("#ccn-todoItem-textarea-" + uuid).val(
|
||||
ccn_todo_todoListCache[uuid][2]
|
||||
);
|
||||
|
||||
// switch to edit mode
|
||||
ccn_todo_ChangeDisplayMode(uuid, true);
|
||||
}
|
||||
|
||||
function ccn_todo_ItemDelete() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
var result = ccn_api_todo_delete(
|
||||
uuid,
|
||||
ccn_todo_todoListCache[uuid][3]
|
||||
);
|
||||
|
||||
if(!result) {
|
||||
// fail
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-delete"));
|
||||
} else {
|
||||
// remove body
|
||||
$("#ccn-todoItem-" + uuid).remove();
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_todo_ItemUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
|
||||
var newData = $("#ccn-todoItem-textarea-" + uuid).val();
|
||||
var result = ccn_api_todo_update(
|
||||
uuid,
|
||||
newData,
|
||||
ccn_todo_todoListCache[uuid][3]
|
||||
);
|
||||
|
||||
if (typeof(result) == 'undefined') {
|
||||
// fail
|
||||
ccn_messagebox_Show($.i18n.prop("ccn-i18n-js-fail-update"));
|
||||
} else {
|
||||
// safely update data & lastChanged and control
|
||||
ccn_todo_todoListCache[uuid][2] = newData;
|
||||
ccn_todo_todoListCache[uuid][3] = result;
|
||||
$("#ccn-todoItem-p-" + uuid).html(LineBreaker2Br(newData));
|
||||
|
||||
// switch to normal mode
|
||||
ccn_todo_ChangeDisplayMode(uuid, false);
|
||||
}
|
||||
}
|
||||
|
||||
function ccn_todo_ItemCancelUpdate() {
|
||||
var uuid = $(this).attr("uuid");
|
||||
// clean data
|
||||
$("#ccn-todoItem-textarea-" + uuid).val("");
|
||||
// switch to normal mode
|
||||
ccn_todo_ChangeDisplayMode(uuid, false);
|
||||
}
|
||||
10
frontend-legacy/static/js/tabcontrol.js
Normal file
10
frontend-legacy/static/js/tabcontrol.js
Normal 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();
|
||||
}
|
||||
50
frontend-legacy/static/js/template.js
Normal file
50
frontend-legacy/static/js/template.js
Normal file
@@ -0,0 +1,50 @@
|
||||
var ccn_template_headerNav = undefined;
|
||||
var ccn_template_messagebox = undefined;
|
||||
var ccn_template_datetimepicker = undefined;
|
||||
var ccn_template_calendarItem = undefined;
|
||||
var ccn_template_scheduleItem = undefined;
|
||||
var ccn_template_ownedItem = undefined;
|
||||
var ccn_template_sharingItem = undefined;
|
||||
var ccn_template_displayOwnedItem = undefined;
|
||||
var ccn_template_displaySharedItem = undefined;
|
||||
var ccn_template_userItem = undefined;
|
||||
var ccn_template_todoItem = undefined;
|
||||
var ccn_template_optionItem = undefined;
|
||||
var ccn_template_tokenItem = undefined;
|
||||
|
||||
function ccn_template_Load() {
|
||||
ccn_template_headerNav = ccn_template_TemplateLoader('headerNav');
|
||||
ccn_template_messagebox = ccn_template_TemplateLoader('messagebox');
|
||||
ccn_template_datetimepicker = ccn_template_TemplateLoader('datetimepicker');
|
||||
|
||||
ccn_template_calendarItem = ccn_template_TemplateLoader('calendarItem');
|
||||
ccn_template_scheduleItem = ccn_template_TemplateLoader('scheduleItem');
|
||||
ccn_template_displayOwnedItem = ccn_template_TemplateLoader('displayOwnedItem');
|
||||
ccn_template_displaySharedItem = ccn_template_TemplateLoader('displaySharedItem');
|
||||
|
||||
ccn_template_todoItem = ccn_template_TemplateLoader('todoItem');
|
||||
ccn_template_userItem = ccn_template_TemplateLoader('userItem');
|
||||
ccn_template_tokenItem = ccn_template_TemplateLoader('tokenItem');
|
||||
|
||||
ccn_template_ownedItem = ccn_template_TemplateLoader('ownedItem');
|
||||
ccn_template_sharingItem = ccn_template_TemplateLoader('sharingItem');
|
||||
ccn_template_optionItem = ccn_template_TemplateLoader('optionItem');
|
||||
|
||||
}
|
||||
|
||||
function ccn_template_TemplateLoader(templateName) {
|
||||
var elements = $("#jsrender-tmpl-" + templateName);
|
||||
if (elements.length == 0) return undefined;
|
||||
var cache = undefined;
|
||||
|
||||
$.ajax({
|
||||
url: elements.attr('src'),
|
||||
type: "GET",
|
||||
async: false,
|
||||
success: function (data) {
|
||||
cache = $.templates(data);
|
||||
}
|
||||
});
|
||||
|
||||
return cache;
|
||||
}
|
||||
70
frontend-legacy/static/js/utils.js
Normal file
70
frontend-legacy/static/js/utils.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
function ComputPasswordWithSalt(password, salt) {
|
||||
return ComputeSHA256(ComputeSHA256(password) + salt.toString());
|
||||
}
|
||||
|
||||
function ComputeSHA256(strl) {
|
||||
var tempstr = new TextEncoder().encode(strl);
|
||||
var hashedStrl = undefined
|
||||
var shitpromise = crypto.subtle.digest('SHA-256', tempstr);
|
||||
Promise.all(shitpromise).then(function(result) {
|
||||
hashedStrl = result;
|
||||
});
|
||||
var hashArray = Array.from(new Uint8Array(hashedStrl));
|
||||
var hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
|
||||
return hashHex.toLowerCase();
|
||||
}
|
||||
*/
|
||||
var DefaultColor = '#536dfe';
|
||||
|
||||
function IsResponseOK(data) {
|
||||
if (typeof (data) == 'undefined') {
|
||||
console.log("Fail to execute an api!");
|
||||
return false;
|
||||
}
|
||||
if (!data['success']) {
|
||||
console.log("Fail to execute an api! Reason:");
|
||||
console.log(data['error']);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function LineBreaker2Br(strl) {
|
||||
return $('<div>').text(strl).html().replace(/\n/g, '<br />');
|
||||
}
|
||||
|
||||
function IsUndefinedOrEmpty(data) {
|
||||
return (typeof (data) == 'undefined' || data == "");
|
||||
}
|
||||
|
||||
function SmarterShowHide(boolean, element) {
|
||||
if (typeof (element) == 'undefined') return;
|
||||
if (boolean) element.show();
|
||||
else element.hide();
|
||||
}
|
||||
|
||||
function GCD(a, b) {
|
||||
if (b == 0) return a;
|
||||
return GCD(b, a % b);
|
||||
}
|
||||
|
||||
function LCM(a, b) {
|
||||
return a / GCD(a, b) * b;
|
||||
}
|
||||
|
||||
String.prototype.format = function() {
|
||||
var e = arguments;
|
||||
return !!this && this.replace(
|
||||
/\{(\d+)\}/g,
|
||||
function (t, n) {
|
||||
return e[n].toString() ? e[n].toString() : t;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Date.prototype.getWeekday = function() {
|
||||
var temp = this.getDay();
|
||||
if (temp == 0) return 6;
|
||||
else return temp - 1;
|
||||
};
|
||||
16
frontend-legacy/static/tmpl/calendarItem.tmpl
Normal file
16
frontend-legacy/static/tmpl/calendarItem.tmpl
Normal file
@@ -0,0 +1,16 @@
|
||||
{{for start=0 end=6 step=1 itemVar="~row"}}
|
||||
<div>
|
||||
{{for start=0 end=7 step=1 itemVar="~column"}}
|
||||
<div id="ccn-calendarItem-{{:~row}}-{{:~column}}">
|
||||
<p><b id="ccn-calendarItem-title-{{:~row}}-{{:~column}}"> </b>
|
||||
<span id="ccn-calendarItem-desc-{{:~row}}-{{:~column}}"></span>
|
||||
</p>
|
||||
<div id="ccn-calendarItem-eventBox1-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
|
||||
<div id="ccn-calendarItem-eventBox2-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
|
||||
<div id="ccn-calendarItem-eventBox3-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
|
||||
<div id="ccn-calendarItem-eventBox4-{{:~row}}-{{:~column}}" class="calendarItem-eventBox" enableDisplay="false"></div>
|
||||
<p id="ccn-calendarItem-task-{{:~row}}-{{:~column}}"> </p>
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
{{/for}}
|
||||
200
frontend-legacy/static/tmpl/datetimepicker.tmpl
Normal file
200
frontend-legacy/static/tmpl/datetimepicker.tmpl
Normal file
@@ -0,0 +1,200 @@
|
||||
<div id="ccn-datetimepicker-modal" class="modal" style="float: left; position: fixed; top: 0; bottom: 0; left: 0; right: 0;">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card" style="height: 70%;">
|
||||
<header class="modal-card-head pickerHeader">
|
||||
<div type="year"><small i18n-name="ccn-i18n-universal-text-year"></small><span id="ccn-datetimepicker-datetime-year"> </span></div>
|
||||
<div type="month"><small i18n-name="ccn-i18n-universal-text-month"></small><span id="ccn-datetimepicker-datetime-month"> </span></div>
|
||||
<div type="day"><small i18n-name="ccn-i18n-universal-text-day"></small><span id="ccn-datetimepicker-datetime-day"> </span></div>
|
||||
<div type="hour"><small i18n-name="ccn-i18n-universal-text-hour"></small><span id="ccn-datetimepicker-datetime-hour"> </span></div>
|
||||
<div type="minute"><small i18n-name="ccn-i18n-universal-text-minute"></small><span id="ccn-datetimepicker-datetime-minute"> </span></div>
|
||||
</header>
|
||||
<div class="modal-card-body pickerContainer">
|
||||
<div id="ccn-datetimepicker-panelYear">
|
||||
<nav class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div class="level-item control">
|
||||
<a id="ccn-datetimepiacker-panelYear-prevBtn" class="button">
|
||||
<span class="icon is-small"><i class="fas fa-chevron-circle-left"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ccn-datetimepiacker-panelYear-title" class="level-item"></div>
|
||||
<div class="level-right">
|
||||
<div class="level-item control">
|
||||
<a id="ccn-datetimepiacker-panelYear-nextBtn" class="button">
|
||||
<span class="icon is-small"><i class="fas fa-chevron-circle-right"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="ccn-datetimepiacker-panelYear-table" class="perfectTable">
|
||||
<div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ccn-datetimepicker-panelMonth">
|
||||
<nav class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div class="level-item control">
|
||||
<a id="ccn-datetimepiacker-panelMonth-prevBtn" class="button">
|
||||
<span class="icon is-small"><i class="fas fa-chevron-circle-left"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ccn-datetimepiacker-panelMonth-title" class="level-item"></div>
|
||||
<div class="level-right">
|
||||
<div class="level-item control">
|
||||
<a id="ccn-datetimepiacker-panelMonth-nextBtn" class="button">
|
||||
<span class="icon is-small"><i class="fas fa-chevron-circle-right"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="ccn-datetimepiacker-panelMonth-table" class="perfectTable">
|
||||
<div>
|
||||
<div i18n-name="ccn-i18n-universal-month-1"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-2"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-3"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-4"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div i18n-name="ccn-i18n-universal-month-5"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-6"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-7"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-8"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div i18n-name="ccn-i18n-universal-month-9"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-10"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-11"></div>
|
||||
<div i18n-name="ccn-i18n-universal-month-12"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ccn-datetimepicker-panelDay">
|
||||
<nav class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div class="level-item control">
|
||||
<a id="ccn-datetimepiacker-panelDay-prevBtn" class="button">
|
||||
<span class="icon is-small"><i class="fas fa-chevron-circle-left"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ccn-datetimepiacker-panelDay-title" class="level-item"></div>
|
||||
<div class="level-right">
|
||||
<div class="level-item control">
|
||||
<a id="ccn-datetimepiacker-panelDay-nextBtn" class="button">
|
||||
<span class="icon is-small"><i class="fas fa-chevron-circle-right"></i></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="ccn-datetimepiacker-panelDay-table" class="perfectTable">
|
||||
<div>
|
||||
<div i18n-name="ccn-i18n-universal-week-1"></div>
|
||||
<div i18n-name="ccn-i18n-universal-week-2"></div>
|
||||
<div i18n-name="ccn-i18n-universal-week-3"></div>
|
||||
<div i18n-name="ccn-i18n-universal-week-4"></div>
|
||||
<div i18n-name="ccn-i18n-universal-week-5"></div>
|
||||
<div i18n-name="ccn-i18n-universal-week-6"></div>
|
||||
<div i18n-name="ccn-i18n-universal-week-7"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
|
||||
</div>
|
||||
<div>
|
||||
<div></div><div></div><div></div><div></div><div></div><div></div><div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg id="ccn-datetimepicker-panelHour" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid" viewBox="0 0 200 200">
|
||||
<circle cx="100.000000" cy="100.000000" r="100.000000" type="background"></circle>
|
||||
<line x1="100" y1="100" x2="100.000000" y2="20.000000"></line>
|
||||
<circle cx="100.000000" cy="20.000000" r="1em" type="symbol"></circle>
|
||||
|
||||
<text x="100.000000" y="20.000000">0</text>
|
||||
<text x="140.000000" y="30.717968">1</text>
|
||||
<text x="169.282032" y="60.000000">2</text>
|
||||
<text x="180.000000" y="100.000000">3</text>
|
||||
<text x="169.282032" y="140.000000">4</text>
|
||||
<text x="140.000000" y="169.282032">5</text>
|
||||
<text x="100.000000" y="180.000000">6</text>
|
||||
<text x="60.000000" y="169.282032">7</text>
|
||||
<text x="30.717968" y="140.000000">8</text>
|
||||
<text x="20.000000" y="100.000000">9</text>
|
||||
<text x="30.717968" y="60.000000">10</text>
|
||||
<text x="60.000000" y="30.717968">11</text>
|
||||
<text x="100.000000" y="40.000000">12</text>
|
||||
<text x="130.000000" y="48.038476">13</text>
|
||||
<text x="151.961524" y="70.000000">14</text>
|
||||
<text x="160.000000" y="100.000000">15</text>
|
||||
<text x="151.961524" y="130.000000">16</text>
|
||||
<text x="130.000000" y="151.961524">17</text>
|
||||
<text x="100.000000" y="160.000000">18</text>
|
||||
<text x="70.000000" y="151.961524">19</text>
|
||||
<text x="48.038476" y="130.000000">20</text>
|
||||
<text x="40.000000" y="100.000000">21</text>
|
||||
<text x="48.038476" y="70.000000">22</text>
|
||||
<text x="70.000000" y="48.038476">23</text>
|
||||
</svg>
|
||||
<svg id="ccn-datetimepicker-panelMinute" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid" viewBox="0 0 200 200">
|
||||
<circle cx="100.000000" cy="100.000000" r="100.000000" type="background"></circle>
|
||||
<line x1="100" y1="100" x2="100.000000" y2="20.000000"></line>
|
||||
<circle cx="100.000000" cy="20.000000" r="1em" type="symbol"></circle>
|
||||
|
||||
<text x="100.000000" y="20.000000">0</text>
|
||||
<text x="140.000000" y="30.717968">5</text>
|
||||
<text x="169.282032" y="60.000000">10</text>
|
||||
<text x="180.000000" y="100.000000">15</text>
|
||||
<text x="169.282032" y="140.000000">20</text>
|
||||
<text x="140.000000" y="169.282032">25</text>
|
||||
<text x="100.000000" y="180.000000">30</text>
|
||||
<text x="60.000000" y="169.282032">35</text>
|
||||
<text x="30.717968" y="140.000000">40</text>
|
||||
<text x="20.000000" y="100.000000">45</text>
|
||||
<text x="30.717968" y="60.000000">50</text>
|
||||
<text x="60.000000" y="30.717968">55</text>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<footer class="modal-card-foot">
|
||||
<a id="ccn-datetimepicker-btnConfirm" class="button is-success">
|
||||
<span i18n-name="ccn-i18n-datetimepicker-confirm"></span>
|
||||
</a>
|
||||
<a id="ccn-datetimepicker-btnCancel" class="button">
|
||||
<span i18n-name="ccn-i18n-datetimepicker-cancel"></span>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
12
frontend-legacy/static/tmpl/displayOwnedItem.tmpl
Normal file
12
frontend-legacy/static/tmpl/displayOwnedItem.tmpl
Normal file
@@ -0,0 +1,12 @@
|
||||
<div id="ccn-displayOwnedItem-{{:uuid}}" class="collection-item card">
|
||||
<div class="collection-item-words">
|
||||
<p>{{>name}}</p>
|
||||
</div>
|
||||
|
||||
<div id="ccn-displayOwnedItem-btnHide-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-eye"></i></span></a>
|
||||
</div>
|
||||
<div id="ccn-displayOwnedItem-btnShow-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-eye-slash"></i></span></a>
|
||||
</div>
|
||||
</div>
|
||||
16
frontend-legacy/static/tmpl/displaySharedItem.tmpl
Normal file
16
frontend-legacy/static/tmpl/displaySharedItem.tmpl
Normal file
@@ -0,0 +1,16 @@
|
||||
<div id="ccn-displaySharedItem-{{:uuid}}" class="collection-item card">
|
||||
<div class="collection-item-words">
|
||||
<b>{{>name}}</b>
|
||||
<p>
|
||||
<span i18n-name="ccn-i18n-sharedItem-sharedBy"></span>
|
||||
<span>{{>username}}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="ccn-displaySharedItem-btnHide-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-eye"></i></span></a>
|
||||
</div>
|
||||
<div id="ccn-displaySharedItem-btnShow-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-eye-slash"></i></span></a>
|
||||
</div>
|
||||
</div>
|
||||
42
frontend-legacy/static/tmpl/headerNav.tmpl
Normal file
42
frontend-legacy/static/tmpl/headerNav.tmpl
Normal file
@@ -0,0 +1,42 @@
|
||||
<nav class="navbar has-shadow is-spaced bd-navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="home">
|
||||
<img src="/static/image/icon.png"><b style="margin:0 0 0 14px;">coconut-leaf</b>
|
||||
</a>
|
||||
|
||||
<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false"
|
||||
data-target="navbarBasicExample">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="navbarBasicExample" class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
<a i18n-name="ccn-i18n-header-nav-home" id="ccn-header-nav-home" class="navbar-item" href="/web/home"></a>
|
||||
<a i18n-name="ccn-i18n-header-nav-collection" id="ccn-header-nav-collection" class="navbar-item" href="/web/collection"></a>
|
||||
<a i18n-name="ccn-i18n-header-nav-calendar" id="ccn-header-nav-calendar" class="navbar-item" href="/web/calendar"></a>
|
||||
<a i18n-name="ccn-i18n-header-nav-todo" id="ccn-header-nav-todo" class="navbar-item" href="/web/todo"></a>
|
||||
<a i18n-name="ccn-i18n-header-nav-admin" id="ccn-header-nav-admin" class="navbar-item" href="/web/admin"></a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-end">
|
||||
<p id="ccn-header-user-login" class="navbar-item">
|
||||
<a class="button is-primary" i18n-name="ccn-i18n-header-user-login" href="/web/login"></a>
|
||||
</p>
|
||||
<p id="ccn-header-user-logout" class="navbar-item">
|
||||
<a class="button is-primary" i18n-name="ccn-i18n-header-user-logout"></a>
|
||||
</p>
|
||||
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="navbar-link" i18n-name="ccn-i18n-header-language"></a>
|
||||
|
||||
<div id="ccn-header-language" class="navbar-dropdown">
|
||||
<a language="en-US" class="navbar-item">English</a>
|
||||
<a language="zh-CN" class="navbar-item">简体中文</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
15
frontend-legacy/static/tmpl/messagebox.tmpl
Normal file
15
frontend-legacy/static/tmpl/messagebox.tmpl
Normal file
@@ -0,0 +1,15 @@
|
||||
<div id="ccn-messagebox-modal" class="modal" style="float: left; position: fixed; top: 0; bottom: 0; left: 0; right: 0;">
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p id="ccn-messagebox-title" class="modal-card-title" i18n-name="ccn-i18n-messagebox-title"></p>
|
||||
<button id="ccn-messagebox-btnClose" class="delete" aria-label="close"></button>
|
||||
</header>
|
||||
<div class="modal-card-body">
|
||||
<p id="ccn-messagebox-body"></p>
|
||||
</div>
|
||||
<footer class="modal-card-foot">
|
||||
<button id="ccn-messagebox-btnConfirm" class="button is-success" i18n-name="ccn-i18n-messagebox-confirm"></button>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
1
frontend-legacy/static/tmpl/optionItem.tmpl
Normal file
1
frontend-legacy/static/tmpl/optionItem.tmpl
Normal file
@@ -0,0 +1 @@
|
||||
<option value="{{:val}}">{{>name}}</option>
|
||||
24
frontend-legacy/static/tmpl/ownedItem.tmpl
Normal file
24
frontend-legacy/static/tmpl/ownedItem.tmpl
Normal file
@@ -0,0 +1,24 @@
|
||||
<div id="ccn-ownedItem-{{:uuid}}" class="collection-item card">
|
||||
<div class="collection-item-words">
|
||||
<p id="ccn-ownedItem-textName-{{:uuid}}">{{>name}}</p>
|
||||
<div id="ccn-ownedItem-boxName-{{:uuid}}" class="control">
|
||||
<input id="ccn-ownedItem-inputName-{{:uuid}}" class="input" type="text"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ccn-ownedItem-btnEdit-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></a>
|
||||
</div>
|
||||
<div id="ccn-ownedItem-btnShare-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-share"></i></a>
|
||||
</div>
|
||||
<div id="ccn-ownedItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
<div id="ccn-ownedItem-btnUpdate-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<button class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></button>
|
||||
</div>
|
||||
<div id="ccn-ownedItem-btnCancelUpdate-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<button class="button"><span class="icon is-small"><i class="fas fa-times"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
36
frontend-legacy/static/tmpl/scheduleItem.tmpl
Normal file
36
frontend-legacy/static/tmpl/scheduleItem.tmpl
Normal file
@@ -0,0 +1,36 @@
|
||||
{{for renderdata}}
|
||||
<div class="schedule-day container">
|
||||
<div class="schedule-day-words">
|
||||
<b i18n-name="ccn-i18n-universal-month-{{:month}}"></b>
|
||||
<b>{{>day}}</b>
|
||||
<b i18n-name="ccn-i18n-universal-week-{{:dayOfWeek}}"></b>
|
||||
</div>
|
||||
<div class="schedule-event-list">
|
||||
{{for events}}
|
||||
{{if isVisible}}
|
||||
<div class="schedule-event-outter card" uuid="{{:uuid}}">
|
||||
<div class="schedule-event-color" style="background: {{:color}};"></div>
|
||||
<div class="schedule-event-inner">
|
||||
<div class="schedule-event-words">
|
||||
<p class="level-item"><b>{{>title}}</b></p>
|
||||
<p class="level-item">{{>description}}</p>
|
||||
<p class="level-item"><span>{{>start}}</span>-<span>{{>end}}</span></p>
|
||||
{{if loopText != ""}}
|
||||
<p><span class="icon is-small"><i class="fas fa-retweet"></i></span><span>{{>loopText}}</span></p>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="schedule-event-icon">
|
||||
{{if isLocked}}
|
||||
<span class="icon is-small"><i class="fas fa-lock"></i></span>
|
||||
{{/if}}
|
||||
{{if timezoneWarning}}
|
||||
<span class="icon is-small"><i class="fas fa-globe"></i></span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
9
frontend-legacy/static/tmpl/sharingItem.tmpl
Normal file
9
frontend-legacy/static/tmpl/sharingItem.tmpl
Normal file
@@ -0,0 +1,9 @@
|
||||
<div id="ccn-sharingItem-{{:uuid}}" class="collection-item card">
|
||||
<div class="collection-item-words">
|
||||
<p>{{>username}}</p>
|
||||
</div>
|
||||
|
||||
<div id="ccn-sharingItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="collection-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-trash"></i></span></a>
|
||||
</div>
|
||||
</div>
|
||||
20
frontend-legacy/static/tmpl/todoItem.tmpl
Normal file
20
frontend-legacy/static/tmpl/todoItem.tmpl
Normal file
@@ -0,0 +1,20 @@
|
||||
<div id="ccn-todoItem-{{:uuid}}" class="todo-item card">
|
||||
<div class="todo-item-words">
|
||||
<p id="ccn-todoItem-p-{{:uuid}}">{{:data}}</p>
|
||||
<textarea id="ccn-todoItem-textarea-{{:uuid}}" class="textarea"></textarea>
|
||||
</div>
|
||||
|
||||
<div id="ccn-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 id="ccn-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 id="ccn-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 id="ccn-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>
|
||||
27
frontend-legacy/static/tmpl/tokenItem.tmpl
Normal file
27
frontend-legacy/static/tmpl/tokenItem.tmpl
Normal file
@@ -0,0 +1,27 @@
|
||||
<div id="ccn-tokenItem-{{:uuid}}" class="token-item card">
|
||||
<div class="token-item-words">
|
||||
<b>{{>uuid}}</b>
|
||||
<p>
|
||||
<span i18n-name="ccn-i18n-tokenItem-ua"></span>
|
||||
<span>{{>ua}}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span i18n-name="ccn-i18n-tokenItem-ip"></span>
|
||||
<span>{{>ip}}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span i18n-name="ccn-i18n-tokenItem-expireOn"></span>
|
||||
<span>{{>expireOn}}</span>
|
||||
</p>
|
||||
{{if isMe}}
|
||||
<p>
|
||||
<span class="icon is-small"><i class="fas fa-exclamation-triangle"></i></span>
|
||||
<span i18n-name="ccn-i18n-tokenItem-isMe"></span>
|
||||
</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div id="ccn-tokenItem-btnLogout-{{:uuid}}" uuid="{{:uuid}}" class="token-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-sign-out-alt"></i></span></a>
|
||||
</div>
|
||||
</div>
|
||||
35
frontend-legacy/static/tmpl/userItem.tmpl
Normal file
35
frontend-legacy/static/tmpl/userItem.tmpl
Normal file
@@ -0,0 +1,35 @@
|
||||
<div id="ccn-userItem-{{:uuid}}" class="user-item card">
|
||||
<div class="user-item-words">
|
||||
<div class="control" style="display: flex; flex-flow: row; align-items: center;">
|
||||
<div id="ccn-userItem-iconIsAdmin-{{:uuid}}" class="icon is-small" style="margin-right: 1rem;">
|
||||
<i class="fas fa-wrench"></i>
|
||||
</div>
|
||||
<div id="ccn-userItem-textName-{{:uuid}}">{{>username}}</div>
|
||||
</div>
|
||||
<div id="ccn-userItem-boxPassword-{{:uuid}}" class="field">
|
||||
<label class="label" i18n-name="ccn-i18n-userItem-newPassword"></label>
|
||||
<div class="control">
|
||||
<input id="ccn-userItem-inputPassword-{{:uuid}}" class="input" type="password"></input>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ccn-userItem-boxIsAdmin-{{:uuid}}" class="field">
|
||||
<label class="checkbox">
|
||||
<input id="ccn-userItem-inputIsAdmin-{{:uuid}}" type="checkbox"><span i18n-name="ccn-i18n-userItem-isAdmin"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ccn-userItem-btnEdit-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-pen"></i></span></a>
|
||||
</div>
|
||||
<div id="ccn-userItem-btnDelete-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-trash"></i></span></a>
|
||||
</div>
|
||||
|
||||
<div id="ccn-userItem-btnUpdate-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-check"></i></span></a>
|
||||
</div>
|
||||
<div id="ccn-userItem-btnCancelUpdate-{{:uuid}}" uuid="{{:uuid}}" class="user-item-icon control">
|
||||
<a class="button"><span class="icon is-small"><i class="fas fa-times"></i></span></a>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user