Added Markdown editor and Javascript code refactoring
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
Version 1.0.27 (unreleased)
|
Version 1.0.27 (unreleased)
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
Improvements:
|
New features:
|
||||||
|
|
||||||
* Improve comments design
|
* Added Markdown editor
|
||||||
* Added letter avatar provider
|
* Added letter avatar provider
|
||||||
* Added pluggable Avatar providers
|
* Added pluggable Avatar providers
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Refactoring of Javascript code
|
||||||
|
* Improve comments design
|
||||||
* Improve task summary sections
|
* Improve task summary sections
|
||||||
* Put back the action sidebar in task view
|
* Put back the action sidebar in task view
|
||||||
* Added support for multiple placeholders for LDAP_USER_FILTER
|
* Added support for multiple placeholders for LDAP_USER_FILTER
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -2,10 +2,10 @@ BUILD_DIR = /tmp
|
|||||||
|
|
||||||
CSS_APP = $(addprefix assets/css/src/, $(addsuffix .css, base links title table form button alert tooltip header board task comment subtask tasklink markdown listing activity dashboard pagination popover confirm sidebar responsive dropdown upload filters gantt project files views accordion avatar))
|
CSS_APP = $(addprefix assets/css/src/, $(addsuffix .css, base links title table form button alert tooltip header board task comment subtask tasklink markdown listing activity dashboard pagination popover confirm sidebar responsive dropdown upload filters gantt project files views accordion avatar))
|
||||||
CSS_PRINT = $(addprefix assets/css/src/, $(addsuffix .css, print links table board task comment subtask tasklink markdown))
|
CSS_PRINT = $(addprefix assets/css/src/, $(addsuffix .css, print links table board task comment subtask tasklink markdown))
|
||||||
CSS_VENDOR = $(addprefix assets/css/vendor/, $(addsuffix .css, jquery-ui.min jquery-ui-timepicker-addon.min chosen.min fullcalendar.min font-awesome.min c3.min))
|
CSS_VENDOR = $(addprefix assets/css/vendor/, $(addsuffix .css, jquery-ui.min jquery-ui-timepicker-addon.min chosen.min fullcalendar.min font-awesome.min c3.min simplemde.min))
|
||||||
|
|
||||||
JS_APP = $(addprefix assets/js/src/, $(addsuffix .js, Popover Dropdown Tooltip Markdown Search App Screenshot FileUpload Calendar Board Column Swimlane Gantt Task Project Subtask TaskRepartitionChart UserRepartitionChart CumulativeFlowDiagram BurndownChart AvgTimeColumnChart TaskTimeColumnChart LeadCycleTimeChart CompareHoursColumnChart Accordion Router))
|
JS_APP = $(addprefix assets/js/src/, $(addsuffix .js, Namespace App Dropdown Popover Notification Accordion Session Calendar AvgTimeColumnChart BurndownChart CompareHoursColumnChart CumulativeFlowDiagram LeadCycleTimeChart UserRepartitionChart TaskTimeColumnChart TaskRepartitionChart Gantt Column Markdown ProjectPermission ProjectCreation Screenshot FileUpload Search Task Subtask Swimlane BoardColumnView BoardColumnScrolling BoardHorizontalScrolling BoardCollapsedMode BoardDragAndDrop BoardTask BoardPolling Tooltip Bootstrap))
|
||||||
JS_VENDOR = $(addprefix assets/js/vendor/, $(addsuffix .js, jquery-1.11.3.min jquery-ui.min jquery-ui-timepicker-addon.min jquery.ui.touch-punch.min chosen.jquery.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min jquery.textcomplete))
|
JS_VENDOR = $(addprefix assets/js/vendor/, $(addsuffix .js, jquery-1.11.3.min jquery-ui.min jquery-ui-timepicker-addon.min jquery.ui.touch-punch.min chosen.jquery.min moment.min fullcalendar.min mousetrap.min mousetrap-global-bind.min simplemde.min))
|
||||||
JS_LANG = $(addprefix assets/js/vendor/lang/, $(addsuffix .js, cs da de es el fi fr hu id it ja nl nb pl pt pt-br ru sv sr th tr zh-cn))
|
JS_LANG = $(addprefix assets/js/vendor/lang/, $(addsuffix .js, cs da de es el fi fr hu id it ja nl nb pl pt pt-br ru sv sr th tr zh-cn))
|
||||||
|
|
||||||
all: css js
|
all: css js
|
||||||
@@ -35,10 +35,9 @@ vendor.js:
|
|||||||
@ cat ${JS_LANG} >> vendor.js
|
@ cat ${JS_LANG} >> vendor.js
|
||||||
|
|
||||||
app.js:
|
app.js:
|
||||||
|
@ rm -f tmp.js
|
||||||
@ rm -f assets/js/app.js
|
@ rm -f assets/js/app.js
|
||||||
@ echo "(function() { 'use strict';" > tmp.js
|
|
||||||
@ cat ${JS_APP} >> tmp.js
|
@ cat ${JS_APP} >> tmp.js
|
||||||
@ echo "})();" >> tmp.js
|
|
||||||
@ yuicompressor --charset utf-8 --type js -o tmp.js tmp.js
|
@ yuicompressor --charset utf-8 --type js -o tmp.js tmp.js
|
||||||
@ cat vendor.js tmp.js >> assets/js/app.js
|
@ cat vendor.js tmp.js >> assets/js/app.js
|
||||||
@ rm -f tmp.js
|
@ rm -f tmp.js
|
||||||
|
|||||||
@@ -13,24 +13,7 @@
|
|||||||
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
|
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
|
<?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
|
||||||
<div class="form-tabs">
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -14,24 +14,7 @@
|
|||||||
<?= $this->form->number('task_limit', $values, $errors) ?>
|
<?= $this->form->number('task_limit', $values, $errors) ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
|
<?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
|
||||||
<div class="form-tabs">
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -16,25 +16,7 @@
|
|||||||
<?= $this->form->number('task_limit', $values, $errors) ?>
|
<?= $this->form->number('task_limit', $values, $errors) ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
|
<?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
|
||||||
<div class="form-tabs">
|
|
||||||
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -6,16 +6,7 @@
|
|||||||
<?= $this->form->hidden('task_id', $values) ?>
|
<?= $this->form->hidden('task_id', $values) ?>
|
||||||
<?= $this->form->hidden('user_id', $values) ?>
|
<?= $this->form->hidden('user_id', $values) ?>
|
||||||
|
|
||||||
<div class="form-tabs">
|
<div class="markdown-editor-small">
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea(
|
<?= $this->form->textarea(
|
||||||
'comment',
|
'comment',
|
||||||
$values,
|
$values,
|
||||||
@@ -26,15 +17,9 @@
|
|||||||
'placeholder="'.t('Leave a comment').'"',
|
'placeholder="'.t('Leave a comment').'"',
|
||||||
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $task['project_id'])).'"',
|
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $task['project_id'])).'"',
|
||||||
),
|
),
|
||||||
'comment-textarea'
|
'markdown-editor'
|
||||||
) ?>
|
) ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -9,24 +9,15 @@
|
|||||||
<?= $this->form->hidden('task_id', $values) ?>
|
<?= $this->form->hidden('task_id', $values) ?>
|
||||||
<?= $this->form->hidden('user_id', $values) ?>
|
<?= $this->form->hidden('user_id', $values) ?>
|
||||||
|
|
||||||
<div class="form-tabs">
|
<div class="markdown-editor-small">
|
||||||
<ul class="form-tabs-nav">
|
<?= $this->form->textarea(
|
||||||
<li class="form-tab form-tab-selected">
|
'comment',
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
$values,
|
||||||
</li>
|
$errors,
|
||||||
<li class="form-tab">
|
array('autofocus', 'required', 'placeholder="'.t('Leave a comment').'"'),
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
'markdown-editor'
|
||||||
</li>
|
) ?>
|
||||||
</ul>
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('comment', $values, $errors, array('autofocus', 'required', 'placeholder="'.t('Leave a comment').'"'), 'comment-textarea') ?>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -3,32 +3,20 @@
|
|||||||
<?= $this->form->hidden('task_id', $values) ?>
|
<?= $this->form->hidden('task_id', $values) ?>
|
||||||
<?= $this->form->hidden('user_id', $values) ?>
|
<?= $this->form->hidden('user_id', $values) ?>
|
||||||
|
|
||||||
<div class="form-tabs">
|
<div class="markdown-editor-small">
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea(
|
<?= $this->form->textarea(
|
||||||
'comment',
|
'comment',
|
||||||
$values,
|
$values,
|
||||||
$errors,
|
$errors,
|
||||||
array(
|
array(
|
||||||
|
'data-markdown-editor-disable-toolbar="true"',
|
||||||
'required',
|
'required',
|
||||||
'placeholder="'.t('Leave a comment').'"',
|
'placeholder="'.t('Leave a comment').'"',
|
||||||
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $task['project_id'])).'"',
|
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $task['project_id'])).'"',
|
||||||
),
|
),
|
||||||
'comment-textarea'
|
'markdown-editor'
|
||||||
) ?>
|
) ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -12,22 +12,7 @@
|
|||||||
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large') ?>
|
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large') ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
<div class="form-tabs">
|
<?= $this->form->textarea('description', $values, $errors, array('placeholder="'.t('Leave a description').'"', 'tabindex="2"'), 'markdown-editor') ?>
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors, array('placeholder="'.t('Leave a description').'"', 'tabindex="2"')) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?= $this->render('task/color_picker', array('colors_list' => $colors_list, 'values' => $values)) ?>
|
<?= $this->render('task/color_picker', array('colors_list' => $colors_list, 'values' => $values)) ?>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,25 +11,7 @@
|
|||||||
<?= $this->form->csrf() ?>
|
<?= $this->form->csrf() ?>
|
||||||
<?= $this->form->hidden('id', $values) ?>
|
<?= $this->form->hidden('id', $values) ?>
|
||||||
<?= $this->form->hidden('name', $values) ?>
|
<?= $this->form->hidden('name', $values) ?>
|
||||||
|
<?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
|
||||||
<div class="form-tabs">
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -10,24 +10,7 @@
|
|||||||
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
|
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
|
<?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
|
||||||
<div class="form-tabs">
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -13,25 +13,7 @@
|
|||||||
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
|
<?= $this->form->text('name', $values, $errors, array('autofocus', 'required', 'maxlength="50"')) ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
|
<?= $this->form->textarea('description', $values, $errors, array(), 'markdown-editor') ?>
|
||||||
<div class="form-tabs">
|
|
||||||
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea('description', $values, $errors) ?>
|
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
@@ -11,9 +11,6 @@
|
|||||||
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large') ?>
|
<?= $this->form->text('title', $values, $errors, array('autofocus', 'required', 'maxlength="200"', 'tabindex="1"'), 'form-input-large') ?>
|
||||||
|
|
||||||
<?= $this->form->label(t('Description'), 'description') ?>
|
<?= $this->form->label(t('Description'), 'description') ?>
|
||||||
|
|
||||||
<div class="form-tabs">
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea(
|
<?= $this->form->textarea(
|
||||||
'description',
|
'description',
|
||||||
$values,
|
$values,
|
||||||
@@ -22,21 +19,9 @@
|
|||||||
'placeholder="'.t('Leave a description').'"',
|
'placeholder="'.t('Leave a description').'"',
|
||||||
'tabindex="2"',
|
'tabindex="2"',
|
||||||
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $values['project_id'])).'"'
|
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $values['project_id'])).'"'
|
||||||
)
|
),
|
||||||
|
'markdown-editor'
|
||||||
) ?>
|
) ?>
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?= $this->render('task/color_picker', array('colors_list' => $colors_list, 'values' => $values)) ?>
|
<?= $this->render('task/color_picker', array('colors_list' => $colors_list, 'values' => $values)) ?>
|
||||||
|
|
||||||
|
|||||||
@@ -7,16 +7,6 @@
|
|||||||
<?= $this->form->csrf() ?>
|
<?= $this->form->csrf() ?>
|
||||||
<?= $this->form->hidden('id', $values) ?>
|
<?= $this->form->hidden('id', $values) ?>
|
||||||
|
|
||||||
<div class="form-tabs">
|
|
||||||
<ul class="form-tabs-nav">
|
|
||||||
<li class="form-tab form-tab-selected">
|
|
||||||
<i class="fa fa-pencil-square-o fa-fw"></i><a id="markdown-write" href="#"><?= t('Write') ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="form-tab">
|
|
||||||
<a id="markdown-preview" href="#"><i class="fa fa-eye fa-fw"></i><?= t('Preview') ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="write-area">
|
|
||||||
<?= $this->form->textarea(
|
<?= $this->form->textarea(
|
||||||
'description',
|
'description',
|
||||||
$values,
|
$values,
|
||||||
@@ -26,15 +16,8 @@
|
|||||||
'placeholder="'.t('Leave a description').'"',
|
'placeholder="'.t('Leave a description').'"',
|
||||||
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $task['project_id'])).'"'
|
'data-mention-search-url="'.$this->url->href('UserHelper', 'mention', array('project_id' => $task['project_id'])).'"'
|
||||||
),
|
),
|
||||||
'task-show-description-textarea'
|
'markdown-editor'
|
||||||
) ?>
|
) ?>
|
||||||
</div>
|
|
||||||
<div class="preview-area">
|
|
||||||
<div class="markdown"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-help"><?= $this->url->doc(t('Write your text in Markdown'), 'syntax-guide') ?></div>
|
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
<button type="submit" class="btn btn-blue"><?= t('Save') ?></button>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -68,15 +68,3 @@
|
|||||||
.comment-content {
|
.comment-content {
|
||||||
margin-left: 55px;
|
margin-left: 55px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* comment textarea */
|
|
||||||
.comment-textarea {
|
|
||||||
height: 200px;
|
|
||||||
width: 80%;
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#comments .comment-textarea {
|
|
||||||
height: 80px;
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -149,7 +149,8 @@ input.form-input-large {
|
|||||||
.form-column {
|
.form-column {
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 3%;
|
margin-right: 3%;
|
||||||
max-width: 47%;
|
max-width: 50%;
|
||||||
|
min-width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-column ul {
|
.form-column ul {
|
||||||
@@ -184,55 +185,6 @@ input.form-input-large {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* preview tabs */
|
|
||||||
label + .form-tabs {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-tabs {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.form-tabs-nav {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-tabs-nav li {
|
|
||||||
margin-left: 0;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-tab {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-tab a {
|
|
||||||
color: #ccc;
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-tab a:focus,
|
|
||||||
.form-tab a:hover {
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-tab-selected a {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-area {
|
|
||||||
border: 1px dashed #000;
|
|
||||||
padding-top: 5px;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
display: none;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reset-password {
|
.reset-password {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,23 @@
|
|||||||
|
/* markdown editor */
|
||||||
|
div.CodeMirror,
|
||||||
|
div.CodeMirror-scroll {
|
||||||
|
max-height: 250px;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-editor-small div.CodeMirror,
|
||||||
|
.markdown-editor-small div.CodeMirror-scroll {
|
||||||
|
min-height: 100px;
|
||||||
|
max-height: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-column div.CodeMirror {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
/* markdown content */
|
/* markdown content */
|
||||||
.markdown {
|
.markdown {
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
font-size: 1.0em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown h1 {
|
.markdown h1 {
|
||||||
|
|||||||
@@ -13,11 +13,10 @@
|
|||||||
#popover-content {
|
#popover-content {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 70%;
|
width: 70%;
|
||||||
margin: 0 0 0 -35%;
|
left: 15%;
|
||||||
left: 50%;
|
|
||||||
top: 1%;
|
top: 1%;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-height: 85%;
|
max-height: 90%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,15 @@
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
td.task-table a {
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.task-table a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
/* task inside the board */
|
/* task inside the board */
|
||||||
.task-board {
|
.task-board {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
7
assets/css/vendor/simplemde.min.css
vendored
Normal file
7
assets/css/vendor/simplemde.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1240
assets/js/app.js
1240
assets/js/app.js
File diff suppressed because one or more lines are too long
@@ -1,11 +1,11 @@
|
|||||||
function Accordion(app) {
|
Kanboard.Accordion = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
Accordion.prototype.listen = function() {
|
Kanboard.Accordion.prototype.listen = function() {
|
||||||
$(document).on("click", ".accordion-toggle", function(e) {
|
$(document).on("click", ".accordion-toggle", function(e) {
|
||||||
e.preventDefault();
|
|
||||||
var section = $(this).parents(".accordion-section");
|
var section = $(this).parents(".accordion-section");
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
if (section.hasClass("accordion-collapsed")) {
|
if (section.hasClass("accordion-collapsed")) {
|
||||||
section.find(".accordion-content").show();
|
section.find(".accordion-content").show();
|
||||||
|
|||||||
@@ -1,75 +1,43 @@
|
|||||||
function App() {
|
Kanboard.App = function() {
|
||||||
this.board = new Board(this);
|
this.controllers = {};
|
||||||
this.markdown = new Markdown();
|
};
|
||||||
this.search = new Search(this);
|
|
||||||
this.swimlane = new Swimlane(this);
|
|
||||||
this.dropdown = new Dropdown();
|
|
||||||
this.tooltip = new Tooltip(this);
|
|
||||||
this.popover = new Popover(this);
|
|
||||||
this.task = new Task(this);
|
|
||||||
this.project = new Project();
|
|
||||||
this.subtask = new Subtask(this);
|
|
||||||
this.column = new Column(this);
|
|
||||||
this.file = new FileUpload(this);
|
|
||||||
this.accordion = new Accordion(this);
|
|
||||||
this.keyboardShortcuts();
|
|
||||||
this.task.keyboardShortcuts();
|
|
||||||
this.chosen();
|
|
||||||
this.poll();
|
|
||||||
|
|
||||||
// Alert box fadeout
|
Kanboard.App.prototype.get = function(controller) {
|
||||||
$(".alert-fade-out").delay(5000).fadeOut(800, function() {
|
return this.controllers[controller];
|
||||||
$(this).remove();
|
};
|
||||||
});
|
|
||||||
|
Kanboard.App.prototype.execute = function() {
|
||||||
|
for (var className in Kanboard) {
|
||||||
|
if (className !== "App") {
|
||||||
|
var controller = new Kanboard[className](this);
|
||||||
|
this.controllers[className] = controller;
|
||||||
|
|
||||||
|
if (typeof controller.execute === "function") {
|
||||||
|
controller.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof controller.listen === "function") {
|
||||||
|
controller.listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof controller.focus === "function") {
|
||||||
|
controller.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof controller.keyboardShortcuts === "function") {
|
||||||
|
controller.keyboardShortcuts();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
App.prototype.listen = function() {
|
|
||||||
this.project.listen();
|
|
||||||
this.popover.listen();
|
|
||||||
this.markdown.listen();
|
|
||||||
this.tooltip.listen();
|
|
||||||
this.dropdown.listen();
|
|
||||||
this.search.listen();
|
|
||||||
this.task.listen();
|
|
||||||
this.swimlane.listen();
|
|
||||||
this.subtask.listen();
|
|
||||||
this.column.listen();
|
|
||||||
this.file.listen();
|
|
||||||
this.accordion.listen();
|
|
||||||
this.search.focus();
|
|
||||||
this.autoComplete();
|
|
||||||
this.datePicker();
|
|
||||||
this.focus();
|
this.focus();
|
||||||
|
this.chosen();
|
||||||
|
this.keyboardShortcuts();
|
||||||
|
this.datePicker();
|
||||||
|
this.autoComplete();
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.refresh = function() {
|
Kanboard.App.prototype.keyboardShortcuts = function() {
|
||||||
$(document).off();
|
|
||||||
this.listen();
|
|
||||||
};
|
|
||||||
|
|
||||||
App.prototype.focus = function() {
|
|
||||||
|
|
||||||
// Autofocus fields (html5 autofocus works only with page onload)
|
|
||||||
$("[autofocus]").each(function(index, element) {
|
|
||||||
$(this).focus();
|
|
||||||
})
|
|
||||||
|
|
||||||
// Auto-select input fields
|
|
||||||
$(document).on('focus', '.auto-select', function() {
|
|
||||||
$(this).select();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Workaround for chrome
|
|
||||||
$(document).on('mouseup', '.auto-select', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
App.prototype.poll = function() {
|
|
||||||
window.setInterval(this.checkSession, 60000);
|
|
||||||
};
|
|
||||||
|
|
||||||
App.prototype.keyboardShortcuts = function() {
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Submit form
|
// Submit form
|
||||||
@@ -85,31 +53,50 @@ App.prototype.keyboardShortcuts = function() {
|
|||||||
|
|
||||||
// Close popover and dropdown
|
// Close popover and dropdown
|
||||||
Mousetrap.bindGlobal("esc", function() {
|
Mousetrap.bindGlobal("esc", function() {
|
||||||
self.popover.close();
|
self.get("Popover").close();
|
||||||
self.dropdown.close();
|
self.get("Dropdown").close();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show keyboard shortcut
|
// Show keyboard shortcut
|
||||||
Mousetrap.bind("?", function() {
|
Mousetrap.bind("?", function() {
|
||||||
self.popover.open($("body").data("keyboard-shortcut-url"));
|
self.get("Popover").open($("body").data("keyboard-shortcut-url"));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.checkSession = function() {
|
Kanboard.App.prototype.focus = function() {
|
||||||
if (! $(".form-login").length) {
|
// Auto-select input fields
|
||||||
$.ajax({
|
$(document).on('focus', '.auto-select', function() {
|
||||||
cache: false,
|
$(this).select();
|
||||||
url: $("body").data("status-url"),
|
});
|
||||||
statusCode: {
|
|
||||||
401: function() {
|
// Workaround for chrome
|
||||||
window.location = $("body").data("login-url");
|
$(document).on('mouseup', '.auto-select', function(e) {
|
||||||
}
|
e.preventDefault();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.datePicker = function() {
|
Kanboard.App.prototype.chosen = function() {
|
||||||
|
$(".chosen-select").each(function() {
|
||||||
|
var searchThreshold = $(this).data("search-threshold");
|
||||||
|
|
||||||
|
if (searchThreshold === undefined) {
|
||||||
|
searchThreshold = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(this).chosen({
|
||||||
|
width: "180px",
|
||||||
|
no_results_text: $(this).data("notfound"),
|
||||||
|
disable_search_threshold: searchThreshold
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".select-auto-redirect").change(function() {
|
||||||
|
var regex = new RegExp($(this).data('redirect-regex'), 'g');
|
||||||
|
window.location = $(this).data('redirect-url').replace(regex, $(this).val());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.App.prototype.datePicker = function() {
|
||||||
// Datepicker translation
|
// Datepicker translation
|
||||||
$.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]);
|
$.datepicker.setDefaults($.datepicker.regional[$("body").data("js-lang")]);
|
||||||
|
|
||||||
@@ -131,7 +118,7 @@ App.prototype.datePicker = function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.autoComplete = function() {
|
Kanboard.App.prototype.autoComplete = function() {
|
||||||
$(".autocomplete").each(function() {
|
$(".autocomplete").each(function() {
|
||||||
var input = $(this);
|
var input = $(this);
|
||||||
var field = input.data("dst-field");
|
var field = input.data("dst-field");
|
||||||
@@ -157,36 +144,33 @@ App.prototype.autoComplete = function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.chosen = function() {
|
Kanboard.App.prototype.hasId = function(id) {
|
||||||
$(".chosen-select").each(function() {
|
return !!document.getElementById(id);
|
||||||
var searchThreshold = $(this).data("search-threshold");
|
|
||||||
|
|
||||||
if (searchThreshold === undefined) {
|
|
||||||
searchThreshold = 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
$(this).chosen({
|
|
||||||
width: "180px",
|
|
||||||
no_results_text: $(this).data("notfound"),
|
|
||||||
disable_search_threshold: searchThreshold
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".select-auto-redirect").change(function() {
|
|
||||||
var regex = new RegExp($(this).data('redirect-regex'), 'g');
|
|
||||||
window.location = $(this).data('redirect-url').replace(regex, $(this).val());
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.showLoadingIcon = function() {
|
Kanboard.App.prototype.showLoadingIcon = function() {
|
||||||
$("body").append('<span id="app-loading-icon"> <i class="fa fa-spinner fa-spin"></i></span>');
|
$("body").append('<span id="app-loading-icon"> <i class="fa fa-spinner fa-spin"></i></span>');
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.hideLoadingIcon = function() {
|
Kanboard.App.prototype.hideLoadingIcon = function() {
|
||||||
$("#app-loading-icon").remove();
|
$("#app-loading-icon").remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.isVisible = function() {
|
Kanboard.App.prototype.formatDuration = function(d) {
|
||||||
|
if (d >= 86400) {
|
||||||
|
return Math.round(d/86400) + "d";
|
||||||
|
}
|
||||||
|
else if (d >= 3600) {
|
||||||
|
return Math.round(d/3600) + "h";
|
||||||
|
}
|
||||||
|
else if (d >= 60) {
|
||||||
|
return Math.round(d/60) + "m";
|
||||||
|
}
|
||||||
|
|
||||||
|
return d + "s";
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.App.prototype.isVisible = function() {
|
||||||
var property = "";
|
var property = "";
|
||||||
|
|
||||||
if (typeof document.hidden !== "undefined") {
|
if (typeof document.hidden !== "undefined") {
|
||||||
@@ -205,17 +189,3 @@ App.prototype.isVisible = function() {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
App.prototype.formatDuration = function(d) {
|
|
||||||
if (d >= 86400) {
|
|
||||||
return Math.round(d/86400) + "d";
|
|
||||||
}
|
|
||||||
else if (d >= 3600) {
|
|
||||||
return Math.round(d/3600) + "h";
|
|
||||||
}
|
|
||||||
else if (d >= 60) {
|
|
||||||
return Math.round(d/60) + "m";
|
|
||||||
}
|
|
||||||
|
|
||||||
return d + "s";
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
function AvgTimeColumnChart(app) {
|
Kanboard.AvgTimeColumnChart = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
AvgTimeColumnChart.prototype.execute = function() {
|
Kanboard.AvgTimeColumnChart.prototype.execute = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
if (this.app.hasId("analytic-avg-time-column")) {
|
||||||
var plots = [$("#chart").data("label")];
|
this.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.AvgTimeColumnChart.prototype.show = function() {
|
||||||
|
var chart = $("#chart");
|
||||||
|
var metrics = chart.data("metrics");
|
||||||
|
var plots = [chart.data("label")];
|
||||||
var categories = [];
|
var categories = [];
|
||||||
|
|
||||||
for (var column_id in metrics) {
|
for (var column_id in metrics) {
|
||||||
|
|||||||
@@ -1,336 +0,0 @@
|
|||||||
function Board(app) {
|
|
||||||
this.app = app;
|
|
||||||
this.checkInterval = null;
|
|
||||||
this.savingInProgress = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Board.prototype.execute = function() {
|
|
||||||
this.app.swimlane.refresh();
|
|
||||||
this.restoreColumnViewMode();
|
|
||||||
this.compactView();
|
|
||||||
this.poll();
|
|
||||||
this.keyboardShortcuts();
|
|
||||||
this.listen();
|
|
||||||
this.dragAndDrop();
|
|
||||||
|
|
||||||
$(window).on("load", this.columnScrolling);
|
|
||||||
$(window).resize(this.columnScrolling);
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.poll = function() {
|
|
||||||
var interval = parseInt($("#board").attr("data-check-interval"));
|
|
||||||
|
|
||||||
if (interval > 0) {
|
|
||||||
this.checkInterval = window.setInterval(this.check.bind(this), interval * 1000);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.reloadFilters = function(search) {
|
|
||||||
this.app.showLoadingIcon();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
cache: false,
|
|
||||||
url: $("#board").data("reload-url"),
|
|
||||||
contentType: "application/json",
|
|
||||||
type: "POST",
|
|
||||||
processData: false,
|
|
||||||
data: JSON.stringify({
|
|
||||||
search: search
|
|
||||||
}),
|
|
||||||
success: this.refresh.bind(this),
|
|
||||||
error: this.app.hideLoadingIcon.bind(this)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.check = function() {
|
|
||||||
if (this.app.isVisible() && ! this.savingInProgress) {
|
|
||||||
var self = this;
|
|
||||||
this.app.showLoadingIcon();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
cache: false,
|
|
||||||
url: $("#board").data("check-url"),
|
|
||||||
statusCode: {
|
|
||||||
200: function(data) { self.refresh(data); },
|
|
||||||
304: function () { self.app.hideLoadingIcon(); }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.save = function(taskId, columnId, position, swimlaneId) {
|
|
||||||
var self = this;
|
|
||||||
this.app.showLoadingIcon();
|
|
||||||
this.savingInProgress = true;
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
cache: false,
|
|
||||||
url: $("#board").data("save-url"),
|
|
||||||
contentType: "application/json",
|
|
||||||
type: "POST",
|
|
||||||
processData: false,
|
|
||||||
data: JSON.stringify({
|
|
||||||
"task_id": taskId,
|
|
||||||
"column_id": columnId,
|
|
||||||
"swimlane_id": swimlaneId,
|
|
||||||
"position": position
|
|
||||||
}),
|
|
||||||
success: function(data) {
|
|
||||||
self.refresh(data);
|
|
||||||
this.savingInProgress = false;
|
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
self.app.hideLoadingIcon();
|
|
||||||
this.savingInProgress = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.refresh = function(data) {
|
|
||||||
$("#board-container").replaceWith(data);
|
|
||||||
|
|
||||||
this.app.refresh();
|
|
||||||
this.app.swimlane.refresh();
|
|
||||||
this.app.hideLoadingIcon();
|
|
||||||
this.listen();
|
|
||||||
this.dragAndDrop();
|
|
||||||
this.compactView();
|
|
||||||
this.restoreColumnViewMode();
|
|
||||||
this.columnScrolling();
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.dragAndDrop = function() {
|
|
||||||
var self = this;
|
|
||||||
var params = {
|
|
||||||
forcePlaceholderSize: true,
|
|
||||||
tolerance: "pointer",
|
|
||||||
connectWith: ".board-task-list",
|
|
||||||
placeholder: "draggable-placeholder",
|
|
||||||
items: ".draggable-item",
|
|
||||||
stop: function(event, ui) {
|
|
||||||
var task = ui.item;
|
|
||||||
var taskId = task.attr('data-task-id');
|
|
||||||
var taskPosition = task.attr('data-position');
|
|
||||||
var taskColumnId = task.attr('data-column-id');
|
|
||||||
var taskSwimlaneId = task.attr('data-swimlane-id');
|
|
||||||
|
|
||||||
var newColumnId = task.parent().attr("data-column-id");
|
|
||||||
var newSwimlaneId = task.parent().attr('data-swimlane-id');
|
|
||||||
var newPosition = task.index() + 1;
|
|
||||||
|
|
||||||
task.removeClass("draggable-item-selected");
|
|
||||||
|
|
||||||
if (newColumnId != taskColumnId || newSwimlaneId != taskSwimlaneId || newPosition != taskPosition) {
|
|
||||||
self.changeTaskState(taskId);
|
|
||||||
self.save(taskId, newColumnId, newPosition, newSwimlaneId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
start: function(event, ui) {
|
|
||||||
ui.item.addClass("draggable-item-selected");
|
|
||||||
ui.placeholder.height(ui.item.height());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ($.support.touch) {
|
|
||||||
$(".task-board-sort-handle").css("display", "inline");
|
|
||||||
params["handle"] = ".task-board-sort-handle";
|
|
||||||
}
|
|
||||||
|
|
||||||
$(".board-task-list").sortable(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.changeTaskState = function(taskId) {
|
|
||||||
var task = $("div[data-task-id=" + taskId + "]");
|
|
||||||
task.addClass('task-board-saving-state');
|
|
||||||
task.find('.task-board-saving-icon').show();
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.listen = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
$(document).on("click", ".task-board-change-assignee", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
self.app.popover.open($(this).data('url'));
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on("click", ".task-board", function(e) {
|
|
||||||
if (e.target.tagName != "A" && e.target.tagName != "IMG") {
|
|
||||||
window.location = $(this).data("task-url");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', ".filter-toggle-scrolling", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
self.toggleCompactView();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on('click', ".filter-toggle-height", function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
self.toggleColumnScrolling();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on("click", ".board-toggle-column-view", function() {
|
|
||||||
self.toggleColumnViewMode($(this).data("column-id"));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.toggleColumnScrolling = function() {
|
|
||||||
var scrolling = localStorage.getItem("column_scroll");
|
|
||||||
|
|
||||||
if (scrolling == undefined) {
|
|
||||||
scrolling = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem("column_scroll", scrolling == 0 ? 1 : 0);
|
|
||||||
this.columnScrolling();
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.columnScrolling = function() {
|
|
||||||
if (localStorage.getItem("column_scroll") == 0) {
|
|
||||||
var height = 80;
|
|
||||||
|
|
||||||
$(".filter-max-height").show();
|
|
||||||
$(".filter-min-height").hide();
|
|
||||||
$(".board-rotation-wrapper").css("min-height", '');
|
|
||||||
|
|
||||||
$(".board-task-list").each(function() {
|
|
||||||
var columnHeight = $(this).height();
|
|
||||||
|
|
||||||
if (columnHeight > height) {
|
|
||||||
height = columnHeight;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".board-task-list").css("min-height", height);
|
|
||||||
$(".board-task-list").css("height", '');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
$(".filter-max-height").hide();
|
|
||||||
$(".filter-min-height").show();
|
|
||||||
|
|
||||||
if ($(".board-swimlane").length > 1) {
|
|
||||||
$(".board-task-list").each(function() {
|
|
||||||
if ($(this).height() > 500) {
|
|
||||||
$(this).css("height", 500);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$(this).css("min-height", 320); // Height of the dropdown menu
|
|
||||||
$(".board-rotation-wrapper").css("min-height", 320);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var height = $(window).height() - 170;
|
|
||||||
|
|
||||||
$(".board-task-list").css("height", height);
|
|
||||||
$(".board-rotation-wrapper").css("min-height", height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.toggleCompactView = function() {
|
|
||||||
var scrolling = localStorage.getItem("horizontal_scroll") || 1;
|
|
||||||
localStorage.setItem("horizontal_scroll", scrolling == 0 ? 1 : 0);
|
|
||||||
this.compactView();
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.compactView = function() {
|
|
||||||
if (localStorage.getItem("horizontal_scroll") == 0) {
|
|
||||||
$(".filter-wide").show();
|
|
||||||
$(".filter-compact").hide();
|
|
||||||
|
|
||||||
$("#board-container").addClass("board-container-compact");
|
|
||||||
$("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$(".filter-wide").hide();
|
|
||||||
$(".filter-compact").show();
|
|
||||||
|
|
||||||
$("#board-container").removeClass("board-container-compact");
|
|
||||||
$("#board th").removeClass("board-column-compact");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.toggleCollapsedMode = function() {
|
|
||||||
var self = this;
|
|
||||||
this.app.showLoadingIcon();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
cache: false,
|
|
||||||
url: $('.filter-display-mode:not([style="display: none;"]) a').attr('href'),
|
|
||||||
success: function(data) {
|
|
||||||
$('.filter-display-mode').toggle();
|
|
||||||
self.refresh(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.restoreColumnViewMode = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
$(".board-column-header").each(function() {
|
|
||||||
var columnId = $(this).data('column-id');
|
|
||||||
if (localStorage.getItem("hidden_column_" + columnId)) {
|
|
||||||
self.hideColumn(columnId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.toggleColumnViewMode = function(columnId) {
|
|
||||||
if (localStorage.getItem("hidden_column_" + columnId)) {
|
|
||||||
this.showColumn(columnId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.hideColumn(columnId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.hideColumn = function(columnId) {
|
|
||||||
$(".board-column-" + columnId + " .board-column-expanded").hide();
|
|
||||||
$(".board-column-" + columnId + " .board-column-collapsed").show();
|
|
||||||
$(".board-column-header-" + columnId + " .board-column-expanded").hide();
|
|
||||||
$(".board-column-header-" + columnId + " .board-column-collapsed").show();
|
|
||||||
|
|
||||||
$(".board-column-header-" + columnId).each(function() {
|
|
||||||
$(this).removeClass("board-column-compact");
|
|
||||||
$(this).addClass("board-column-header-collapsed");
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".board-column-" + columnId ).each(function() {
|
|
||||||
$(this).addClass("board-column-task-collapsed");
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".board-column-" + columnId + " .board-rotation").each(function() {
|
|
||||||
$(this).css("width", $(".board-column-" + columnId + "").height());
|
|
||||||
});
|
|
||||||
|
|
||||||
localStorage.setItem("hidden_column_" + columnId, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.showColumn = function(columnId) {
|
|
||||||
$(".board-column-" + columnId + " .board-column-expanded").show();
|
|
||||||
$(".board-column-" + columnId + " .board-column-collapsed").hide();
|
|
||||||
$(".board-column-header-" + columnId + " .board-column-expanded").show();
|
|
||||||
$(".board-column-header-" + columnId + " .board-column-collapsed").hide();
|
|
||||||
|
|
||||||
$(".board-column-header-" + columnId).removeClass("board-column-header-collapsed");
|
|
||||||
$(".board-column-" + columnId).removeClass("board-column-task-collapsed");
|
|
||||||
|
|
||||||
if (localStorage.getItem("horizontal_scroll") == 0) {
|
|
||||||
$(".board-column-header-" + columnId).addClass("board-column-compact");
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.removeItem("hidden_column_" + columnId);
|
|
||||||
};
|
|
||||||
|
|
||||||
Board.prototype.keyboardShortcuts = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
Mousetrap.bind("c", function() { self.toggleCompactView(); });
|
|
||||||
Mousetrap.bind("s", function() { self.toggleCollapsedMode(); });
|
|
||||||
|
|
||||||
Mousetrap.bind("n", function() {
|
|
||||||
self.app.popover.open($("#board").data("task-creation-url"));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
25
assets/js/src/BoardCollapsedMode.js
Normal file
25
assets/js/src/BoardCollapsedMode.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
Kanboard.BoardCollapsedMode = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardCollapsedMode.prototype.keyboardShortcuts = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Mousetrap.bind("s", function() {
|
||||||
|
self.toggle();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardCollapsedMode.prototype.toggle = function() {
|
||||||
|
var self = this;
|
||||||
|
this.app.showLoadingIcon();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
url: $('.filter-display-mode:not([style="display: none;"]) a').attr('href'),
|
||||||
|
success: function(data) {
|
||||||
|
$('.filter-display-mode').toggle();
|
||||||
|
self.app.get("BoardDragAndDrop").refresh(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
85
assets/js/src/BoardColumnScrolling.js
Normal file
85
assets/js/src/BoardColumnScrolling.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
Kanboard.BoardColumnScrolling = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnScrolling.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("board")) {
|
||||||
|
this.render();
|
||||||
|
|
||||||
|
$(window).on("load", this.render);
|
||||||
|
$(window).resize(this.render);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnScrolling.prototype.listen = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(document).on('click', ".filter-toggle-height", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self.toggle();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnScrolling.prototype.onBoardRendered = function() {
|
||||||
|
this.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnScrolling.prototype.toggle = function() {
|
||||||
|
var scrolling = localStorage.getItem("column_scroll");
|
||||||
|
|
||||||
|
if (scrolling == undefined) {
|
||||||
|
scrolling = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("column_scroll", scrolling == 0 ? 1 : 0);
|
||||||
|
this.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnScrolling.prototype.render = function() {
|
||||||
|
var taskList = $(".board-task-list");
|
||||||
|
var rotationWrapper = $(".board-rotation-wrapper");
|
||||||
|
var filterMax = $(".filter-max-height");
|
||||||
|
var filterMin = $(".filter-min-height");
|
||||||
|
|
||||||
|
if (localStorage.getItem("column_scroll") == 0) {
|
||||||
|
var height = 80;
|
||||||
|
|
||||||
|
filterMax.show();
|
||||||
|
filterMin.hide();
|
||||||
|
rotationWrapper.css("min-height", '');
|
||||||
|
|
||||||
|
taskList.each(function() {
|
||||||
|
var columnHeight = $(this).height();
|
||||||
|
|
||||||
|
if (columnHeight > height) {
|
||||||
|
height = columnHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
taskList.css("min-height", height);
|
||||||
|
taskList.css("height", '');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
filterMax.hide();
|
||||||
|
filterMin.show();
|
||||||
|
|
||||||
|
if ($(".board-swimlane").length > 1) {
|
||||||
|
taskList.each(function() {
|
||||||
|
if ($(this).height() > 500) {
|
||||||
|
$(this).css("height", 500);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(this).css("min-height", 320); // Height of the dropdown menu
|
||||||
|
rotationWrapper.css("min-height", 320);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var height = $(window).height() - 170;
|
||||||
|
|
||||||
|
taskList.css("height", height);
|
||||||
|
rotationWrapper.css("min-height", height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
79
assets/js/src/BoardColumnView.js
Normal file
79
assets/js/src/BoardColumnView.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
Kanboard.BoardColumnView = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("board")) {
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.listen = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(document).on("click", ".board-toggle-column-view", function() {
|
||||||
|
self.toggle($(this).data("column-id"));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.onBoardRendered = function() {
|
||||||
|
this.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.render = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(".board-column-header").each(function() {
|
||||||
|
var columnId = $(this).data('column-id');
|
||||||
|
if (localStorage.getItem("hidden_column_" + columnId)) {
|
||||||
|
self.hideColumn(columnId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.toggle = function(columnId) {
|
||||||
|
if (localStorage.getItem("hidden_column_" + columnId)) {
|
||||||
|
this.showColumn(columnId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.hideColumn(columnId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.hideColumn = function(columnId) {
|
||||||
|
$(".board-column-" + columnId + " .board-column-expanded").hide();
|
||||||
|
$(".board-column-" + columnId + " .board-column-collapsed").show();
|
||||||
|
$(".board-column-header-" + columnId + " .board-column-expanded").hide();
|
||||||
|
$(".board-column-header-" + columnId + " .board-column-collapsed").show();
|
||||||
|
|
||||||
|
$(".board-column-header-" + columnId).each(function() {
|
||||||
|
$(this).removeClass("board-column-compact");
|
||||||
|
$(this).addClass("board-column-header-collapsed");
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".board-column-" + columnId).each(function() {
|
||||||
|
$(this).addClass("board-column-task-collapsed");
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".board-column-" + columnId + " .board-rotation").each(function() {
|
||||||
|
$(this).css("width", $(".board-column-" + columnId + "").height());
|
||||||
|
});
|
||||||
|
|
||||||
|
localStorage.setItem("hidden_column_" + columnId, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardColumnView.prototype.showColumn = function(columnId) {
|
||||||
|
$(".board-column-" + columnId + " .board-column-expanded").show();
|
||||||
|
$(".board-column-" + columnId + " .board-column-collapsed").hide();
|
||||||
|
$(".board-column-header-" + columnId + " .board-column-expanded").show();
|
||||||
|
$(".board-column-header-" + columnId + " .board-column-collapsed").hide();
|
||||||
|
|
||||||
|
$(".board-column-header-" + columnId).removeClass("board-column-header-collapsed");
|
||||||
|
$(".board-column-" + columnId).removeClass("board-column-task-collapsed");
|
||||||
|
|
||||||
|
if (localStorage.getItem("horizontal_scroll") == 0) {
|
||||||
|
$(".board-column-header-" + columnId).addClass("board-column-compact");
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.removeItem("hidden_column_" + columnId);
|
||||||
|
};
|
||||||
103
assets/js/src/BoardDragAndDrop.js
Normal file
103
assets/js/src/BoardDragAndDrop.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
Kanboard.BoardDragAndDrop = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
this.savingInProgress = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardDragAndDrop.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("board")) {
|
||||||
|
this.dragAndDrop();
|
||||||
|
this.executeListeners();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardDragAndDrop.prototype.dragAndDrop = function() {
|
||||||
|
var self = this;
|
||||||
|
var params = {
|
||||||
|
forcePlaceholderSize: true,
|
||||||
|
tolerance: "pointer",
|
||||||
|
connectWith: ".board-task-list",
|
||||||
|
placeholder: "draggable-placeholder",
|
||||||
|
items: ".draggable-item",
|
||||||
|
stop: function(event, ui) {
|
||||||
|
var task = ui.item;
|
||||||
|
var taskId = task.attr('data-task-id');
|
||||||
|
var taskPosition = task.attr('data-position');
|
||||||
|
var taskColumnId = task.attr('data-column-id');
|
||||||
|
var taskSwimlaneId = task.attr('data-swimlane-id');
|
||||||
|
|
||||||
|
var newColumnId = task.parent().attr("data-column-id");
|
||||||
|
var newSwimlaneId = task.parent().attr('data-swimlane-id');
|
||||||
|
var newPosition = task.index() + 1;
|
||||||
|
|
||||||
|
task.removeClass("draggable-item-selected");
|
||||||
|
|
||||||
|
if (newColumnId != taskColumnId || newSwimlaneId != taskSwimlaneId || newPosition != taskPosition) {
|
||||||
|
self.changeTaskState(taskId);
|
||||||
|
self.save(taskId, newColumnId, newPosition, newSwimlaneId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
start: function(event, ui) {
|
||||||
|
ui.item.addClass("draggable-item-selected");
|
||||||
|
ui.placeholder.height(ui.item.height());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($.support.touch) {
|
||||||
|
$(".task-board-sort-handle").css("display", "inline");
|
||||||
|
params["handle"] = ".task-board-sort-handle";
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".board-task-list").sortable(params);
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardDragAndDrop.prototype.changeTaskState = function(taskId) {
|
||||||
|
var task = $("div[data-task-id=" + taskId + "]");
|
||||||
|
task.addClass('task-board-saving-state');
|
||||||
|
task.find('.task-board-saving-icon').show();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardDragAndDrop.prototype.save = function(taskId, columnId, position, swimlaneId) {
|
||||||
|
var self = this;
|
||||||
|
self.app.showLoadingIcon();
|
||||||
|
self.savingInProgress = true;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
url: $("#board").data("save-url"),
|
||||||
|
contentType: "application/json",
|
||||||
|
type: "POST",
|
||||||
|
processData: false,
|
||||||
|
data: JSON.stringify({
|
||||||
|
"task_id": taskId,
|
||||||
|
"column_id": columnId,
|
||||||
|
"swimlane_id": swimlaneId,
|
||||||
|
"position": position
|
||||||
|
}),
|
||||||
|
success: function(data) {
|
||||||
|
self.refresh(data);
|
||||||
|
self.savingInProgress = false;
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
self.app.hideLoadingIcon();
|
||||||
|
self.savingInProgress = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardDragAndDrop.prototype.refresh = function(data) {
|
||||||
|
$("#board-container").replaceWith(data);
|
||||||
|
|
||||||
|
this.app.hideLoadingIcon();
|
||||||
|
this.dragAndDrop();
|
||||||
|
this.executeListeners();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardDragAndDrop.prototype.executeListeners = function() {
|
||||||
|
for (var className in this.app.controllers) {
|
||||||
|
var controller = this.app.get(className);
|
||||||
|
|
||||||
|
if (typeof controller.onBoardRendered === "function") {
|
||||||
|
controller.onBoardRendered();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
53
assets/js/src/BoardHorizontalScrolling.js
Normal file
53
assets/js/src/BoardHorizontalScrolling.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
Kanboard.BoardHorizontalScrolling = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardHorizontalScrolling.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("board")) {
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardHorizontalScrolling.prototype.listen = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(document).on('click', ".filter-toggle-scrolling", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self.toggle();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardHorizontalScrolling.prototype.keyboardShortcuts = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Mousetrap.bind("c", function() {
|
||||||
|
self.toggle();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardHorizontalScrolling.prototype.onBoardRendered = function() {
|
||||||
|
this.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardHorizontalScrolling.prototype.toggle = function() {
|
||||||
|
var scrolling = localStorage.getItem("horizontal_scroll") || 1;
|
||||||
|
localStorage.setItem("horizontal_scroll", scrolling == 0 ? 1 : 0);
|
||||||
|
this.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardHorizontalScrolling.prototype.render = function() {
|
||||||
|
if (localStorage.getItem("horizontal_scroll") == 0) {
|
||||||
|
$(".filter-wide").show();
|
||||||
|
$(".filter-compact").hide();
|
||||||
|
|
||||||
|
$("#board-container").addClass("board-container-compact");
|
||||||
|
$("#board th:not(.board-column-header-collapsed)").addClass("board-column-compact");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".filter-wide").hide();
|
||||||
|
$(".filter-compact").show();
|
||||||
|
|
||||||
|
$("#board-container").removeClass("board-container-compact");
|
||||||
|
$("#board th").removeClass("board-column-compact");
|
||||||
|
}
|
||||||
|
};
|
||||||
33
assets/js/src/BoardPolling.js
Normal file
33
assets/js/src/BoardPolling.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
Kanboard.BoardPolling = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardPolling.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("board")) {
|
||||||
|
var interval = parseInt($("#board").attr("data-check-interval"));
|
||||||
|
|
||||||
|
if (interval > 0) {
|
||||||
|
window.setInterval(this.check.bind(this), interval * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardPolling.prototype.check = function() {
|
||||||
|
if (this.app.isVisible() && !this.app.get("BoardDragAndDrop").savingInProgress) {
|
||||||
|
var self = this;
|
||||||
|
this.app.showLoadingIcon();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
url: $("#board").data("check-url"),
|
||||||
|
statusCode: {
|
||||||
|
200: function(data) {
|
||||||
|
self.app.get("BoardDragAndDrop").refresh(data);
|
||||||
|
},
|
||||||
|
304: function () {
|
||||||
|
self.app.hideLoadingIcon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
27
assets/js/src/BoardTask.js
Normal file
27
assets/js/src/BoardTask.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Kanboard.BoardTask = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardTask.prototype.listen = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$(document).on("click", ".task-board-change-assignee", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
self.app.get("Popover").open($(this).data('url'));
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", ".task-board", function(e) {
|
||||||
|
if (e.target.tagName != "A" && e.target.tagName != "IMG") {
|
||||||
|
window.location = $(this).data("task-url");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BoardTask.prototype.keyboardShortcuts = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
Mousetrap.bind("n", function() {
|
||||||
|
self.app.get("Popover").open($("#board").data("task-creation-url"));
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,12 +1,20 @@
|
|||||||
function BurndownChart() {
|
Kanboard.BurndownChart = function(app) {
|
||||||
}
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
BurndownChart.prototype.execute = function() {
|
Kanboard.BurndownChart.prototype.execute = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
if (this.app.hasId("analytic-burndown")) {
|
||||||
var columns = [[$("#chart").data("label-total")]];
|
this.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.BurndownChart.prototype.show = function() {
|
||||||
|
var chart = $("#chart");
|
||||||
|
var metrics = chart.data("metrics");
|
||||||
|
var columns = [[chart.data("label-total")]];
|
||||||
var categories = [];
|
var categories = [];
|
||||||
var inputFormat = d3.time.format("%Y-%m-%d");
|
var inputFormat = d3.time.format("%Y-%m-%d");
|
||||||
var outputFormat = d3.time.format($("#chart").data("date-format"));
|
var outputFormat = d3.time.format(chart.data("date-format"));
|
||||||
|
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
for (var i = 0; i < metrics.length; i++) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
function Calendar() {
|
Kanboard.Calendar = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
Kanboard.Calendar.prototype.execute = function() {
|
||||||
|
|
||||||
Calendar.prototype.execute = function() {
|
|
||||||
var calendar = $('#calendar');
|
var calendar = $('#calendar');
|
||||||
|
|
||||||
|
if (calendar.length == 1) {
|
||||||
|
this.show(calendar);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Calendar.prototype.show = function(calendar) {
|
||||||
calendar.fullCalendar({
|
calendar.fullCalendar({
|
||||||
lang: $("body").data("js-lang"),
|
lang: $("body").data("js-lang"),
|
||||||
editable: true,
|
editable: true,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
function Column(app) {
|
Kanboard.Column = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
Column.prototype.listen = function() {
|
Kanboard.Column.prototype.listen = function() {
|
||||||
this.dragAndDrop();
|
this.dragAndDrop();
|
||||||
};
|
};
|
||||||
|
|
||||||
Column.prototype.dragAndDrop = function() {
|
Kanboard.Column.prototype.dragAndDrop = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$(".draggable-row-handle").mouseenter(function() {
|
$(".draggable-row-handle").mouseenter(function() {
|
||||||
@@ -36,7 +36,7 @@ Column.prototype.dragAndDrop = function() {
|
|||||||
}).disableSelection();
|
}).disableSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
Column.prototype.savePosition = function(columnId, position) {
|
Kanboard.Column.prototype.savePosition = function(columnId, position) {
|
||||||
var url = $(".columns-table").data("save-position-url");
|
var url = $(".columns-table").data("save-position-url");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
function CompareHoursColumnChart(app) {
|
Kanboard.CompareHoursColumnChart = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
CompareHoursColumnChart.prototype.execute = function() {
|
Kanboard.CompareHoursColumnChart.prototype.execute = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
if (this.app.hasId("analytic-compare-hours")) {
|
||||||
var labelOpen = $("#chart").data("label-open");
|
this.show();
|
||||||
var labelClosed = $("#chart").data("label-closed");
|
}
|
||||||
var spent = [$("#chart").data("label-spent")];
|
};
|
||||||
var estimated = [$("#chart").data("label-estimated")];
|
|
||||||
|
Kanboard.CompareHoursColumnChart.prototype.show = function() {
|
||||||
|
var chart = $("#chart");
|
||||||
|
var metrics = chart.data("metrics");
|
||||||
|
var labelOpen = chart.data("label-open");
|
||||||
|
var labelClosed = chart.data("label-closed");
|
||||||
|
var spent = [chart.data("label-spent")];
|
||||||
|
var estimated = [chart.data("label-estimated")];
|
||||||
var categories = [];
|
var categories = [];
|
||||||
|
|
||||||
for (var status in metrics) {
|
for (var status in metrics) {
|
||||||
|
|||||||
@@ -1,14 +1,21 @@
|
|||||||
function CumulativeFlowDiagram() {
|
Kanboard.CumulativeFlowDiagram = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.CumulativeFlowDiagram.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("analytic-cfd")) {
|
||||||
|
this.show();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
CumulativeFlowDiagram.prototype.execute = function() {
|
Kanboard.CumulativeFlowDiagram.prototype.show = function() {
|
||||||
|
var chart = $("#chart");
|
||||||
var metrics = $("#chart").data("metrics");
|
var metrics = chart.data("metrics");
|
||||||
var columns = [];
|
var columns = [];
|
||||||
var groups = [];
|
var groups = [];
|
||||||
var categories = [];
|
var categories = [];
|
||||||
var inputFormat = d3.time.format("%Y-%m-%d");
|
var inputFormat = d3.time.format("%Y-%m-%d");
|
||||||
var outputFormat = d3.time.format($("#chart").data("date-format"));
|
var outputFormat = d3.time.format(chart.data("date-format"));
|
||||||
|
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
for (var i = 0; i < metrics.length; i++) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
function Dropdown() {
|
Kanboard.Dropdown = function(app) {
|
||||||
}
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
Dropdown.prototype.listen = function() {
|
Kanboard.Dropdown.prototype.listen = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$(document).on('click', function() {
|
$(document).on('click', function() {
|
||||||
@@ -46,23 +47,12 @@ Dropdown.prototype.listen = function() {
|
|||||||
$(this).find('a:visible')[0].click(); // Calling native click() not the jQuery one
|
$(this).find('a:visible')[0].click(); // Calling native click() not the jQuery one
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// User mention autocomplete
|
|
||||||
$('textarea[data-mention-search-url]').textcomplete([{
|
|
||||||
match: /(^|\s)@(\w*)$/,
|
|
||||||
search: function (term, callback) {
|
|
||||||
var url = $('textarea[data-mention-search-url]').data('mention-search-url');
|
|
||||||
$.getJSON(url, { q: term })
|
|
||||||
.done(function (resp) { callback(resp); })
|
|
||||||
.fail(function () { callback([]); });
|
|
||||||
},
|
|
||||||
replace: function (value) {
|
|
||||||
return '$1@' + value + ' ';
|
|
||||||
},
|
|
||||||
cache: true
|
|
||||||
}], {className: "textarea-dropdown"});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Dropdown.prototype.close = function() {
|
Kanboard.Dropdown.prototype.close = function() {
|
||||||
$("#dropdown").remove();
|
$("#dropdown").remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Kanboard.Dropdown.prototype.onPopoverOpened = function() {
|
||||||
|
this.close();
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
function FileUpload(app) {
|
Kanboard.FileUpload = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.files = [];
|
this.files = [];
|
||||||
this.currentFile = 0;
|
this.currentFile = 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
FileUpload.prototype.listen = function() {
|
Kanboard.FileUpload.prototype.onPopoverOpened = function() {
|
||||||
var dropzone = document.getElementById("file-dropzone");
|
var dropzone = document.getElementById("file-dropzone");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ FileUpload.prototype.listen = function() {
|
|||||||
dropzone.ondragover = dropzone.ondragenter = function(e) {
|
dropzone.ondragover = dropzone.ondragenter = function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
};
|
||||||
|
|
||||||
dropzone.ondrop = function(e) {
|
dropzone.ondrop = function(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -20,7 +20,7 @@ FileUpload.prototype.listen = function() {
|
|||||||
self.files = e.dataTransfer.files;
|
self.files = e.dataTransfer.files;
|
||||||
self.show();
|
self.show();
|
||||||
$("#file-error-max-size").hide();
|
$("#file-error-max-size").hide();
|
||||||
}
|
};
|
||||||
|
|
||||||
$(document).on("click", "#file-browser", function(e) {
|
$(document).on("click", "#file-browser", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -41,7 +41,7 @@ FileUpload.prototype.listen = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUpload.prototype.show = function() {
|
Kanboard.FileUpload.prototype.show = function() {
|
||||||
$("#file-list").remove();
|
$("#file-list").remove();
|
||||||
|
|
||||||
if (this.files.length > 0) {
|
if (this.files.length > 0) {
|
||||||
@@ -69,7 +69,7 @@ FileUpload.prototype.show = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUpload.prototype.checkFiles = function() {
|
Kanboard.FileUpload.prototype.checkFiles = function() {
|
||||||
var max = parseInt($("#file-dropzone").data("max-size"));
|
var max = parseInt($("#file-dropzone").data("max-size"));
|
||||||
|
|
||||||
for (var i = 0; i < this.files.length; i++) {
|
for (var i = 0; i < this.files.length; i++) {
|
||||||
@@ -84,13 +84,13 @@ FileUpload.prototype.checkFiles = function() {
|
|||||||
this.uploadFiles();
|
this.uploadFiles();
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUpload.prototype.uploadFiles = function() {
|
Kanboard.FileUpload.prototype.uploadFiles = function() {
|
||||||
if (this.files.length > 0) {
|
if (this.files.length > 0) {
|
||||||
this.uploadFile(this.files[this.currentFile]);
|
this.uploadFile(this.files[this.currentFile]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUpload.prototype.uploadFile = function(file) {
|
Kanboard.FileUpload.prototype.uploadFile = function(file) {
|
||||||
var dropzone = document.getElementById("file-dropzone");
|
var dropzone = document.getElementById("file-dropzone");
|
||||||
var url = dropzone.dataset.url;
|
var url = dropzone.dataset.url;
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
@@ -104,21 +104,22 @@ FileUpload.prototype.uploadFile = function(file) {
|
|||||||
xhr.send(fd);
|
xhr.send(fd);
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUpload.prototype.updateProgress = function(e) {
|
Kanboard.FileUpload.prototype.updateProgress = function(e) {
|
||||||
if (e.lengthComputable) {
|
if (e.lengthComputable) {
|
||||||
$("#file-progress-" + this.currentFile).val(e.loaded / e.total);
|
$("#file-progress-" + this.currentFile).val(e.loaded / e.total);
|
||||||
$("#file-percentage-" + this.currentFile).text('(' + Math.floor((e.loaded / e.total) * 100) + '%)');
|
$("#file-percentage-" + this.currentFile).text('(' + Math.floor((e.loaded / e.total) * 100) + '%)');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FileUpload.prototype.transferComplete = function() {
|
Kanboard.FileUpload.prototype.transferComplete = function() {
|
||||||
this.currentFile++;
|
this.currentFile++;
|
||||||
|
|
||||||
if (this.currentFile < this.files.length) {
|
if (this.currentFile < this.files.length) {
|
||||||
this.uploadFile(this.files[this.currentFile]);
|
this.uploadFile(this.files[this.currentFile]);
|
||||||
} else {
|
} else {
|
||||||
$("#file-upload-button").prop("disabled", true);
|
var uploadButton = $("#file-upload-button");
|
||||||
$("#file-upload-button").parent().hide();
|
uploadButton.prop("disabled", true);
|
||||||
|
uploadButton.parent().hide();
|
||||||
$("#file-done").show();
|
$("#file-done").show();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Based on jQuery.ganttView v.0.8.8 Copyright (c) 2010 JC Grubbs - jc.grubbs@devmynd.com - MIT License
|
// Based on jQuery.ganttView v.0.8.8 Copyright (c) 2010 JC Grubbs - jc.grubbs@devmynd.com - MIT License
|
||||||
function Gantt(app) {
|
Kanboard.Gantt = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.data = [];
|
this.data = [];
|
||||||
|
|
||||||
@@ -13,10 +13,16 @@ function Gantt(app) {
|
|||||||
slideWidth: 1000,
|
slideWidth: 1000,
|
||||||
vHeaderWidth: 200
|
vHeaderWidth: 200
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Gantt.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("gantt-chart")) {
|
||||||
|
this.show();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Save record after a resize or move
|
// Save record after a resize or move
|
||||||
Gantt.prototype.saveRecord = function(record) {
|
Kanboard.Gantt.prototype.saveRecord = function(record) {
|
||||||
this.app.showLoadingIcon();
|
this.app.showLoadingIcon();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@@ -31,7 +37,7 @@ Gantt.prototype.saveRecord = function(record) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Build the Gantt chart
|
// Build the Gantt chart
|
||||||
Gantt.prototype.execute = function() {
|
Kanboard.Gantt.prototype.show = function() {
|
||||||
this.data = this.prepareData($(this.options.container).data('records'));
|
this.data = this.prepareData($(this.options.container).data('records'));
|
||||||
|
|
||||||
var minDays = Math.floor((this.options.slideWidth / this.options.cellWidth) + 5);
|
var minDays = Math.floor((this.options.slideWidth / this.options.cellWidth) + 5);
|
||||||
@@ -60,7 +66,7 @@ Gantt.prototype.execute = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Render record list on the left
|
// Render record list on the left
|
||||||
Gantt.prototype.renderVerticalHeader = function() {
|
Kanboard.Gantt.prototype.renderVerticalHeader = function() {
|
||||||
var headerDiv = jQuery("<div>", { "class": "ganttview-vtheader" });
|
var headerDiv = jQuery("<div>", { "class": "ganttview-vtheader" });
|
||||||
var itemDiv = jQuery("<div>", { "class": "ganttview-vtheader-item" });
|
var itemDiv = jQuery("<div>", { "class": "ganttview-vtheader-item" });
|
||||||
var seriesDiv = jQuery("<div>", { "class": "ganttview-vtheader-series" });
|
var seriesDiv = jQuery("<div>", { "class": "ganttview-vtheader-series" });
|
||||||
@@ -92,7 +98,7 @@ Gantt.prototype.renderVerticalHeader = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Render right part of the chart (top header + grid + bars)
|
// Render right part of the chart (top header + grid + bars)
|
||||||
Gantt.prototype.renderSlider = function(startDate, endDate) {
|
Kanboard.Gantt.prototype.renderSlider = function(startDate, endDate) {
|
||||||
var slideDiv = jQuery("<div>", {"class": "ganttview-slide-container"});
|
var slideDiv = jQuery("<div>", {"class": "ganttview-slide-container"});
|
||||||
var dates = this.getDates(startDate, endDate);
|
var dates = this.getDates(startDate, endDate);
|
||||||
|
|
||||||
@@ -105,7 +111,7 @@ Gantt.prototype.renderSlider = function(startDate, endDate) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Render top header (days)
|
// Render top header (days)
|
||||||
Gantt.prototype.renderHorizontalHeader = function(dates) {
|
Kanboard.Gantt.prototype.renderHorizontalHeader = function(dates) {
|
||||||
var headerDiv = jQuery("<div>", { "class": "ganttview-hzheader" });
|
var headerDiv = jQuery("<div>", { "class": "ganttview-hzheader" });
|
||||||
var monthsDiv = jQuery("<div>", { "class": "ganttview-hzheader-months" });
|
var monthsDiv = jQuery("<div>", { "class": "ganttview-hzheader-months" });
|
||||||
var daysDiv = jQuery("<div>", { "class": "ganttview-hzheader-days" });
|
var daysDiv = jQuery("<div>", { "class": "ganttview-hzheader-days" });
|
||||||
@@ -135,7 +141,7 @@ Gantt.prototype.renderHorizontalHeader = function(dates) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Render grid
|
// Render grid
|
||||||
Gantt.prototype.renderGrid = function(dates) {
|
Kanboard.Gantt.prototype.renderGrid = function(dates) {
|
||||||
var gridDiv = jQuery("<div>", { "class": "ganttview-grid" });
|
var gridDiv = jQuery("<div>", { "class": "ganttview-grid" });
|
||||||
var rowDiv = jQuery("<div>", { "class": "ganttview-grid-row" });
|
var rowDiv = jQuery("<div>", { "class": "ganttview-grid-row" });
|
||||||
|
|
||||||
@@ -162,7 +168,7 @@ Gantt.prototype.renderGrid = function(dates) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Render bar containers
|
// Render bar containers
|
||||||
Gantt.prototype.addBlockContainers = function() {
|
Kanboard.Gantt.prototype.addBlockContainers = function() {
|
||||||
var blocksDiv = jQuery("<div>", { "class": "ganttview-blocks" });
|
var blocksDiv = jQuery("<div>", { "class": "ganttview-blocks" });
|
||||||
|
|
||||||
for (var i = 0; i < this.data.length; i++) {
|
for (var i = 0; i < this.data.length; i++) {
|
||||||
@@ -173,7 +179,7 @@ Gantt.prototype.addBlockContainers = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Render bars
|
// Render bars
|
||||||
Gantt.prototype.addBlocks = function(slider, start) {
|
Kanboard.Gantt.prototype.addBlocks = function(slider, start) {
|
||||||
var rows = jQuery("div.ganttview-blocks div.ganttview-block-container", slider);
|
var rows = jQuery("div.ganttview-blocks div.ganttview-block-container", slider);
|
||||||
var rowIdx = 0;
|
var rowIdx = 0;
|
||||||
|
|
||||||
@@ -219,7 +225,7 @@ Gantt.prototype.addBlocks = function(slider, start) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get tooltip for vertical header
|
// Get tooltip for vertical header
|
||||||
Gantt.prototype.getVerticalHeaderTooltip = function(record) {
|
Kanboard.Gantt.prototype.getVerticalHeaderTooltip = function(record) {
|
||||||
var tooltip = "";
|
var tooltip = "";
|
||||||
|
|
||||||
if (record.type == "task") {
|
if (record.type == "task") {
|
||||||
@@ -246,7 +252,7 @@ Gantt.prototype.getVerticalHeaderTooltip = function(record) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get tooltip for bars
|
// Get tooltip for bars
|
||||||
Gantt.prototype.getBarTooltip = function(record) {
|
Kanboard.Gantt.prototype.getBarTooltip = function(record) {
|
||||||
var tooltip = "";
|
var tooltip = "";
|
||||||
|
|
||||||
if (record.not_defined) {
|
if (record.not_defined) {
|
||||||
@@ -266,7 +272,7 @@ Gantt.prototype.getBarTooltip = function(record) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Set bar color
|
// Set bar color
|
||||||
Gantt.prototype.setBarColor = function(block, record) {
|
Kanboard.Gantt.prototype.setBarColor = function(block, record) {
|
||||||
if (record.not_defined) {
|
if (record.not_defined) {
|
||||||
block.addClass("ganttview-block-not-defined");
|
block.addClass("ganttview-block-not-defined");
|
||||||
}
|
}
|
||||||
@@ -277,7 +283,7 @@ Gantt.prototype.setBarColor = function(block, record) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup jquery-ui resizable
|
// Setup jquery-ui resizable
|
||||||
Gantt.prototype.listenForBlockResize = function(startDate) {
|
Kanboard.Gantt.prototype.listenForBlockResize = function(startDate) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
jQuery("div.ganttview-block", this.options.container).resizable({
|
jQuery("div.ganttview-block", this.options.container).resizable({
|
||||||
@@ -293,7 +299,7 @@ Gantt.prototype.listenForBlockResize = function(startDate) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Setup jquery-ui drag and drop
|
// Setup jquery-ui drag and drop
|
||||||
Gantt.prototype.listenForBlockMove = function(startDate) {
|
Kanboard.Gantt.prototype.listenForBlockMove = function(startDate) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
jQuery("div.ganttview-block", this.options.container).draggable({
|
jQuery("div.ganttview-block", this.options.container).draggable({
|
||||||
@@ -309,7 +315,7 @@ Gantt.prototype.listenForBlockMove = function(startDate) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Update the record data and the position on the chart
|
// Update the record data and the position on the chart
|
||||||
Gantt.prototype.updateDataAndPosition = function(block, startDate) {
|
Kanboard.Gantt.prototype.updateDataAndPosition = function(block, startDate) {
|
||||||
var container = jQuery("div.ganttview-slide-container", this.options.container);
|
var container = jQuery("div.ganttview-slide-container", this.options.container);
|
||||||
var scroll = container.scrollLeft();
|
var scroll = container.scrollLeft();
|
||||||
var offset = block.offset().left - container.offset().left - 1 + scroll;
|
var offset = block.offset().left - container.offset().left - 1 + scroll;
|
||||||
@@ -349,7 +355,7 @@ Gantt.prototype.updateDataAndPosition = function(block, startDate) {
|
|||||||
|
|
||||||
// Creates a 3 dimensional array [year][month][day] of every day
|
// Creates a 3 dimensional array [year][month][day] of every day
|
||||||
// between the given start and end dates
|
// between the given start and end dates
|
||||||
Gantt.prototype.getDates = function(start, end) {
|
Kanboard.Gantt.prototype.getDates = function(start, end) {
|
||||||
var dates = [];
|
var dates = [];
|
||||||
dates[start.getFullYear()] = [];
|
dates[start.getFullYear()] = [];
|
||||||
dates[start.getFullYear()][start.getMonth()] = [start];
|
dates[start.getFullYear()][start.getMonth()] = [start];
|
||||||
@@ -374,7 +380,7 @@ Gantt.prototype.getDates = function(start, end) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Convert data to Date object
|
// Convert data to Date object
|
||||||
Gantt.prototype.prepareData = function(data) {
|
Kanboard.Gantt.prototype.prepareData = function(data) {
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
var start = new Date(data[i].start[0], data[i].start[1] - 1, data[i].start[2], 0, 0, 0, 0);
|
var start = new Date(data[i].start[0], data[i].start[1] - 1, data[i].start[2], 0, 0, 0, 0);
|
||||||
data[i].start = start;
|
data[i].start = start;
|
||||||
@@ -387,7 +393,7 @@ Gantt.prototype.prepareData = function(data) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get the start and end date from the data provided
|
// Get the start and end date from the data provided
|
||||||
Gantt.prototype.getDateRange = function(minDays) {
|
Kanboard.Gantt.prototype.getDateRange = function(minDays) {
|
||||||
var minStart = new Date();
|
var minStart = new Date();
|
||||||
var maxEnd = new Date();
|
var maxEnd = new Date();
|
||||||
|
|
||||||
@@ -425,7 +431,7 @@ Gantt.prototype.getDateRange = function(minDays) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Returns the number of day between 2 dates
|
// Returns the number of day between 2 dates
|
||||||
Gantt.prototype.daysBetween = function(start, end) {
|
Kanboard.Gantt.prototype.daysBetween = function(start, end) {
|
||||||
if (! start || ! end) {
|
if (! start || ! end) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -441,17 +447,17 @@ Gantt.prototype.daysBetween = function(start, end) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Return true if it's the weekend
|
// Return true if it's the weekend
|
||||||
Gantt.prototype.isWeekend = function(date) {
|
Kanboard.Gantt.prototype.isWeekend = function(date) {
|
||||||
return date.getDay() % 6 == 0;
|
return date.getDay() % 6 == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clone Date object
|
// Clone Date object
|
||||||
Gantt.prototype.cloneDate = function(date) {
|
Kanboard.Gantt.prototype.cloneDate = function(date) {
|
||||||
return new Date(date.getTime());
|
return new Date(date.getTime());
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add days to a Date object
|
// Add days to a Date object
|
||||||
Gantt.prototype.addDays = function(date, value) {
|
Kanboard.Gantt.prototype.addDays = function(date, value) {
|
||||||
date.setDate(date.getDate() + value * 1);
|
date.setDate(date.getDate() + value * 1);
|
||||||
return date;
|
return date;
|
||||||
};
|
};
|
||||||
@@ -463,7 +469,7 @@ Gantt.prototype.addDays = function(date, value) {
|
|||||||
* 0 = values are equal
|
* 0 = values are equal
|
||||||
* 1 = date1 is greaterthan date2.
|
* 1 = date1 is greaterthan date2.
|
||||||
*/
|
*/
|
||||||
Gantt.prototype.compareDate = function(date1, date2) {
|
Kanboard.Gantt.prototype.compareDate = function(date1, date2) {
|
||||||
if (isNaN(date1) || isNaN(date2)) {
|
if (isNaN(date1) || isNaN(date2)) {
|
||||||
throw new Error(date1 + " - " + date2);
|
throw new Error(date1 + " - " + date2);
|
||||||
} else if (date1 instanceof Date && date2 instanceof Date) {
|
} else if (date1 instanceof Date && date2 instanceof Date) {
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
function LeadCycleTimeChart(app) {
|
Kanboard.LeadCycleTimeChart = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
LeadCycleTimeChart.prototype.execute = function() {
|
Kanboard.LeadCycleTimeChart.prototype.execute = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
if (this.app.hasId("analytic-lead-cycle-time")) {
|
||||||
var cycle = [$("#chart").data("label-cycle")];
|
this.show();
|
||||||
var lead = [$("#chart").data("label-lead")];
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.LeadCycleTimeChart.prototype.show = function() {
|
||||||
|
var chart = $("#chart");
|
||||||
|
var metrics = chart.data("metrics");
|
||||||
|
var cycle = [chart.data("label-cycle")];
|
||||||
|
var lead = [chart.data("label-lead")];
|
||||||
var categories = [];
|
var categories = [];
|
||||||
|
|
||||||
var types = {};
|
var types = {};
|
||||||
types[$("#chart").data("label-cycle")] = 'area';
|
types[chart.data("label-cycle")] = 'area';
|
||||||
types[$("#chart").data("label-lead")] = 'area-spline';
|
types[chart.data("label-lead")] = 'area-spline';
|
||||||
|
|
||||||
var colors = {};
|
var colors = {};
|
||||||
colors[$("#chart").data("label-lead")] = '#afb42b';
|
colors[chart.data("label-lead")] = '#afb42b';
|
||||||
colors[$("#chart").data("label-cycle")] = '#4e342e';
|
colors[chart.data("label-cycle")] = '#4e342e';
|
||||||
|
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
for (var i = 0; i < metrics.length; i++) {
|
||||||
cycle.push(parseInt(metrics[i].avg_cycle_time));
|
cycle.push(parseInt(metrics[i].avg_cycle_time));
|
||||||
|
|||||||
@@ -1,48 +1,59 @@
|
|||||||
function Markdown() {
|
Kanboard.Markdown = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
this.editor = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Markdown.prototype.onPopoverOpened = function() {
|
||||||
|
this.listen();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Markdown.prototype.onPopoverClosed = function() {
|
||||||
|
this.listen();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Markdown.prototype.listen = function() {
|
||||||
|
var editors = $(".markdown-editor");
|
||||||
|
|
||||||
|
if (this.editor) {
|
||||||
|
this.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
Markdown.prototype.showPreview = function(e) {
|
if (editors.length > 0) {
|
||||||
e.preventDefault();
|
this.show(editors[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var write = $(".write-area");
|
Kanboard.Markdown.prototype.destroy = function() {
|
||||||
var preview = $(".preview-area");
|
var cm = this.editor.codemirror;
|
||||||
var textarea = $("textarea");
|
var wrapper = cm.getWrapperElement();
|
||||||
|
|
||||||
$("#markdown-write").parent().removeClass("form-tab-selected");
|
for (var item in ["toolbar", "statusbar", "sideBySide"]) {
|
||||||
$("#markdown-preview").parent().addClass("form-tab-selected");
|
if (this.editor.gui[item]) {
|
||||||
|
wrapper.parentNode.removeChild(this.editor.gui[item]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var request = $.ajax({
|
cm.toTextArea();
|
||||||
url: $("body").data("markdown-preview-url"),
|
this.editor = null;
|
||||||
contentType: "application/json",
|
};
|
||||||
type: "POST",
|
|
||||||
processData: false,
|
|
||||||
dataType: "html",
|
|
||||||
data: JSON.stringify({
|
|
||||||
"text": textarea.val()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
request.done(function(data) {
|
Kanboard.Markdown.prototype.show = function(textarea) {
|
||||||
preview.find(".markdown").html(data)
|
var toolbar = ["bold", "italic", "strikethrough", "heading", "|", "unordered-list", "ordered-list", "link", "|", "code", "table"];
|
||||||
preview.css("height", textarea.css("height"));
|
|
||||||
preview.css("width", textarea.css("width"));
|
|
||||||
|
|
||||||
write.hide();
|
this.editor = new SimpleMDE({
|
||||||
preview.show();
|
element: textarea,
|
||||||
|
status: false,
|
||||||
|
toolbarTips: false,
|
||||||
|
autoDownloadFontAwesome: false,
|
||||||
|
spellChecker: false,
|
||||||
|
autosave: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
forceSync: true,
|
||||||
|
blockStyles: {
|
||||||
|
italic: "_"
|
||||||
|
},
|
||||||
|
toolbar: textarea.hasAttribute("data-markdown-editor-disable-toolbar") ? false : toolbar,
|
||||||
|
placeholder: textarea.getAttribute("placeholder")
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Markdown.prototype.showWriter = function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
$("#markdown-write").parent().addClass("form-tab-selected");
|
|
||||||
$("#markdown-preview").parent().removeClass("form-tab-selected");
|
|
||||||
|
|
||||||
$(".write-area").show();
|
|
||||||
$(".preview-area").hide();
|
|
||||||
};
|
|
||||||
|
|
||||||
Markdown.prototype.listen = function() {
|
|
||||||
$(document).on("click", "#markdown-preview", this.showPreview.bind(this));
|
|
||||||
$(document).on("click", "#markdown-write", this.showWriter.bind(this));
|
|
||||||
};
|
|
||||||
|
|||||||
3
assets/js/src/Namespace.js
Normal file
3
assets/js/src/Namespace.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Kanboard = {};
|
||||||
9
assets/js/src/Notification.js
Normal file
9
assets/js/src/Notification.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Kanboard.Notification = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Notification.prototype.execute = function() {
|
||||||
|
$(".alert-fade-out").delay(4000).fadeOut(800, function() {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,35 +1,28 @@
|
|||||||
function Popover(app) {
|
Kanboard.Popover = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.router = new Router();
|
|
||||||
this.router.addRoute('screenshot-zone', Screenshot);
|
|
||||||
}
|
|
||||||
|
|
||||||
Popover.prototype.isOpen = function() {
|
|
||||||
return $('#popover-container').size() > 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Popover.prototype.open = function(link) {
|
Kanboard.Popover.prototype.listen = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.app.dropdown.close();
|
|
||||||
|
|
||||||
$.get(link, function(content) {
|
$(document).on("click", ".popover", function(e) {
|
||||||
$("body").prepend('<div id="popover-container"><div id="popover-content">' + content + '</div></div>');
|
self.onClick(e);
|
||||||
self.afterOpen();
|
});
|
||||||
|
|
||||||
|
$(document).on("click", ".close-popover", function(e) {
|
||||||
|
self.close(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", "#popover-container", function(e) {
|
||||||
|
self.close(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", "#popover-content", function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Popover.prototype.close = function(e) {
|
Kanboard.Popover.prototype.onClick = function(e) {
|
||||||
if (this.isOpen()) {
|
|
||||||
|
|
||||||
if (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#popover-container').remove();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Popover.prototype.onClick = function(e) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
@@ -45,20 +38,69 @@ Popover.prototype.onClick = function(e) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Popover.prototype.listen = function() {
|
Kanboard.Popover.prototype.isOpen = function() {
|
||||||
$(document).on("click", ".popover", this.onClick.bind(this));
|
return $('#popover-container').size() > 0;
|
||||||
$(document).on("click", ".close-popover", this.close.bind(this));
|
|
||||||
$(document).on("click", "#popover-container", this.close.bind(this));
|
|
||||||
$(document).on("click", "#popover-content", function(e) { e.stopPropagation(); });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Popover.prototype.afterOpen = function() {
|
Kanboard.Popover.prototype.open = function(link) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
$.get(link, function(content) {
|
||||||
|
$("body").prepend('<div id="popover-container"><div id="popover-content">' + content + '</div></div>');
|
||||||
|
self.executeOnOpenedListeners();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Popover.prototype.close = function(e) {
|
||||||
|
if (this.isOpen()) {
|
||||||
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#popover-container").remove();
|
||||||
|
this.executeOnClosedListeners();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Popover.prototype.ajaxReload = function(data, request, self) {
|
||||||
|
var redirect = request.getResponseHeader("X-Ajax-Redirect");
|
||||||
|
|
||||||
|
if (redirect) {
|
||||||
|
window.location = redirect === 'self' ? window.location.href.split("#")[0] : redirect;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#popover-content").html(data);
|
||||||
|
$("#popover-content input[autofocus]").focus();
|
||||||
|
self.executeOnOpenedListeners();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Popover.prototype.executeOnOpenedListeners = function() {
|
||||||
|
for (var className in this.app.controllers) {
|
||||||
|
var controller = this.app.get(className);
|
||||||
|
|
||||||
|
if (typeof controller.onPopoverOpened === "function") {
|
||||||
|
controller.onPopoverOpened();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.afterOpen();
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Popover.prototype.executeOnClosedListeners = function() {
|
||||||
|
for (var className in this.app.controllers) {
|
||||||
|
var controller = this.app.get(className);
|
||||||
|
|
||||||
|
if (typeof controller.onPopoverClosed === "function") {
|
||||||
|
controller.onPopoverClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Popover.prototype.afterOpen = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var popoverForm = $("#popover-content .popover-form");
|
var popoverForm = $("#popover-content .popover-form");
|
||||||
|
|
||||||
self.app.refresh();
|
|
||||||
self.router.dispatch(this.app);
|
|
||||||
|
|
||||||
// Submit forms with Ajax request
|
// Submit forms with Ajax request
|
||||||
if (popoverForm) {
|
if (popoverForm) {
|
||||||
popoverForm.on("submit", function(e) {
|
popoverForm.on("submit", function(e) {
|
||||||
@@ -69,7 +111,7 @@ Popover.prototype.afterOpen = function() {
|
|||||||
url: popoverForm.attr("action"),
|
url: popoverForm.attr("action"),
|
||||||
data: popoverForm.serialize(),
|
data: popoverForm.serialize(),
|
||||||
success: function(data, textStatus, request) {
|
success: function(data, textStatus, request) {
|
||||||
self.afterSubmit(data, request, self);
|
self.ajaxReload(data, request, self);
|
||||||
},
|
},
|
||||||
beforeSend: function() {
|
beforeSend: function() {
|
||||||
var button = $('.popover-form button[type="submit"]');
|
var button = $('.popover-form button[type="submit"]');
|
||||||
@@ -88,21 +130,16 @@ Popover.prototype.afterOpen = function() {
|
|||||||
type: "GET",
|
type: "GET",
|
||||||
url: $(this).attr("href"),
|
url: $(this).attr("href"),
|
||||||
success: function(data, textStatus, request) {
|
success: function(data, textStatus, request) {
|
||||||
self.afterSubmit(data, request, self);
|
self.ajaxReload(data, request, self);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
Popover.prototype.afterSubmit = function(data, request, self) {
|
// Autofocus fields (html5 autofocus works only with page onload)
|
||||||
var redirect = request.getResponseHeader("X-Ajax-Redirect");
|
$("[autofocus]").each(function() {
|
||||||
|
$(this).focus();
|
||||||
|
});
|
||||||
|
|
||||||
if (redirect) {
|
this.app.datePicker();
|
||||||
window.location = redirect === 'self' ? window.location.href.split("#")[0] : redirect;
|
this.app.autoComplete();
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("#popover-content").html(data);
|
|
||||||
$("#popover-content input[autofocus]").focus();
|
|
||||||
self.afterOpen();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
function Project() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Project.prototype.listen = function() {
|
|
||||||
$('.project-change-role').on('change', function() {
|
|
||||||
$.ajax({
|
|
||||||
cache: false,
|
|
||||||
url: $(this).data('url'),
|
|
||||||
contentType: "application/json",
|
|
||||||
type: "POST",
|
|
||||||
processData: false,
|
|
||||||
data: JSON.stringify({
|
|
||||||
"id": $(this).data('id'),
|
|
||||||
"role": $(this).val()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#project-creation-form #form-src_project_id').on('change', function() {
|
|
||||||
var srcProjectId = $(this).val();
|
|
||||||
|
|
||||||
if (srcProjectId == 0) {
|
|
||||||
$(".project-creation-options").hide();
|
|
||||||
} else {
|
|
||||||
$(".project-creation-options").show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
15
assets/js/src/ProjectCreation.js
Normal file
15
assets/js/src/ProjectCreation.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Kanboard.ProjectCreation = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.ProjectCreation.prototype.onPopoverOpened = function() {
|
||||||
|
$('#project-creation-form #form-src_project_id').on('change', function() {
|
||||||
|
var srcProjectId = $(this).val();
|
||||||
|
|
||||||
|
if (srcProjectId == 0) {
|
||||||
|
$(".project-creation-options").hide();
|
||||||
|
} else {
|
||||||
|
$(".project-creation-options").show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
19
assets/js/src/ProjectPermission.js
Normal file
19
assets/js/src/ProjectPermission.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Kanboard.ProjectPermission = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.ProjectPermission.prototype.listen = function() {
|
||||||
|
$('.project-change-role').on('change', function () {
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
url: $(this).data('url'),
|
||||||
|
contentType: "application/json",
|
||||||
|
type: "POST",
|
||||||
|
processData: false,
|
||||||
|
data: JSON.stringify({
|
||||||
|
"id": $(this).data('id'),
|
||||||
|
"role": $(this).val()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
function Router() {
|
|
||||||
this.routes = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Router.prototype.addRoute = function(id, controller) {
|
|
||||||
this.routes[id] = controller;
|
|
||||||
};
|
|
||||||
|
|
||||||
Router.prototype.dispatch = function(app) {
|
|
||||||
for (var id in this.routes) {
|
|
||||||
if (document.getElementById(id)) {
|
|
||||||
var controller = Object.create(this.routes[id].prototype);
|
|
||||||
this.routes[id].apply(controller, [app]);
|
|
||||||
controller.execute();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
jQuery(document).ready(function() {
|
|
||||||
var app = new App();
|
|
||||||
var router = new Router();
|
|
||||||
router.addRoute('board', Board);
|
|
||||||
router.addRoute('calendar', Calendar);
|
|
||||||
router.addRoute('screenshot-zone', Screenshot);
|
|
||||||
router.addRoute('analytic-task-repartition', TaskRepartitionChart);
|
|
||||||
router.addRoute('analytic-user-repartition', UserRepartitionChart);
|
|
||||||
router.addRoute('analytic-cfd', CumulativeFlowDiagram);
|
|
||||||
router.addRoute('analytic-burndown', BurndownChart);
|
|
||||||
router.addRoute('analytic-avg-time-column', AvgTimeColumnChart);
|
|
||||||
router.addRoute('analytic-task-time-column', TaskTimeColumnChart);
|
|
||||||
router.addRoute('analytic-lead-cycle-time', LeadCycleTimeChart);
|
|
||||||
router.addRoute('analytic-compare-hours', CompareHoursColumnChart);
|
|
||||||
router.addRoute('gantt-chart', Gantt);
|
|
||||||
router.dispatch(app);
|
|
||||||
app.listen();
|
|
||||||
});
|
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
function Screenshot() {
|
Kanboard.Screenshot = function(app) {
|
||||||
|
this.app = app;
|
||||||
this.pasteCatcher = null;
|
this.pasteCatcher = null;
|
||||||
}
|
};
|
||||||
|
|
||||||
Screenshot.prototype.execute = function() {
|
Kanboard.Screenshot.prototype.onPopoverOpened = function() {
|
||||||
|
if (this.app.hasId("screenshot-zone")) {
|
||||||
this.initialize();
|
this.initialize();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup event listener and workarounds
|
// Setup event listener and workarounds
|
||||||
Screenshot.prototype.initialize = function() {
|
Kanboard.Screenshot.prototype.initialize = function() {
|
||||||
this.destroy();
|
this.destroy();
|
||||||
|
|
||||||
if (! window.Clipboard) {
|
if (! window.Clipboard) {
|
||||||
@@ -40,7 +43,7 @@ Screenshot.prototype.initialize = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Destroy contentEditable element
|
// Destroy contentEditable element
|
||||||
Screenshot.prototype.destroy = function() {
|
Kanboard.Screenshot.prototype.destroy = function() {
|
||||||
if (this.pasteCatcher != null) {
|
if (this.pasteCatcher != null) {
|
||||||
document.body.removeChild(this.pasteCatcher);
|
document.body.removeChild(this.pasteCatcher);
|
||||||
}
|
}
|
||||||
@@ -53,14 +56,14 @@ Screenshot.prototype.destroy = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Set focus on contentEditable element
|
// Set focus on contentEditable element
|
||||||
Screenshot.prototype.setFocus = function() {
|
Kanboard.Screenshot.prototype.setFocus = function() {
|
||||||
if (this.pasteCatcher !== null) {
|
if (this.pasteCatcher !== null) {
|
||||||
this.pasteCatcher.focus();
|
this.pasteCatcher.focus();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Paste event callback
|
// Paste event callback
|
||||||
Screenshot.prototype.pasteHandler = function(e) {
|
Kanboard.Screenshot.prototype.pasteHandler = function(e) {
|
||||||
// Firefox doesn't have the property e.clipboardData.items (only Chrome)
|
// Firefox doesn't have the property e.clipboardData.items (only Chrome)
|
||||||
if (e.clipboardData && e.clipboardData.items) {
|
if (e.clipboardData && e.clipboardData.items) {
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ Screenshot.prototype.pasteHandler = function(e) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Parse the input in the paste catcher element
|
// Parse the input in the paste catcher element
|
||||||
Screenshot.prototype.checkInput = function() {
|
Kanboard.Screenshot.prototype.checkInput = function() {
|
||||||
var child = this.pasteCatcher.childNodes[0];
|
var child = this.pasteCatcher.childNodes[0];
|
||||||
|
|
||||||
if (child) {
|
if (child) {
|
||||||
@@ -110,7 +113,7 @@ Screenshot.prototype.checkInput = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Creates a new image from a given source
|
// Creates a new image from a given source
|
||||||
Screenshot.prototype.createImage = function(blob) {
|
Kanboard.Screenshot.prototype.createImage = function(blob) {
|
||||||
var pastedImage = new Image();
|
var pastedImage = new Image();
|
||||||
pastedImage.src = blob;
|
pastedImage.src = blob;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
function Search(app) {
|
Kanboard.Search = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.keyboardShortcuts();
|
};
|
||||||
}
|
|
||||||
|
Kanboard.Search.prototype.focus = function() {
|
||||||
|
|
||||||
Search.prototype.focus = function() {
|
|
||||||
// Place cursor at the end when focusing on the search box
|
// Place cursor at the end when focusing on the search box
|
||||||
$(document).on("focus", "#form-search", function() {
|
$(document).on("focus", "#form-search", function() {
|
||||||
if ($("#form-search")[0].setSelectionRange) {
|
var input = $("#form-search");
|
||||||
$('#form-search')[0].setSelectionRange($('#form-search').val().length, $('#form-search').val().length);
|
|
||||||
|
if (input[0].setSelectionRange) {
|
||||||
|
var len = input.val().length * 2;
|
||||||
|
input[0].setSelectionRange(len, len);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Search.prototype.listen = function() {
|
Kanboard.Search.prototype.listen = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Filter helper for search
|
// Filter helper for search
|
||||||
@@ -21,68 +24,51 @@ Search.prototype.listen = function() {
|
|||||||
|
|
||||||
var filter = $(this).data("filter");
|
var filter = $(this).data("filter");
|
||||||
var appendFilter = $(this).data("append-filter");
|
var appendFilter = $(this).data("append-filter");
|
||||||
|
var input = $("#form-search");
|
||||||
|
|
||||||
if (appendFilter) {
|
if (appendFilter) {
|
||||||
filter = $("#form-search").val() + " " + appendFilter;
|
filter = input.val() + " " + appendFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#form-search").val(filter);
|
input.val(filter);
|
||||||
|
|
||||||
if ($('#board').length) {
|
|
||||||
self.app.board.reloadFilters(filter);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("form.search").submit();
|
$("form.search").submit();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Search.prototype.keyboardShortcuts = function() {
|
Kanboard.Search.prototype.goToView = function(label) {
|
||||||
|
var link = $(label);
|
||||||
|
|
||||||
|
if (link.length) {
|
||||||
|
window.location = link.attr('href');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Search.prototype.keyboardShortcuts = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// Switch view mode for projects: go to the overview page
|
// Switch view mode for projects: go to the overview page
|
||||||
Mousetrap.bind("v o", function(e) {
|
Mousetrap.bind("v o", function() {
|
||||||
var link = $(".view-overview");
|
self.goToView(".view-overview");
|
||||||
|
|
||||||
if (link.length) {
|
|
||||||
window.location = link.attr('href');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Switch view mode for projects: go to the board
|
// Switch view mode for projects: go to the board
|
||||||
Mousetrap.bind("v b", function(e) {
|
Mousetrap.bind("v b", function() {
|
||||||
var link = $(".view-board");
|
self.goToView(".view-board");
|
||||||
|
|
||||||
if (link.length) {
|
|
||||||
window.location = link.attr('href');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Switch view mode for projects: go to the calendar
|
// Switch view mode for projects: go to the calendar
|
||||||
Mousetrap.bind("v c", function(e) {
|
Mousetrap.bind("v c", function() {
|
||||||
var link = $(".view-calendar");
|
self.goToView(".view-calendar");
|
||||||
|
|
||||||
if (link.length) {
|
|
||||||
window.location = link.attr('href');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Switch view mode for projects: go to the listing
|
// Switch view mode for projects: go to the listing
|
||||||
Mousetrap.bind("v l", function(e) {
|
Mousetrap.bind("v l", function() {
|
||||||
var link = $(".view-listing");
|
self.goToView(".view-listing");
|
||||||
|
|
||||||
if (link.length) {
|
|
||||||
window.location = link.attr('href');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Switch view mode for projects: go to the gantt chart
|
// Switch view mode for projects: go to the gantt chart
|
||||||
Mousetrap.bind("v g", function(e) {
|
Mousetrap.bind("v g", function() {
|
||||||
var link = $(".view-gantt");
|
self.goToView(".view-gantt");
|
||||||
|
|
||||||
if (link.length) {
|
|
||||||
window.location = link.attr('href');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Focus to the search field
|
// Focus to the search field
|
||||||
@@ -99,14 +85,9 @@ Search.prototype.keyboardShortcuts = function() {
|
|||||||
Mousetrap.bind("r", function(e) {
|
Mousetrap.bind("r", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var reset = $(".filter-reset").data("filter");
|
var reset = $(".filter-reset").data("filter");
|
||||||
|
var input = $("#form-search");
|
||||||
|
|
||||||
$("#form-search").val(reset);
|
input.val(reset);
|
||||||
|
|
||||||
if ($('#board').length) {
|
|
||||||
self.app.board.reloadFilters(reset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$("form.search").submit();
|
$("form.search").submit();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
21
assets/js/src/Session.js
Normal file
21
assets/js/src/Session.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Kanboard.Session = function(app) {
|
||||||
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Session.prototype.execute = function() {
|
||||||
|
window.setInterval(this.checkSession, 60000);
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Session.prototype.checkSession = function() {
|
||||||
|
if (! $(".form-login").length) {
|
||||||
|
$.ajax({
|
||||||
|
cache: false,
|
||||||
|
url: $("body").data("status-url"),
|
||||||
|
statusCode: {
|
||||||
|
401: function() {
|
||||||
|
window.location = $("body").data("login-url");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
function Subtask(app) {
|
Kanboard.Subtask = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
Subtask.prototype.listen = function() {
|
Kanboard.Subtask.prototype.listen = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.dragAndDrop();
|
this.dragAndDrop();
|
||||||
|
|
||||||
$(document).on("click", ".subtask-toggle-status", function(e) {
|
$(document).on("click", ".subtask-toggle-status", function(e) {
|
||||||
e.preventDefault();
|
|
||||||
var el = $(this);
|
var el = $(this);
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
cache: false,
|
cache: false,
|
||||||
@@ -27,8 +26,8 @@ Subtask.prototype.listen = function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
$(document).on("click", ".subtask-toggle-timer", function(e) {
|
$(document).on("click", ".subtask-toggle-timer", function(e) {
|
||||||
e.preventDefault();
|
|
||||||
var el = $(this);
|
var el = $(this);
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
cache: false,
|
cache: false,
|
||||||
@@ -41,7 +40,7 @@ Subtask.prototype.listen = function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Subtask.prototype.dragAndDrop = function() {
|
Kanboard.Subtask.prototype.dragAndDrop = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$(".draggable-row-handle").mouseenter(function() {
|
$(".draggable-row-handle").mouseenter(function() {
|
||||||
@@ -71,7 +70,7 @@ Subtask.prototype.dragAndDrop = function() {
|
|||||||
}).disableSelection();
|
}).disableSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
Subtask.prototype.savePosition = function(subtaskId, position) {
|
Kanboard.Subtask.prototype.savePosition = function(subtaskId, position) {
|
||||||
var url = $(".subtasks-table").data("save-position-url");
|
var url = $(".subtasks-table").data("save-position-url");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|||||||
@@ -1,60 +1,15 @@
|
|||||||
function Swimlane(app) {
|
Kanboard.Swimlane = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
|
||||||
|
|
||||||
Swimlane.prototype.getStorageKey = function() {
|
|
||||||
return "hidden_swimlanes_" + $("#board").data("project-id");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Swimlane.prototype.expand = function(swimlaneId) {
|
Kanboard.Swimlane.prototype.execute = function() {
|
||||||
var swimlaneIds = this.getAllCollapsed();
|
if ($(".swimlanes-table").length) {
|
||||||
var index = swimlaneIds.indexOf(swimlaneId);
|
this.dragAndDrop();
|
||||||
|
|
||||||
if (index > -1) {
|
|
||||||
swimlaneIds.splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem(this.getStorageKey(), JSON.stringify(swimlaneIds));
|
|
||||||
|
|
||||||
$('.board-swimlane-columns-' + swimlaneId).css('display', 'table-row');
|
|
||||||
$('.board-swimlane-tasks-' + swimlaneId).css('display', 'table-row');
|
|
||||||
$('.hide-icon-swimlane-' + swimlaneId).css('display', 'inline');
|
|
||||||
$('.show-icon-swimlane-' + swimlaneId).css('display', 'none');
|
|
||||||
};
|
|
||||||
|
|
||||||
Swimlane.prototype.collapse = function(swimlaneId) {
|
|
||||||
var swimlaneIds = this.getAllCollapsed();
|
|
||||||
|
|
||||||
if (swimlaneIds.indexOf(swimlaneId) < 0) {
|
|
||||||
swimlaneIds.push(swimlaneId);
|
|
||||||
localStorage.setItem(this.getStorageKey(), JSON.stringify(swimlaneIds));
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.board-swimlane-columns-' + swimlaneId + ':not(:first-child)').css('display', 'none');
|
|
||||||
$('.board-swimlane-tasks-' + swimlaneId).css('display', 'none');
|
|
||||||
$('.hide-icon-swimlane-' + swimlaneId).css('display', 'none');
|
|
||||||
$('.show-icon-swimlane-' + swimlaneId).css('display', 'inline');
|
|
||||||
};
|
|
||||||
|
|
||||||
Swimlane.prototype.isCollapsed = function(swimlaneId) {
|
|
||||||
return this.getAllCollapsed().indexOf(swimlaneId) > -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
Swimlane.prototype.getAllCollapsed = function() {
|
|
||||||
return JSON.parse(localStorage.getItem(this.getStorageKey())) || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
Swimlane.prototype.refresh = function() {
|
|
||||||
var swimlaneIds = this.getAllCollapsed();
|
|
||||||
|
|
||||||
for (var i = 0; i < swimlaneIds.length; i++) {
|
|
||||||
this.collapse(swimlaneIds[i]);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Swimlane.prototype.listen = function() {
|
Kanboard.Swimlane.prototype.listen = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.dragAndDrop();
|
|
||||||
|
|
||||||
$(document).on('click', ".board-swimlane-toggle", function(e) {
|
$(document).on('click', ".board-swimlane-toggle", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -70,7 +25,57 @@ Swimlane.prototype.listen = function() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Swimlane.prototype.dragAndDrop = function() {
|
Kanboard.Swimlane.prototype.onBoardRendered = function() {
|
||||||
|
var swimlaneIds = this.getAllCollapsed();
|
||||||
|
|
||||||
|
for (var i = 0; i < swimlaneIds.length; i++) {
|
||||||
|
this.collapse(swimlaneIds[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Swimlane.prototype.getStorageKey = function() {
|
||||||
|
return "hidden_swimlanes_" + $("#board").data("project-id");
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Swimlane.prototype.expand = function(swimlaneId) {
|
||||||
|
var swimlaneIds = this.getAllCollapsed();
|
||||||
|
var index = swimlaneIds.indexOf(swimlaneId);
|
||||||
|
|
||||||
|
if (index > -1) {
|
||||||
|
swimlaneIds.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(this.getStorageKey(), JSON.stringify(swimlaneIds));
|
||||||
|
|
||||||
|
$('.board-swimlane-columns-' + swimlaneId).css('display', 'table-row');
|
||||||
|
$('.board-swimlane-tasks-' + swimlaneId).css('display', 'table-row');
|
||||||
|
$('.hide-icon-swimlane-' + swimlaneId).css('display', 'inline');
|
||||||
|
$('.show-icon-swimlane-' + swimlaneId).css('display', 'none');
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Swimlane.prototype.collapse = function(swimlaneId) {
|
||||||
|
var swimlaneIds = this.getAllCollapsed();
|
||||||
|
|
||||||
|
if (swimlaneIds.indexOf(swimlaneId) < 0) {
|
||||||
|
swimlaneIds.push(swimlaneId);
|
||||||
|
localStorage.setItem(this.getStorageKey(), JSON.stringify(swimlaneIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.board-swimlane-columns-' + swimlaneId + ':not(:first-child)').css('display', 'none');
|
||||||
|
$('.board-swimlane-tasks-' + swimlaneId).css('display', 'none');
|
||||||
|
$('.hide-icon-swimlane-' + swimlaneId).css('display', 'none');
|
||||||
|
$('.show-icon-swimlane-' + swimlaneId).css('display', 'inline');
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Swimlane.prototype.isCollapsed = function(swimlaneId) {
|
||||||
|
return this.getAllCollapsed().indexOf(swimlaneId) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Swimlane.prototype.getAllCollapsed = function() {
|
||||||
|
return JSON.parse(localStorage.getItem(this.getStorageKey())) || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.Swimlane.prototype.dragAndDrop = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
$(".draggable-row-handle").mouseenter(function() {
|
$(".draggable-row-handle").mouseenter(function() {
|
||||||
@@ -100,7 +105,7 @@ Swimlane.prototype.dragAndDrop = function() {
|
|||||||
}).disableSelection();
|
}).disableSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
Swimlane.prototype.savePosition = function(swimlaneId, position) {
|
Kanboard.Swimlane.prototype.savePosition = function(swimlaneId, position) {
|
||||||
var url = $(".swimlanes-table").data("save-position-url");
|
var url = $(".swimlanes-table").data("save-position-url");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
function Task(app) {
|
Kanboard.Task = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
Task.prototype.keyboardShortcuts = function() {
|
Kanboard.Task.prototype.keyboardShortcuts = function() {
|
||||||
var taskView = $("#task-view");
|
var taskView = $("#task-view");
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (taskView.length) {
|
if (this.app.hasId("task-view")) {
|
||||||
Mousetrap.bind("e", function() {
|
Mousetrap.bind("e", function() {
|
||||||
self.app.popover.open(taskView.data("edit-url"));
|
self.app.get("Popover").open(taskView.data("edit-url"));
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind("c", function() {
|
Mousetrap.bind("c", function() {
|
||||||
self.app.popover.open(taskView.data("comment-url"));
|
self.app.get("Popover").open(taskView.data("comment-url"));
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind("s", function() {
|
Mousetrap.bind("s", function() {
|
||||||
self.app.popover.open(taskView.data("subtask-url"));
|
self.app.get("Popover").open(taskView.data("subtask-url"));
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind("l", function() {
|
Mousetrap.bind("l", function() {
|
||||||
self.app.popover.open(taskView.data("internal-link-url"));
|
self.app.get("Popover").open(taskView.data("internal-link-url"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Task.prototype.listen = function() {
|
Kanboard.Task.prototype.onPopoverOpened = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var reloadingProjectId = 0;
|
var reloadingProjectId = 0;
|
||||||
|
|
||||||
@@ -38,11 +38,11 @@ Task.prototype.listen = function() {
|
|||||||
|
|
||||||
// Assign to me
|
// Assign to me
|
||||||
$(document).on("click", ".assign-me", function(e) {
|
$(document).on("click", ".assign-me", function(e) {
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var currentId = $(this).data("current-id");
|
var currentId = $(this).data("current-id");
|
||||||
var dropdownId = "#" + $(this).data("target-id");
|
var dropdownId = "#" + $(this).data("target-id");
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
if ($(dropdownId + ' option[value=' + currentId + ']').length) {
|
if ($(dropdownId + ' option[value=' + currentId + ']').length) {
|
||||||
$(dropdownId).val(currentId);
|
$(dropdownId).val(currentId);
|
||||||
}
|
}
|
||||||
@@ -65,8 +65,7 @@ Task.prototype.listen = function() {
|
|||||||
success: function(data, textStatus, request) {
|
success: function(data, textStatus, request) {
|
||||||
reloadingProjectId = 0;
|
reloadingProjectId = 0;
|
||||||
$(".loading-icon").hide();
|
$(".loading-icon").hide();
|
||||||
|
self.app.get("Popover").ajaxReload(data, request, self.app.get("Popover"));
|
||||||
self.app.popover.afterSubmit(data, request, self.app.popover);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
function TaskRepartitionChart() {
|
Kanboard.TaskRepartitionChart = function(app) {
|
||||||
}
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
TaskRepartitionChart.prototype.execute = function() {
|
Kanboard.TaskRepartitionChart.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("analytic-task-repartition")) {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.TaskRepartitionChart.prototype.show = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
var metrics = $("#chart").data("metrics");
|
||||||
var columns = [];
|
var columns = [];
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
function TaskTimeColumnChart(app) {
|
Kanboard.TaskTimeColumnChart = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
TaskTimeColumnChart.prototype.execute = function() {
|
Kanboard.TaskTimeColumnChart.prototype.execute = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
if (this.app.hasId("analytic-task-time-column")) {
|
||||||
var plots = [$("#chart").data("label")];
|
this.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.TaskTimeColumnChart.prototype.show = function() {
|
||||||
|
var chart = $("#chart");
|
||||||
|
var metrics = chart.data("metrics");
|
||||||
|
var plots = [chart.data("label")];
|
||||||
var categories = [];
|
var categories = [];
|
||||||
|
|
||||||
for (var i = 0; i < metrics.length; i++) {
|
for (var i = 0; i < metrics.length; i++) {
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
function Tooltip(app) {
|
Kanboard.Tooltip = function(app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
};
|
||||||
|
|
||||||
Tooltip.prototype.listen = function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
|
Kanboard.Tooltip.prototype.execute = function() {
|
||||||
$(".tooltip").tooltip({
|
$(".tooltip").tooltip({
|
||||||
track: false,
|
track: false,
|
||||||
show: false,
|
show: false,
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
function UserRepartitionChart() {
|
Kanboard.UserRepartitionChart = function(app) {
|
||||||
}
|
this.app = app;
|
||||||
|
};
|
||||||
|
|
||||||
UserRepartitionChart.prototype.execute = function() {
|
Kanboard.UserRepartitionChart.prototype.execute = function() {
|
||||||
|
if (this.app.hasId("analytic-user-repartition")) {
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Kanboard.UserRepartitionChart.prototype.show = function() {
|
||||||
var metrics = $("#chart").data("metrics");
|
var metrics = $("#chart").data("metrics");
|
||||||
var columns = [];
|
var columns = [];
|
||||||
|
|
||||||
|
|||||||
4
assets/js/src/bootstrap.js
vendored
Normal file
4
assets/js/src/bootstrap.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
jQuery(document).ready(function() {
|
||||||
|
var app = new Kanboard.App();
|
||||||
|
app.execute();
|
||||||
|
});
|
||||||
1227
assets/js/vendor/jquery.textcomplete.js
vendored
1227
assets/js/vendor/jquery.textcomplete.js
vendored
File diff suppressed because it is too large
Load Diff
14
assets/js/vendor/simplemde.min.js
vendored
Normal file
14
assets/js/vendor/simplemde.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user