diff --git a/module/testcase/css/create.css b/module/testcase/css/create.css
index 5fb0c33927..c865a87647 100644
--- a/module/testcase/css/create.css
+++ b/module/testcase/css/create.css
@@ -35,3 +35,23 @@
.colorpicker.input-group-btn > .btn {border-right: none}
#branch {border-left-width: 0px;}
+
+#steps .step-id {text-align: right}
+#steps .step-child-id {background-color: transparent; border: none; display: none; width: 30px; padding-left: 0; padding-right: 0; text-align: right; padding-right: 8px}
+#steps .checkbox-inline input[type="checkbox"] {top: -2px}
+#steps .btn-group .btn {padding-left: 0; padding-right: 0; min-width: 30px;}
+#steps .step-actions {width: 98px;}
+#steps .active td {transition: background-color .5s;}
+#steps .step-group .step-steps {resize: none; max-height: 30px;}
+#steps .step-group .step-expects {display: none;}
+#steps .step-child .step-child-id {display: table-cell;}
+#steps .step-child .step-id {color: transparent}
+
+#steps .btn-step-move {cursor: move}
+#steps.sortable > tr.drag-shadow {display: none}
+#steps.sortable-sorting > tr {transition: all .2s; position: relative; z-index: 5; opacity: .3;}
+#steps.sortable-sorting {cursor: move;}
+#steps.sortable-sorting > tr.drag-row {opacity: 1; z-index: 10; box-shadow: 0 2px 4px red}
+#steps.sortable-sorting > tr.drag-row + tr > td {box-shadow: inset 0 4px 2px rgba(0,0,0,.2)}
+#steps.sortable-sorting > tr.drag-row > td {background-color: #edf3fe!important}
+#steps.sortable > tr.drop-success > td {background-color: #cfe0ff; transition: background-color 2s;}
diff --git a/module/testcase/js/create.js b/module/testcase/js/create.js
index 6b33c30543..fcd8b6c608 100644
--- a/module/testcase/js/create.js
+++ b/module/testcase/js/create.js
@@ -15,20 +15,100 @@ function setPreview()
}
}
-function createRow()
+function initSteps()
{
- if(newRowID == 0) newRowID = $('.stepID').size();
- newRowID ++;
- var newRow = "
";
- newRow += " | ";
- newRow += " | ";
- newRow += " | ";
- newRow += "";
- newRow += "";
- newRow += "";
- newRow += "";
- newRow += " | ";
- return newRow;
+ if(navigator.userAgent.indexOf("Firefox") < 0)
+ {
+ $(document).on('input keyup paste change', 'textarea.autosize', function()
+ {
+ this.style.height = 'auto';
+ this.style.height = (this.scrollHeight + 2) + "px";
+ });
+ }
+ var $steps = $('#steps');
+ var $stepTemplate = $('#stepTemplate').detach().removeClass('template').attr('id', null);
+ var initSortableCallTask = null;
+ var groupNameText = $steps.data('groupName');
+ var insertStepRow = function($row, count)
+ {
+ if(count === undefined) count = 1;
+ for(var i = 0; i < count; ++i)
+ {
+ var $step = $stepTemplate.clone();
+ if($row) $row.after($step);
+ else $steps.append($step);
+ $step.addClass('step-new');
+ }
+ };
+ var toggleStepRowType = function($row, toggleisGroup)
+ {
+ if(toggleisGroup === undefined) targetIsGroup = $row.find('.step-type').is(':checked');
+ $row.toggleClass('step-group', targetIsGroup);
+ $row.find('.step-steps').toggleClass('autosize', !targetIsGroup).attr('placeholder', targetIsGroup ? groupNameText : null).focus();
+ };
+ var refreshStepsID = function()
+ {
+ var parentId = 1, childId = 0;
+ $steps.children('.step:not(.drag-shadow)').each(function(idx)
+ {
+ var $step = $(this);
+ var isGroup = $step.find('.step-type').is(':checked');
+ var stepID;
+ if(isGroup || !childId)
+ {
+ $step.removeClass('step-child');
+ stepID = parentId++;
+ $step.find('.step-id').text(stepID);
+ if(isGroup) childId = 1;
+ }
+ else
+ {
+ stepID = (parentId - 1) + '.' + (childId++);
+ $step.addClass('step-child').find('.step-child-id').text(stepID);
+ }
+ $step.find('.step-id-control').val(stepID);
+ });
+ };
+ var initSortable = function()
+ {
+ clearTimeout(initSortableCallTask);
+ initSortableCallTask = setTimeout(function()
+ {
+ var $oldSteps = $steps.children('.step');
+ var $newSteps = $oldSteps.clone();
+ $oldSteps.remove();
+ $steps.append($newSteps);
+ $steps.sortable(
+ {
+ selector: 'tr.step',
+ dragCssClass: 'drag-row',
+ trigger: '.btn-step-move',
+ finish: function(e)
+ {
+ e.element.addClass('drop-success');
+ setTimeout(function(){$steps.find('.drop-success').removeClass('drop-success');}, 800);
+ refreshStepsID();
+ }
+ });
+ $steps.children('.step-new').removeClass('step-new').last().find('textarea:first').focus();
+ }, 100);
+ }
+ $steps.on('click', '.btn-step-add', function()
+ {
+ insertStepRow($(this).closest('.step'));
+ initSortable();
+ refreshStepsID();
+ }).on('click', '.btn-step-delete', function()
+ {
+ $(this).closest('.step').remove();
+ refreshStepsID();
+ }).on('change', '.step-type', function()
+ {
+ toggleStepRowType($(this).closest('.step'));
+ refreshStepsID();
+ });
+ initSortable();
+ refreshStepsID();
}
$(function()
@@ -176,4 +256,6 @@ $(function()
}
return false;
});
+
+ initSteps();
})
diff --git a/module/testcase/lang/en.php b/module/testcase/lang/en.php
index 481359aee4..7727756226 100644
--- a/module/testcase/lang/en.php
+++ b/module/testcase/lang/en.php
@@ -77,6 +77,7 @@ $lang->testcase->export = "Export Data";
$lang->testcase->confirmChange = 'Confirm Case Change';
$lang->testcase->confirmStoryChange = 'Confirm Story Change';
$lang->testcase->copy = 'Duplicate Case';
+$lang->testcase->group = 'Group';
$lang->testcase->new = 'New';
diff --git a/module/testcase/lang/zh-cn.php b/module/testcase/lang/zh-cn.php
index ef6db81af1..c46dfc4851 100644
--- a/module/testcase/lang/zh-cn.php
+++ b/module/testcase/lang/zh-cn.php
@@ -79,6 +79,8 @@ $lang->testcase->export = "导出数据";
$lang->testcase->confirmChange = '确认用例变动';
$lang->testcase->confirmStoryChange = '确认需求变动';
$lang->testcase->copy = '复制用例';
+$lang->testcase->group = '分组';
+$lang->testcase->groupName = '分组名称';
$lang->testcase->new = '新增';
diff --git a/module/testcase/view/create.html.php b/module/testcase/view/create.html.php
index 76618228cf..5cc95d5b38 100644
--- a/module/testcase/view/create.html.php
+++ b/module/testcase/view/create.html.php
@@ -135,25 +135,61 @@
testcase->stepID;?> |
testcase->stepDesc;?> |
testcase->stepExpect;?> |
- actions;?> |
+ actions;?> |
- $step)
- {
- $stepID += 1;
- echo "";
- echo "| $stepID | ";
- echo '' . html::textarea('steps[]', $step->desc, "rows='1' class='form-control'") . ' | ';
- echo '' . html::textarea('expects[]', $step->expect, "rows='1' class='form-control'") . ' | ';
- echo "";
- echo "";
- echo "";
- echo "";
- echo " | ";
- echo '
';
- }
- ?>
+