Skip to content

Commit

Permalink
Merge pull request #33 from kaishuu0123/master
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
kaishuu0123 authored Nov 17, 2019
2 parents 67e4756 + 11815c1 commit 7cc2936
Show file tree
Hide file tree
Showing 33 changed files with 352 additions and 34 deletions.
7 changes: 6 additions & 1 deletion app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ class ProjectsController < ApplicationController
:settings,
:users,
:groups, :add_group, :delete_group,
:delete_image
:delete_image,
:project_tags
]

def index
Expand Down Expand Up @@ -122,6 +123,10 @@ def delete_image
head :no_content
end

def project_tags
@tags = Tag.where(project: @project)
end

private

def project_params
Expand Down
21 changes: 18 additions & 3 deletions app/controllers/tickets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ def show
end

def create
@ticket = ticket_type.new(ticket_params)
@ticket = ticket_type.new(ticket_params.except(:tags))
authorize! :manage, @ticket

if @ticket.project_ticket_status.blank?
@ticket.project_ticket_status = @ticket.project.project_ticket_statuses.order(:sort_order).first
end

if ticket_params[:tags].class == Array
(ticket_params[:tags] || []).each do |tag|
@ticket.tags << Tag.find_or_create_by(name: tag[:name], project_id: ticket_params[:project_id])
end
end

respond_to do |format|
if @ticket.save
format.json { render :show, status: :ok, location: [@ticket.project, @ticket] }
Expand All @@ -29,7 +35,16 @@ def create

def update
authorize! :manage, @ticket
if @ticket.update(ticket_params)

if ticket_params[:tags].class == Array
@ticket.tag_tickets.destroy_all

(ticket_params[:tags] || []).each do |tag|
@ticket.tags << Tag.find_or_create_by(name: tag[:name], project_id: ticket_params[:project_id])
end
end

if @ticket.update(ticket_params.except(:tags))
render :show, status: :ok, location: [@ticket.project, @ticket]
else
render json: @ticket.errors, status: :unprocessable_entity
Expand All @@ -51,7 +66,7 @@ def ticket_params
params.permit(
:title, :body, :project_id, :sprint_id, :row_order_position,
:story_id, :project_ticket_status_id, :project_ticket_category_id,
:assignee_id, :point
:assignee_id, :point, tags: [:id, :name, :project_id]
)
end

