Creation project wizard

stable
Xavier Julián 2014-09-11 17:31:56 +02:00 committed by Andrey Antukh
parent 38f617f943
commit 1d847523f4
9 changed files with 343 additions and 47 deletions

View File

@ -21,6 +21,7 @@
taiga = @.taiga
bindOnce = @.taiga.bindOnce
timeout = @.taiga.timeout
module = angular.module("taigaProject")
@ -28,6 +29,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
link = ($scope, $el, attrs) ->
$scope.data = {}
$scope.templates = []
form = $el.find("form").checksley({"onlyOneErrorElement": true})
onSuccessSubmit = (response) ->
@ -37,8 +39,14 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
$rootscope.$broadcast("projects:reload")
onErrorSubmit = (response) ->
$confirm.notify("light-error", "According to our Oompa Loompas, project name is
already in use.") #TODO: i18n
form.setErrors(response)
selectors = []
for error_field in _.keys(response)
selectors.push("[name=#{error_field}]")
$el.find(".active").removeClass("active")
error_step = $el.find(selectors.join(",")).first().parents(".wizard-step")
error_step.addClass("active")
$el.find('.progress-bar').removeClass().addClass('progress-bar').addClass(error_step.data("step"))
submit = ->
if not form.validate()
@ -48,19 +56,64 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project
promise.then(onSuccessSubmit, onErrorSubmit)
$scope.$on "projects:create", ->
$scope.data = {}
$scope.$apply ->
$scope.data = {
total_story_points: 100
total_milestones: 5
}
if !$scope.templates.length
$rs.projects.templates()
.then (result) =>
$scope.templates = _.map(result, (item) -> {"id": item.id, "name": item.name})
$rs.projects.templates().then (result) =>
$scope.templates = result
$scope.data.creation_template = _.head(_.filter($scope.templates, (x) -> x.slug == "scrum")).id
else
$scope.$apply ->
$scope.data.creation_template = _.head(_.filter($scope.templates, (x) -> x.slug == "scrum")).id
$el.find(".active").removeClass("active")
$el.find(".create-step1").addClass("active")
lightboxService.open($el)
timeout 600, ->
$el.find(".progress-bar").addClass('step1')
$el.on "click", "a.button-green", (event) ->
$el.on "click", ".button-next", (event) ->
event.preventDefault()
current = $el.find(".active")
valid = true
for field in form.fields
if current.find("[name=#{field.element.attr('name')}]").length
valid = field.validate() != false and valid
if not valid
return
next = current.next()
current.toggleClass('active')
next.toggleClass('active')
step = next.data('step')
$el.find('.progress-bar').removeClass().addClass('progress-bar').addClass(step)
$el.on "click", ".button-prev", (event) ->
event.preventDefault()
current = $el.find(".active")
prev = current.prev()
current.toggleClass('active')
prev.toggleClass('active')
step = prev.data('step')
$el.find('.progress-bar').removeClass().addClass('progress-bar').addClass(step)
$el.on "click", ".button-submit", (event) ->
event.preventDefault()
submit()
$el.on "click", ".close", (event) ->
event.preventDefault()
lightboxService.close($el)
return {link:link}
module.directive("tgLbCreateProject", ["$rootScope", "$tgRepo", "$tgConfirm", "$location", "$tgNavUrls",

View File

@ -1,27 +0,0 @@
a.close(href="", title="close")
span.icon.icon-delete
form
h2.title Create Project
form
fieldset
input(type="text", name="name", ng-model="data.name", data-required="true",
placeholder="Name", maxlength="45")
fieldset
textarea(name="description", ng-model="data.description", data-required="true",
placeholder="Description")
fieldset
input(type="number", name="total_story_points", min="0", ng-model="data.total_story_points",
data-type="digits", data-required="true", placeholder="Total story points")
fieldset
input(type="number", name="total_milestones", min="0", ng-model="data.total_milestones",
data-type="digits", placeholder="Total milestones")
fieldset
select(name="creation_template", ng-model="data.creation_template",
ng-options="template.id as template.name for template in templates")
option(value="") Select one template to generate the defaults values for the new project
fieldset
a.button.button-green(href="", title="Create") Create
input(type="submit", class="hidden")

View File

@ -3,7 +3,7 @@
include ../components/spinner
p Loading project...
div.lightbox.lightbox_create-project.hidden(tg-lb-create-project)
include lightbox_create-project
div.wizard-create-project.hidden(tg-lb-create-project)
include wizard-create-project
nav.projects-nav(ng-controller="ProjectsNavigationController", tg-projects-nav, tg-projects-pagination, projects="projects")

View File

@ -0,0 +1,54 @@
form
section.wizard-step.create-step1.active(data-step="step1")
div.title
h1 Create Project
p Fresh and clean. So exciting!
fieldset
input(type="text", name="name", ng-model="data.name", data-required="true", placeholder="Name", maxlength="45")
fieldset
textarea(name="description", ng-model="data.description", data-required="true", placeholder="Description")
fieldset
a.button-next.button.button-green(href="", title="Next") Next
section.wizard-step.create-step2(data-step="step2")
div.title
h1 Choose a template
p Which template would fit better in your project?
div.template-wrapper
div.template-inner
fieldset(ng-repeat="template in templates")
input(type="radio", name="template", id="template-{{ template.id }}",
ng-value='template.id', ng-model="data.creation_template",
data-required="true")
label.backlog(for="template-{{ template.id }}")
span.icon.icon-backlog
h2 {{ template.name }}
p {{ template.description }}
fieldset.wizard-action
div
a.button-prev.button.button-gray(href="", title="Prev") Prev
a.button-submit.button.button-green(href="", title="Create") Create
// section.wizard-step.create-step3(data-step="step3")
// div.title
// h1 Final Touch
// p Give a final touch and make this project totally yours
// fieldset
// input(type="number", name="total_story_points", min="0", ng-model="data.total_story_points", data-type="digits", data-required="true", placeholder="Total story points")
// fieldset
// input(type="number", name="total_milestones", min="0", ng-model="data.total_milestones", data-type="digits", placeholder="Total milestones")
// fieldset.wizard-action
// div
// a.button-prev.button.button-gray(href="", title="Prev") Prev
// a.button-submit.button.button-green(href="", title="Create") Create
div.progress-bar
div.progress-state
span Name and description
span Template selection
// span Final touches
div.progress-bar-wrapper
div.bar
a.close(href="" title="close")
span.icon.icon-delete

View File

@ -45,3 +45,18 @@
opacity: 1;
}
}
@include keyframes(formSlide) {
0% {
@include filter(blur(5px));
@include transform(translateY(10rem));
opacity: 0;
}
50% {
@include filter(blur(0));
}
100% {
@include transform(translateY(0));
opacity: 1;
}
}

View File

@ -62,6 +62,7 @@ $prefix-for-spec: true;
@import 'modules/common/attachments';
@import 'modules/common/related-tasks';
@import 'modules/common/history';
@import 'modules/common/wizard';
//Project modules
@import 'modules/home-projects-list';

View File

@ -1,6 +1,6 @@
.us-assigned-to {
@include table-flex();
margin-top: 2rem;
margin-top: 1rem;
position: relative;
.user-avatar {
@include table-flex-child(1, 0);
@ -30,8 +30,8 @@
color: $gray-light;
opacity: 1;
position: absolute;
right: 1rem;
top: 1rem;
right: 0;
top: 0;
&:hover {
color: $red;
}

View File

@ -1,4 +1,5 @@
.lightbox {
.lightbox,
%lightbox {
@include background-opacity($white, .95);
@include table-flex(center, center, flex, row, wrap, center);
@include transition (opacity .3s ease);
@ -27,7 +28,8 @@
textarea {
resize: vertical;
}
.button-green {
.button-green,
.button-gray {
display: block;
padding: 12px;
text-align: center;
@ -496,12 +498,6 @@
}
}
.lightbox_create-project {
form {
width: 600px;
}
}
.lb-create-edit-userstory {
.points-per-role {
margin-bottom: 1rem;

View File

@ -0,0 +1,204 @@
.wizard-create-project {
@extend %lightbox;
background: url('/images/invitation_bg.jpg') no-repeat center center;
background-size: cover;
color: $white;
text-align: center;
form {
width: 500px;
}
.title {
width: 100%;
}
h1,
p {
color: $white;
}
h1 {
line-height: 1.5rem;
}
p {
@extend %small;
opacity: .8;
}
input,
textarea,
select {
background: rgba($white, .7);
@include placeholder {
color: $grayer;
}
}
.close {
color: $white;
&:hover {
color: $red-light;
}
}
.wizard-step {
display: none;
@include animation(formSlide .4s ease-in-out);
@include animation-direction(alternate-reverse);
&.active {
@include animation(formSlide .4s ease-in-out);
&.create-step1,
&.create-step3 {
@include table-flex();
}
&.create-step2 {
display: block;
}
}
}
.wizard-action {
div {
@include table-flex();
}
a {
@include table-flex-child(1, 40%, 0);
color: $white;
display: inline-block;
&:first-child {
margin-right: .5rem;
}
}
}
.create-step2 {
.template-inner {
@include table-flex();
fieldset {
@include table-flex-child(1, 0, 0);
&:first-child {
margin-right: .5rem;
}
}
}
input[type="radio"] {
display: none;
&:checked {
+label {
@include transition(background .3s ease-in);
background: rgba($fresh-taiga, .7);
}
}
+label {
@include transition(background .3s ease-in);
background: rgba($whitish, .7);
cursor: pointer;
display: block;
margin-bottom: 1rem;
padding: 1rem;
text-align: center;
&:hover {
@include transition(background .3s ease-in);
background: rgba($green-taiga, .7);
}
.icon {
@extend %xxlarge;
color: $white;
}
}
}
h2 {
color: $white;
margin: 0;
margin-top: .5rem;
text-transform: uppercase;
}
p {
text-align: center;
}
}
.progress-bar {
bottom: 0;
height: .5rem;
left: 0;
position: absolute;
width: 100%;
&.step1 {
.bar {
@include transition(width .6s ease-in-out);
width: 25%;
}
.progress-state {
span {
&:nth-child(1) {
@include transition(color .3s ease-in-out);
@include transition-delay(.6s);
color: rgba($white, 1);
}
}
}
}
&.step2 {
.bar {
@include transition(width .6s ease-in-out);
// width: 50%;
width: 75%;
}
.progress-state {
span {
&:nth-child(1),
&:nth-child(2) {
@include transition(color .3s ease-in-out);
@include transition-delay(.6s);
color: rgba($white, 1);
}
}
}
}
// &.step3 {
// .bar {
// @include transition(width .6s ease-in-out);
// width: 75%;
// }
// .progress-state {
// span {
// &:nth-child(1),
// &:nth-child(2),
// &:nth-child(3) {
// @include transition(color .3s ease-in-out);
// @include transition-delay(.6s);
// color: rgba($white, 1);
// }
// }
// }
// }
}
.progress-state {
position: absolute;
width: 100%;
span {
@include transition(all 1s ease-in);
color: rgba($white, .5);
display: inline-block;
margin-left: -100px;
position: absolute;
text-align: center;
top: -2rem;
width: 200px;
&:nth-child(1) {
left: 25%;
}
&:nth-child(2) {
// left: 50%;
left: 75%;
}
// &:nth-child(3) {
// left: 75%;
// }
}
}
.progress-bar-wrapper {
background: rgba($white, .3);
height: .5rem;
}
.bar {
background: rgba($fresh-taiga, .9);
height: .5rem;
left: 0;
position: absolute;
top: 0;
width: 0;
}
}