Commit 6e25089e authored by Roisin Pearson's avatar Roisin Pearson Committed by Cecilia Vela Gurovic

Bug #1742347 Editing overall style of timeline

Change-Id: Ia33e77d4892b6599c6533f165c18a244f8fad849
Signed-off-by: default avatarRoisin Pearson <roisinpearson@catalyst.net.nz>
parent 3e5c72e8
......@@ -11,3 +11,5 @@ Changes:
* Removed demo examples
* Adjusted ajax setting to accept parameters from Mahara
* Moved the css styles to htdocs/theme/raw/sass/features/_timeline.scss
* Added prev / next arrows for the events
/* --------------------------------
NOTE: These styles are now used in htdocs/theme/raw/sass/features/_timeline.sass
Please update the styles there and not here - this is just kept to help upgrade process
Primary style
......
......@@ -46,6 +46,7 @@
timelineComponents['timelineDates'] = parseDate(timelineComponents['timelineEvents']);
timelineComponents['eventsMinLapse'] = minLapse(timelineComponents['timelineDates']);
timelineComponents['timelineNavigation'] = timeline.find('.cd-timeline-navigation');
timelineComponents['timelineNavigationViewport'] = timeline.find('.cd-timeline-navigation-second');
timelineComponents['eventsContent'] = timeline.children('.events-content');
//assign a left postion to the single events along the timeline
setDatePosition(timelineComponents, options.eventsMinDistance);
......@@ -73,6 +74,41 @@
updateFilling($(this), timelineComponents['fillingLine'], timelineTotWidth);
updateVisibleContent($(this), timelineComponents['eventsContent']);
});
//detect click on the next viewport arrow
timelineComponents['timelineNavigationViewport'].on('click', '.next', function (event) {
event.preventDefault();
// $().addClass('selected');
var currentSelected = $('#jtlinesection .events a.selected');
currentSelected.removeClass('selected');
console.log(currentSelected);
var nextSelected = currentSelected.closest('li').next().find('a');
nextSelected.addClass('selected');
console.log(nextSelected);
updateOlderEvents(nextSelected);
updateFilling(nextSelected, timelineComponents['fillingLine'], timelineTotWidth);
updateVisibleContent(nextSelected, timelineComponents['eventsContent']);
updateSlide(timelineComponents, timelineTotWidth, 'next');
});
//detect click on the prev viewport arrow
timelineComponents['timelineNavigationViewport'].on('click', '.prev', function (event) {
event.preventDefault();
var currentSelected = $('#jtlinesection .events ol li a.selected');
currentSelected.removeClass('selected');
console.log(currentSelected);
var nextSelected = currentSelected.closest('li').next().find('a');
nextSelected.removeClass('selected');
var prevSelected = currentSelected.closest('li').prev().find('a');
prevSelected.addClass('selected');
updateOlderEvents(prevSelected);
updateFilling(prevSelected, timelineComponents['fillingLine'], timelineTotWidth);
updateVisibleContent(prevSelected, timelineComponents['eventsContent']);
updateSlide(timelineComponents, timelineTotWidth, 'prev');
// prevSelected.removeClass('older-event');
console.log(prevSelected);
});
//on swipe, show next/prev event content
timelineComponents['eventsContent'].on('swipeleft', function () {
......@@ -110,6 +146,10 @@
var visibleContent = timelineComponents['eventsContent'].find('.selected'),
newContent = (string == 'next') ? visibleContent.next() : visibleContent.prev();
var showOldContent = function (timelineComponents, timelineTotWidth, string) {
var visibleContent = timelineComponents['eventsContent'].find('.selected'),
oldContent = (string == 'prev') ? visibleContent.prev() : visibleContent.next();
if (newContent.length > 0) { //if there's a next/prev event - show it
var selectedDate = timelineComponents['eventsWrapper'].find('.selected'),
newEvent = (string == 'next') ? selectedDate.parent('li').next('li').children('a') : selectedDate.parent('li').prev('li').children('a');
......@@ -122,6 +162,7 @@
updateTimelinePosition(string, newEvent, timelineComponents);
}
}
}
var updateTimelinePosition = function (string, event, timelineComponents) {
//translate timeline to the left/right according to the position of the selected event
......@@ -144,6 +185,8 @@
//update navigation arrows visibility
(value == 0) ? timelineComponents['timelineNavigation'].find('.prev').addClass('inactive') : timelineComponents['timelineNavigation'].find('.prev').removeClass('inactive');
(value == totWidth) ? timelineComponents['timelineNavigation'].find('.next').addClass('inactive') : timelineComponents['timelineNavigation'].find('.next').removeClass('inactive');
(value == 0) ? timelineComponents['timelineNavigationViewport'].find('.prev').addClass('inactive') : timelineComponents['timelineNavigationViewport'].find('.prev').removeClass('inactive');
(value == totWidth) ? timelineComponents['timelineNavigationViewport'].find('.next').addClass('inactive') : timelineComponents['timelineNavigationViewport'].find('.next').removeClass('inactive');
}
var updateFilling = function (selectedEvent, filling, totWidth) {
......@@ -237,10 +280,11 @@
classLeaving = 'leave-right';
}
selectedContent.attr('class', classEnetering);
visibleContent.attr('class', classLeaving).one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function () {
visibleContent.removeClass('leave-right leave-left');
selectedContent.addClass(classEnetering);
visibleContent.addClass(classLeaving).one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function () {
visibleContent.removeClass('leave-right leave-left selected');
selectedContent.removeClass('enter-left enter-right');
selectedContent.addClass('selected');
});
eventsContent.css('height', selectedContentHeight + 'px');
}
......@@ -431,8 +475,12 @@
$liTimeLineCollection += point.pointCnt + '</a></li>';
// -----------------
$liEventContentCollection += '<li ';
if (isSelectedPoint)
$liEventContentCollection += 'class="selected"';
if (isSelectedPoint) {
$liEventContentCollection += 'class="lineli selected"';
}
else {
$liEventContentCollection += 'class="lineli"';
}
$liEventContentCollection += ' data-date="' + point.dateValue + '">' + formatTitle(point.title, dataCollection[i]) + formatSubTitle(point.subTitle, dataCollection[i]) + formatBodyContent(point.bodyCnt, dataCollection[i]) + '</li>';
}
......@@ -442,8 +490,8 @@
var $container = $(mainObject);
var $sectionStart = '<section id="jtlinesection" class="jtline">';
var $timeline = '<div class="timeline"><div class="events-wrapper"><div class="events"><ol>' + $liTimeLineCollection + '</ol><span class="filling-line" aria-hidden="true"></span></div></div><ul class="cd-timeline-navigation"><li><a href="#0" class="prev inactive">Prev</a></li><li><a href="#0" class="next">Next</a></li></ul></div>';
var $eventsContent = '<div class="events-content"><ol>' + $liEventContentCollection + '</ol></div>';
var $timeline = '<div class="timeline"><div class="events-wrapper"><div class="events"><ol>' + $liTimeLineCollection + '</ol><span class="filling-line" aria-hidden="true"></span></div></div><ul class="cd-timeline-navigation"><li class="lineli"><a href="#0" class="prev inactive">Prev</a></li><li lineli><a href="#0" class="next">Next</a></li></ul></div>';
var $eventsContent = '<div class="events-content"><ol>' + $liEventContentCollection + '</ol><ul class="cd-timeline-navigation-second"><li><a href="#0" class="prev inactive">Prev</a></li><li><a href="#0" class="next">Next</a></li></ul></div>';
var $sectionEnd = '</section>';
var allHtml = $sectionStart + $timeline + $eventsContent + $sectionEnd;
......@@ -477,7 +525,7 @@
if (formatBodyCnt)
return options.formatBodyContent(bodyCnt, obj);
else
return '<p>' + bodyCnt + '</p>';
return '<p class="linep">' + bodyCnt + '</p>';
}
var _attacheEvents = function () {
......
......@@ -254,6 +254,7 @@ $string['blocknotinview'] = 'The block with ID "%d" is not in the page.';
$string['viewcreatedsuccessfully'] = 'Page created successfully';
$string['viewaccesseditedsuccessfully'] = 'Page access saved successfully';
$string['viewsavedsuccessfully'] = 'Page saved successfully';
$string['savedtotimeline'] = 'Saved to timeline';
$string['updatedaccessfornumviews1'] = array(
'Access rules were updated for 1 page.',
'Access rules were updated for %d pages.',
......@@ -520,3 +521,6 @@ $string['advanced'] = 'Advanced';
// Versioning strings
$string['timeline'] = 'Timeline';
$string['timelinespecific'] = 'Timeline for %s';
$string['savetimeline'] = 'Save to timeline';
$string['savetimelinespecific'] = 'Save timeline for %s';
......@@ -7082,7 +7082,8 @@ class View {
if ($records = get_records_sql_array("SELECT vv.*, v.title AS viewname, v.owner, v.institution
FROM {view_versioning} vv
JOIN {view} v ON v.id = vv.view
WHERE vv.ctime < ? AND vv.ctime > ? AND vv.view = ?", array($todate, $fromdate, $view))) {
WHERE vv.ctime < ? AND vv.ctime > ? AND vv.view = ?
ORDER BY vv.ctime ASC", array($todate, $fromdate, $view))) {
$versions->count = count($records);
$versions->data = $records;
}
......@@ -7091,7 +7092,8 @@ class View {
if ($records = get_records_sql_array("SELECT vv.*,v.title AS viewname, v.owner, v.institution
FROM {view_versioning} vv
JOIN {view} v ON v.id = vv.view
WHERE vv.view = ?", array($view))) {
WHERE vv.view = ?
ORDER BY vv.ctime ASC", array($view))) {
$versions->count = count($records);
$versions->data = $records;
}
......@@ -7104,12 +7106,12 @@ class View {
require_once('pieforms/pieform/elements/calendar.php');
$elements = array(
'from' => array(
'title' => get_string('from'),
'title' => get_string('From'),
'type' => 'calendar',
'defaultvalue' => strtotime($from),
),
'to' => array(
'title' => get_string('to'),
'title' => get_string('To'),
'type' => 'calendar',
'defaultvalue' => strtotime($to),
),
......@@ -7134,8 +7136,60 @@ class View {
public function build_timeline_results($search, $offset, $limit) {
return false;
}
public function format_versioning_data($data) {
if (empty($data)) {
return $data;
}
$data=json_decode($data);
$this->numrows = isset($data->numrows) ? $data->numrows : $this->numrows;
$this->layout = isset($data->layout) ? $data->layout : $this->layout;
$this->description = isset($data->description) ? $data->description : '';
$this->tags = isset($data->tags) && is_array($data->tags) ? $data->tags : array();
$colsperrow = array();
if (isset($data->columnsperrow)) {
foreach ($data->columnsperrow as $k=>$v){
$colsperrow[$k] = $v;
}
}
$this->columnsperrow = $colsperrow;
$this->columns = array();
for ($i = 1; $i <= $this->numrows; $i++) {
for ($j = 1; $j <= $data->columnsperrow->{$i}->columns; $j++) {
$this->columns[$i][$j] = array('blockinstances' => array());
}
}
$html = '';
if (!empty($data->blocks)) {
require_once(get_config('docroot') . 'blocktype/lib.php');
foreach ($data->blocks as $k => $v) {
// log_debug($k . ': ' . $v->blocktype);
safe_require('blocktype', $v->blocktype);
$bi = new BlockInstance(0,
array(
'blocktype' => $v->blocktype,
'title' => $v->title,
'view' => $this->get('id'),
'view_obj' => $this,
'row' => $v->row,
'column' => $v->column,
'order' => $v->order,
'configdata' => serialize((array)$v->configdata),
)
);
// $html .= call_static_method(generate_class_name("blocktype", $v->blocktype), "render_instance", $bi);
$this->columns[$v->row][$v->column]['blockinstances'][] = $bi;
}
}
$html = $this->build_rows(true);
// log_debug($html);
$data->html = $html;
return $data;
}
}
class ViewSubmissionException extends UserException {
public function strings() {
return array_merge(
......
......@@ -388,6 +388,7 @@ td.action-list-copy {
padding: 1px 4px;
}
// Tinymce primary button
.mce-container,
.mce-widget,
......
......@@ -24,7 +24,7 @@ Main Components
position: relative;
height: 100px;
width: 100%;
max-width: 850px;
max-width: 1150px;
margin: 0 auto;
}
.jtline .events-wrapper {
......@@ -44,13 +44,11 @@ Main Components
}
.jtline .events-wrapper::before {
left: 0;
background-image: -webkit-linear-gradient( left , #f8f8f8, rgba(248, 248, 248, 0));
background-image: linear-gradient(to right, #f8f8f8, rgba(248, 248, 248, 0));
}
.jtline .events-wrapper::after {
right: 0;
background-image: -webkit-linear-gradient( right , #f8f8f8, rgba(248, 248, 248, 0));
background-image: linear-gradient(to left, #f8f8f8, rgba(248, 248, 248, 0));
// background-image: -webkit-linear-gradient( right , #f8f8f8, rgba(248, 248, 248, 0));
// background-image: linear-gradient(to left, #f8f8f8, rgba(248, 248, 248, 0));
}
.jtline .events {
/* this is the grey line/timeline */
......@@ -148,10 +146,17 @@ Main Components
}
}
.cd-timeline-navigation a {
ul.cd-timeline-navigation-second{
list-style-type: none !important;
padding: 0;
margin:0;
}
.cd-timeline-navigation a,
.cd-timeline-navigation-second a {
/* these are the left/right arrows to navigate the timeline */
position: absolute;
z-index: 1;
z-index: 8;
top: 50%;
bottom: auto;
-webkit-transform: translateY(-50%);
......@@ -163,6 +168,7 @@ Main Components
width: 34px;
border-radius: 50%;
border: 2px solid #dfdfdf;
list-style-type: none !important;
/* replace text with an icon */
overflow: hidden;
color: transparent;
......@@ -172,7 +178,12 @@ Main Components
-moz-transition: border-color 0.3s;
transition: border-color 0.3s;
}
.cd-timeline-navigation a::after {
.cd-timeline-navigation-second a {
}
.cd-timeline-navigation a::after,
.cd-timeline-navigation-second a::after {
/* arrow icon */
content: '';
position: absolute;
......@@ -189,7 +200,8 @@ Main Components
transform: translateX(-50%) translateY(-50%);
background: url(../../raw/images/cd-arrow.svg) no-repeat 0 0;
}
.cd-timeline-navigation a.prev {
.cd-timeline-navigation a.prev,
.cd-timeline-navigation-second a.prev {
left: 0;
-webkit-transform: translateY(-50%) rotate(180deg);
-moz-transform: translateY(-50%) rotate(180deg);
......@@ -197,24 +209,29 @@ Main Components
-o-transform: translateY(-50%) rotate(180deg);
transform: translateY(-50%) rotate(180deg);
}
.cd-timeline-navigation a.next {
.cd-timeline-navigation a.next,
.cd-timeline-navigation-second a.next {
right: 0;
}
.no-touch .cd-timeline-navigation a:hover {
.no-touch .cd-timeline-navigation a:hover,
.no-touch .cd-timeline-navigation-second a:hover {
border-color: #7b9d6f;
}
.cd-timeline-navigation a.inactive {
.cd-timeline-navigation a.inactive,
.cd-timeline-navigation-second a.inactive {
cursor: not-allowed;
}
.cd-timeline-navigation a.inactive::after {
.cd-timeline-navigation a.inactive::after,
.cd-timeline-navigation-second a.inactive::after {
background-position: 0 -16px;
}
.no-touch .cd-timeline-navigation a.inactive:hover {
.no-touch .cd-timeline-navigation a.inactive:hover,
.no-touch .cd-timeline-navigation-second a.inactive:hover {
border-color: #dfdfdf;
}
.jtline .events-content {
width:800px;
// width:900px;
margin:0 auto;
position: relative;
......@@ -223,7 +240,7 @@ Main Components
-moz-transition: height 0.4s;
transition: height 0.4s;
}
.jtline .events-content li {
.jtline .events-content li.lineli {
position: absolute;
z-index: 1;
width: 100%;
......@@ -241,7 +258,9 @@ Main Components
-webkit-animation-timing-function: ease-in-out;
-moz-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
list-style: none !important;
}
.jtline .events-content li.selected {
/* visible event content */
position: relative;
......@@ -273,15 +292,30 @@ Main Components
list-style: none !important;
}
.jtline .timeline .cd-timeline-navigation {
.jtline .events a:hover {
outline-color: #000;
}
.jtline .timeline .cd-timeline-navigation,
.jtline .timeline .cd-timeline-navigation-second {
list-style: none !important;
}
.jtline .timeline .cd-timeline-navigation ul li,
.jtline #jtlinesection .timeline .cd-timeline-navigation-second li {
list-style-type: none !important;
}
.jtline .timeline ol, .ListeOL {
list-style: none !important;
// list-style: none !important;
margin: 0 0 0 0;
padding: 50px;
}
.jtline .events-content ol {
// margin: 2px;
}
.jtline .events-content h2 {
font-weight: bold;
font-size: 2.6rem;
......@@ -298,11 +332,11 @@ padding: 50px;
.jtline .events-content em::before {
content: '- ';
}
.jtline .events-content p {
.jtline .events-content p.linep {
font-size: 1.4rem;
color: #959595;
}
.jtline .events-content em, .jtline .events-content p {
.jtline .events-content em, .jtline .events-content p.linep {
line-height: 1.6;
}
@media only screen and (min-width: 768px) {
......@@ -312,7 +346,7 @@ padding: 50px;
.jtline .events-content em {
font-size: 2rem;
}
.jtline .events-content p {
.jtline .events-content p.linep {
font-size: 1.8rem;
}
}
......@@ -396,13 +430,15 @@ padding: 50px;
#timeline_from_container {
width: 250px;
width: 200px;
display: inline-block;
margin-left: 5px;
}
#timeline_to_container {
width: 250px;
width: 200px;
display: inline-block;
margin-left: 3%;
}
#timeline_submit_container {
......
{include file="header.tpl"}
<div class="grouppageswrap view-container">
{if $views}
<table class="table table-striped fullwidth listing">
<tr>
<th> id </th>
<th> title </th>
<th> owner </th>
<th> institution </th>
</tr>
{$viewresults|safe}
</table>
{else}
<div class="no-results">
{str tag="youhavenoviews1" section="view"}
</div>
{/if}
{$timelineform|safe}
<div class="jtline"></div>
</div>
<script>
$(document).ready(function () {
var jtLine = $('.jtline').jTLine({
callType: 'ajax',
url:'versioning.json.php',
eventsMinDistance: 200,
distanceMode: 'fixDistance',
params: {literal}{{/literal}
'sesskey': config.sesskey,
{if $fromdate} 'fromdate' : '{$fromdate}', {/if}
{if $todate}'todate' : '{$todate}', {/if}
'view' : '{$view}',
{literal}}{/literal},
map: {
"dataRoot": "/",
"title": "taskTitle",
"subTitle": "taskSubTitle",
"dateValue": "assignDate",
"pointCnt": "taskShortDate",
"bodyCnt": "taskDetails"
},
formatTitle: function (title, obj) { return '<h3>' + title + '</h3>';},
formatSubTitle: function (subTitle, obj) { return '<div class="metadata">' + subTitle + '</div>';},
formatBodyContent: function (bodyCnt, obj) { return bodyCnt;},
onPointClick: function (e) {
console.log(e);
}
});
});
</script>
{include file="footer.tpl"}
......@@ -41,10 +41,7 @@
<div class="btn-group btn-group-top">
<a class="btn btn-default" href="{$versionurl}">
<span class="icon icon-code-fork icon-lg left" role="presentation" aria-hidden="true"></span>
{str tag=timeline section=view}
</a>
{if $editurl}{strip}
<a title="{str tag=editthisview section=view}" href="{$editurl}" class="btn btn-default">
<span class="icon icon-pencil icon-lg left" role="presentation" aria-hidden="true"></span>
......@@ -126,6 +123,22 @@
</li>
{/if}
{/if}
<li>
<a href="{$versionurl}">
<span class="icon icon-code-fork icon-lg left" role="presentation" aria-hidden="true"></span>
<span class="sr-only">{str(tag=timelinespecific section=view arg1=$maintitle)|escape:html|safe}</span>
{str tag=timeline section=view}
</a>
</li>
{if $userisowner}
<li>
<a href="{$createversionurl}">
<span class="icon icon-save icon-lg left" role="presentation" aria-hidden="true"></span>
<span class="sr-only">{str(tag=savetimelinespecific section=view arg1=$maintitle)|escape:html|safe}</span>
{str tag=savetimeline section=view}
</a>
</li>
{/if}
</ul>
</div>
<div class="btn-group-top-below">
......
<?php
/**
*
* @package mahara
* @subpackage core
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
require(dirname(dirname(__FILE__)) . '/init.php');
require_once('view.php');
$viewid = param_integer('view');
$view = new View($viewid, null);
if (!$view || !$USER->can_edit_view($view) || $view->is_submitted()) {
throw new AccessDeniedException(get_string('cantversionview', 'view'));
}
$groupid = $view->get('group');
if ($groupid && !group_within_edit_window($groupid)) {
throw new AccessDeniedException(get_string('cantversionview', 'view'));
}
$version = new stdClass();
$version->numrows = $view->get('numrows');
$version->layout = $view->get('layout');
$version->description = $view->get('description');
$version->tags = $view->get('tags');
$version->columnsperrow = $view->get('columnsperrow');
$version->blocks = array();
$blocks = get_records_array('block_instance', 'view', $view->get('id'));
if ($blocks) {
foreach ($blocks as $k => $b) {
if (safe_require('blocktype', $b->blocktype, 'lib.php', 'require_once', true) !== false) {
$oldblock = new BlockInstance($b->id, $b);
$bi = new stdClass();
$bi->blocktype = $oldblock->get('blocktype');
$bi->title = $oldblock->get('title');
$bi->configdata = $oldblock->get('configdata');