Expand Down
2 changes: 1 addition & 1 deletion app/javascript/components/backlogs/BacklogsCard.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="card mt-2 shadow-sm mb-3">
<div class="card-header px-3 py-2 d-flex flex-row flex-wrap align-items-center justify-content-between">
<div class="card-header px-2 py-2 d-flex flex-row flex-wrap align-items-center justify-content-between">
<h6 class="m-0 text-gray-700">{{ $t('title.productBacklogs') }}</h6>
<div class="d-flex flex-row flex-wrap align-items-center">
<router-link :to="createStoryPath" class="btn rb-btn-xs p-1 btn-outline-primary shadow-sm mr-2">
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/components/backlogs/SprintCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</a>
</div>
</div>
<div v-else class="card-header px-3 py-2 d-flex flex-wrap align-items-center justify-content-between">
<div v-else class="card-header px-2 py-2 d-flex flex-wrap align-items-center justify-content-between">
<h6 class="m-0 text-gray-700" @click="editEnter">{{ sprint.title }}</h6>
<div class="d-flex flex-wrap align-items-center">
<div class="mr-3" @click="editEnter">
Expand Down
5 changes: 5 additions & 0 deletions app/javascript/components/backlogs/StoryListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
{{ story.point | numeral('0.0') }}
</span>
</div>
<div class="mt-1" v-if="story.tags && story.tags.length > 0">
<span class="rb-tag mr-1" v-for="tag in story.tags" :key="tag.id">
{{ tag.name }}
</span>
</div>
</div>
<div v-else>
<b-form @submit.stop.prevent="editDone(true)">
Expand Down
25 changes: 17 additions & 8 deletions app/javascript/components/backlogs/StoryModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
<div class="col-9">
<div class="d-flex mb-2">
<div>
<div v-if="story.id != null">
<div v-if="!isNew">
<button type="button" class="btn rb-btn-s btn-outline-danger shadow-sm" @click="onClickDelete">
<i class="fas fa-trash-alt mr-1" /> {{ $t('action.delete') }}
</button>
</div>
</div>
<div class="d-flex ml-auto">
<div class="mr-2" v-if="story.id != null">
<div class="mr-2" v-if="!isNew">
<div class="dropdown">
<button class="btn rb-btn-s btn-outline-secondary shadow-sm dropdown-toggle" type="button" id="clickboardMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-paperclip mr-1" /> {{ $t('action.copyToClipboard') }}
Expand All @@ -53,6 +53,11 @@
<i class="fas fa-pen mr-1" /> {{ $t('action.edit') }}
</button>
</div>
<div v-else-if="isEdit && !isNew" class="mr-2">
<button type="button" class="btn rb-btn-s btn-outline-secondary shadow-sm" @click="() => this.$refs.ticketForm.handleSubmit()">
<i class="fas fa-pen mr-1" /> {{ $t('action.submit') }}
</button>
</div>
<div>
<button type="button" class="btn rb-btn-s btn-outline-secondary shadow-sm" @click="() => this.$refs.modal.hide()">
<i class="fas fa-times mr-1" /> {{ $t('action.close') }}
Expand Down Expand Up @@ -89,7 +94,9 @@
:ticket="story"
ticketType="stories"
:isLoading="isLoading"
:afterSubmit="afterSubmit" />
:afterSubmit="afterSubmit"
:isNew="isNew"
ref="ticketForm" />
<TicketPreview
v-else
:projectId="projectId"
Expand All @@ -116,13 +123,12 @@
<hr />
</div>
<div>
<b-tabs content-class="mt-3">
<b-tabs content-class="mt-3" v-if="!isNew">
<b-tab>
<template v-slot:title>
<i class="fas fa-comment"></i> {{ $t('tab.comment') }}
</template>
<CommentFormAndList
v-if="story.id"
:projectId="projectId"
:ticket="selectedStory"
ticketType="stories"
Expand All @@ -142,9 +148,9 @@
</div>
<div class="col-3 p-0">
<div class="p-3 bg-gray-100">
<SelectCategory :projectId="projectId" :ticket="story" ticketType="stories" :isNew="story.id == null" v-model="story.projectTicketCategory" />
<SelectAssignee :projectId="projectId" :ticket="story" ticketType="stories" :isNew="story.id == null" v-model="story.assignee" />
<SelectStatus :projectId="projectId" :ticket="story" ticketType="stories" :isNew="story.id == null" v-model="story.projectTicketStatus" />
<SelectCategory :projectId="projectId" :ticket="story" ticketType="stories" :isNew="isNew" v-model="story.projectTicketCategory" />
<SelectAssignee :projectId="projectId" :ticket="story" ticketType="stories" :isNew="isNew" v-model="story.assignee" />
<SelectStatus :projectId="projectId" :ticket="story" ticketType="stories" :isNew="isNew" v-model="story.projectTicketStatus" />
<InputPoint v-if="story.id != null" :projectId="projectId" :ticket="story" ticketType="stories" />
</div>
</div>
Expand Down Expand Up @@ -236,6 +242,9 @@ export default {
border: `1px solid ${Color(color).darken(0.1)}`
}
},
isNew() {
return this.story.id == null
},
...mapState('Stories', {
selectedStory: 'selectedStory'
})
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/components/commons/SelectAssignee.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
:options="assignee.assignees"
:components="{OpenIndicator}"
label='username'
placeholder='Unassigned'
:placeholder="$t('title.unassigned')"
v-model="assignee.selected"
value="id"
ref="vSelect"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
:options="assignee.assignees"
label='username'
v-model="assignee.selected"
placeholder='Unassigned'
:placeholder="$t('title.unassigned')"
value="id"
ref="vSelect"
dir="rtl"
Expand Down
90 changes: 90 additions & 0 deletions app/javascript/components/commons/TagInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<template>
<div>
<v-select
@search:focus="onFocusTags"
@input="onInputTag"
:clearable="true"
:options="projectTags.tags"
v-model="projectTags.selected"
label="name"
:placeholder="$t('message.tagInput')"
:components="{OpenIndicator}"
:multiple="true"
:taggable="true"
ref="vSelect"
>
<template slot="selected-option" slot-scope="selected_option">
<span class="text-gray-600">
{{ selected_option.name }}
</span>
</template>
</v-select>
</div>
</template>

