255 lines
12 KiB
HTML
255 lines
12 KiB
HTML
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<button type="button" class="close" aria-hidden="true"
|
|
ng-click="close()">×</button>
|
|
<h3 class="panel-title">New Story</h3>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="row">
|
|
<div class="col-xs-12">
|
|
<form class="form-horizontal" role="form" name="storyForm">
|
|
<div class="form-group">
|
|
<label for="name" class="col-sm-2 control-label">
|
|
Title
|
|
</label>
|
|
|
|
<div class="col-sm-10">
|
|
<input id="name"
|
|
focus
|
|
type="text"
|
|
class="form-control"
|
|
ng-model="story.title"
|
|
required
|
|
maxlength="255"
|
|
placeholder="Story Title">
|
|
</div>
|
|
</div>
|
|
<div class="form-group" ng-show="preview">
|
|
<label class="col-sm-2 control-label">
|
|
Description Preview
|
|
</label>
|
|
<div class="col-sm-10">
|
|
<insert-markdown content="story.description">
|
|
</insert-markdown>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="description"
|
|
class="col-sm-2 control-label">
|
|
Description
|
|
</label>
|
|
|
|
<div class="col-sm-10">
|
|
<textarea id="description"
|
|
class="form-control new-textArea"
|
|
ng-model="story.description"
|
|
msd-elastic
|
|
required
|
|
placeholder="A brief story description">
|
|
</textarea>
|
|
</div>
|
|
</div>
|
|
<div class="form-group" ng-if="!forcePrivate">
|
|
<label for="private" class="col-sm-2 control-label">
|
|
Private
|
|
</label>
|
|
<div class="col-sm-10">
|
|
<div class="checkbox" ng-show="!privacyLocked">
|
|
<input id="private"
|
|
type="checkbox"
|
|
class="modal-checkbox"
|
|
ng-model="story.private"
|
|
ng-disabled="isSaving || privacyLocked"
|
|
/>
|
|
</div>
|
|
<div class="checkbox help-block"
|
|
ng-show="privacyLocked">
|
|
Security-related stories are always private when created.
|
|
If privacy is really not required, the story can be edited
|
|
after creation to be made public.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group" ng-if="!forcePrivate">
|
|
<label for="security" class="col-sm-2 control-label">
|
|
Vulnerability or Security-related
|
|
</label>
|
|
<div class="col-sm-10 checkbox">
|
|
<input id="security"
|
|
type="checkbox"
|
|
class="modal-checkbox"
|
|
ng-model="story.security"
|
|
ng-change="updateSecurity(true, false)"
|
|
ng-disabled="isSaving"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6 col-md-offset-3"
|
|
ng-show="story.private">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Teams and Users that can see this story</th>
|
|
<th class="text-right">
|
|
<small>
|
|
<a href
|
|
ng-click="showAddUser = !showAddUser">
|
|
<i class="fa fa-plus" ng-if="!showAddUser"></i>
|
|
<i class="fa fa-minus" ng-if="showAddUser"></i>
|
|
Add Team or User
|
|
</a>
|
|
</small>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr ng-repeat="team in story.teams">
|
|
<td colspan="2">
|
|
<i class="fa fa-fw fa-sb-team text-muted"></i> 
|
|
{{ team.name }}
|
|
<a class="close"
|
|
ng-click="removeTeam(team)"
|
|
ng-show="story.teams.length > 1 || story.users.length > 0">
|
|
×
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<tr ng-repeat="user in story.users">
|
|
<td colspan="2">
|
|
<i class="fa fa-fw fa-sb-user text-muted"></i> 
|
|
{{user.full_name}}
|
|
<a class="close"
|
|
ng-click="removeUser(user)"
|
|
ng-show="story.users.length > 1 || story.teams.length > 0">
|
|
×
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<tr ng-show="showAddUser">
|
|
<td colspan="2">
|
|
<input id="user"
|
|
type="text"
|
|
autocomplete="off"
|
|
placeholder="Click to add a team or user"
|
|
ng-model="asyncUser"
|
|
typeahead-wait-ms="200"
|
|
typeahead-editable="false"
|
|
typeahead="actor as actor.name for actor in
|
|
searchActors($viewValue, story.users, story.teams)"
|
|
typeahead-loading="loadingUsers"
|
|
typeahead-on-select="addActor($model)"
|
|
typeahead-template-url="/inline/actor-typeahead-item.html"
|
|
class="form-control input-sm"
|
|
/>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-xs-12">
|
|
<label class="col-sm-2 control-label">
|
|
Tasks
|
|
</label>
|
|
<form role="form" name="tasksForm">
|
|
<table class="table table-striped table-outlined">
|
|
<tbody>
|
|
<tr ng-repeat="(index, task) in tasks" ng-include
|
|
src="'/inline/task_row.html'">
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-xs-6">
|
|
<button type="button"
|
|
class="btn btn-default"
|
|
ng-click="addTask()">
|
|
+
|
|
Add another task
|
|
</button>
|
|
<a class="btn btn-link" target="_blank"
|
|
href="http://daringfireball.net/projects/markdown/basics">
|
|
Markdown formatting is supported
|
|
</a>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<button type="button"
|
|
class="btn btn-primary"
|
|
ng-click="preview = !preview">
|
|
Preview Description
|
|
</button>
|
|
<button type="button"
|
|
class="btn btn-primary"
|
|
ng-click="save()"
|
|
ng-disabled="!storyForm.$valid || !tasksForm.$valid">
|
|
Save Changes
|
|
</button>
|
|
<button type="button"
|
|
ng-click="close()"
|
|
class="btn btn-default">
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<script type="text/ng-template" id="/inline/actor-typeahead-item.html">
|
|
<a tabindex="-1">
|
|
<i ng-class="'fa fa-sb-' + match.model.type"></i>
|
|
<span ng-bind-html="match.model.name | typeaheadHighlight:query"></span>
|
|
</a>
|
|
</script>
|
|
|
|
|
|
<!-- Template for story metadata -->
|
|
<script type="text/ng-template" id="/inline/task_row.html">
|
|
<td>
|
|
<input type="text"
|
|
class="form-control input-sm"
|
|
ng-model="task.title"
|
|
required
|
|
placeholder="Task Title">
|
|
</td>
|
|
<td class="col-xs-4">
|
|
<div class="has-feedback has-feedback-no-label">
|
|
<input id="project"
|
|
type="text"
|
|
placeholder="Select a Project"
|
|
autocomplete="off"
|
|
required
|
|
ng-model="asyncProject"
|
|
typeahead-wait-ms="200"
|
|
typeahead-editable="false"
|
|
typeahead="project as project.name for project
|
|
in searchProjects($viewValue)"
|
|
typeahead-loading="loadingProjects"
|
|
typeahead-input-formatter="formatProjectName($model)"
|
|
typeahead-on-select="selectNewProject($model, task)"
|
|
class="form-control input-sm"
|
|
/>
|
|
<span class="form-control-feedback text-muted
|
|
form-control-feedback-sm">
|
|
<i class="fa fa-sync fa-spin" ng-show="loadingProjects"></i>
|
|
<i class="fa fa-search" ng-hide="loadingProjects"></i>
|
|
</span>
|
|
</div>
|
|
</td>
|
|
<th class="col-xs-1"
|
|
ng-show="tasks.length > 1">
|
|
<button type="button" class="close"
|
|
ng-click="removeTask(task)">
|
|
×
|
|
</button>
|
|
</th>
|
|
</script>
|