<script>
import vSelect from 'vue-select'
import { mapState, mapActions } from 'vuex'
export default {
name: 'TagInput',
components: {
vSelect
},
props: {
value: Array,
projectId: String,
},
data () {
return {
options: [
'Vue.js',
'Javascript',
'Open Source'
],
OpenIndicator: {
render: createElement => createElement('i', {class: 'fas fa-caret-down'})
}
}
},
watch: {
value: function(value, old) {
this.projectTags.selected = value
}
},
mounted() {
this.projectTags.selected = this.value
},
computed: {
...mapState('Tickets', {
projectTags: 'projectTags'
})
},
methods: {
onInputTag(tags) {
this.$emit('input', tags)
},
onFocusTags() {
this.getProjectTags({
projectId: this.projectId
})
},
...mapActions('Tickets', {
getProjectTags: 'getProjectTags'
})
}
}
</script>

<style lang="scss" scoped>
$vs-selected-bg: #eaecf4;
$vs-selected-border-color: #b7b9cc;
/deep/ {
@import "~vue-select/src/scss/vue-select.scss";
.vs__search::placeholder {
color: #b7b9cc;
}
}
</style>
32 changes: 28 additions & 4 deletions app/javascript/components/commons/TicketForm.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<b-form ref="form" @submit.stop.prevent="handleSubmit">
<b-form ref="form" @submit.stop.prevent="handleSubmit" @keydown.enter="onEnterKeyDown">
<b-form-group
id="title-group"
label-for="title-input"
Expand All @@ -15,6 +15,19 @@
size="sm"
/>
</b-form-group>
<b-form-group
id="tag-group"
label-for="tag-input"
>
<div class="d-flex align-items-center">
<div class="text-nowrap text-gray-600 mr-2">
{{ $t('title.tag') }}:
</div>
<div class="w-100">
<TagInput v-model="ticket.tags" :projectId="projectId" />
</div>
</div>
</b-form-group>
<b-form-group
id="body-group"
label-for="body-input"
Expand All @@ -31,21 +44,28 @@
</b-form-group>
<div class="d-flex align-items-center">
<b-form-text><i class="fab fa-markdown"></i> Markdown available</b-form-text>
<b-button class="ml-auto" variant="primary" size="sm" type="submit">{{ $t('action.submit') }}</b-button>
<b-button class="ml-auto" variant="primary" size="sm" type="submit">
{{ (() => isNew ? $t('action.create') : $t('action.submit'))() }}
</b-button>
</div>
</b-form>
</template>

<script>
import Vue from 'vue'
import { mapActions, mapMutations, mapState } from 'vuex'
import TagInput from './TagInput'
export default {
components: {
TagInput
},
props: {
projectId: String,
ticket: Object,
ticketType: String,
isLoading: Boolean,
isNew: Boolean,
afterSubmit: Function
},
mounted() {
Expand All @@ -59,6 +79,11 @@ export default {
this.ticket[key] = value;
this.$emit('input', this.value)
},
onEnterKeyDown(e) {
if (e.target.className.includes("vs__search")) {
e.preventDefault();
}
},
handleSubmit(event) {
if (!this.$refs.form.checkValidity()) {
this.$refs.form.reportValidity()
Expand Down Expand Up @@ -116,5 +141,4 @@ export default {
</script>

<style>
</style>
</style>
10 changes: 9 additions & 1 deletion app/javascript/components/commons/TicketPreview.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
<template>
<div>
<h1 class="h4 text-gray-800 mb-3">{{ ticket.title }}</h1>
<h1 class="h4 text-gray-800 mb-2">{{ ticket.title }}</h1>
<div class="d-flex align-items-center mb-2">
<div class="text-gray-600 mr-2">
{{ $t('title.tag') }}:
</div>
<span v-for="tag in ticket.tags" :key="tag.id" class="rb-tag mr-1">
{{ tag.name }}
</span>
</div>
<MarkdownText :content="ticket.body" v-if="ticket.body" />
<div v-else class="d-flex bg-gray-100 align-items-center border rounded">
<p class="text-xs text-gray-500 p-1 mb-0"> {{ $t('message.noDescription') }}</p>
Expand Down
Loading

0 comments on commit 7cc2936

Please sign in to comment.