Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions app/views/shared/_ticker_issue_list.html.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
<div data-controller="list" data-issue-completion-target="listAnchor">
<table data-list-target="table">
<template>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could also give it a data attr for easier access

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is
.querySelector('[data-template]')
easier than
.querySelector('template')
?

<%= render "shared/ticker_issue_list_entry", issue: Issue.new(id: 0) %>
</template>
<tbody>
<% timer_session.relevant_issues.each do |issue| %>
<tr class="issue-container" data-form-target="issue" data-issue-id="<%= issue.id %>">
<td>
<b><%= link_to "#{issue.project} - #{issue.id}:", issue_path(issue.id), target: '_blank', rel: 'noopener' %></b>
</td>
<td>
<%= issue.subject %>
</td>
<td>
<span class="text-danger input-group-text" data-action="click->list#removeItem">
<%= sprite_icon('del', t(:button_delete), icon_only: true) %>
</span>
<%= hidden_field_tag 'timer_session[issue_ids][]', issue.id, id: "timer_session_issue_id_#{issue.id}", readonly: true %>
</td>
</tr>
<%= render "shared/ticker_issue_list_entry", issue: issue %>
<% end %>
</tbody>
</table>
Expand Down
13 changes: 13 additions & 0 deletions app/views/shared/_ticker_issue_list_entry.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<tr class="issue-container" data-form-target="issue" data-issue-id="<%= issue.id %>">
<td>
<b><%= link_to "#{issue.project} - #{issue.id}:", issue_path(issue.id), target: :_blank, rel: :noopener %></b>
</td>
<td data-issue-subject><%= issue.subject %></td>
<td>
<span class="text-danger input-group-text" data-action="click->list#removeItem">
<%= sprite_icon('del', t(:button_delete), icon_only: true) %>
</span>
<%= hidden_field_tag 'timer_session[issue_ids][]', issue.id,
id: "timer_session_issue_id_#{issue.id}", readonly: true %>
</td>
</tr>
81 changes: 19 additions & 62 deletions assets.src/src/redmine-tracky/controllers/list-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,72 +6,29 @@ export default class extends Controller {

static targets = ['table']

public addItem(item: CompletionResult) {
const tbody = this.tableTarget.getElementsByTagName('tbody')[0]
tbody.appendChild(this.buildItem(item))
addItem(item: CompletionResult) {
this.tableTarget.querySelector('tbody')!.appendChild(this.buildItem(item))
}

public removeItem(event: Event) {
const { target } = event
const row = (target as Element).closest('[data-form-target="issue"]')
row?.remove()
removeItem({ target }: Event) {
const item = target as Element
item.closest('[data-form-target="issue"]')?.remove()
}

private buildItem(item: CompletionResult) {
const row = document.createElement('tr')
row.setAttribute('data-form-target', 'issue')
row.classList.add('issue-container')
row.setAttribute('data-issue-id', item.id.toString())
;[
this.buildLabelColumn(item),
this.buildSubjectColumn(item),
this.buildDeletionButtonColumn(item),
].forEach((element) => row.appendChild(element))

return row
}

private buildLabelColumn(item: CompletionResult) {
const bold = document.createElement('b')
const a = document.createElement('a')

a.setAttribute('href', `/issues/${item.id}`)
a.setAttribute('target', '_blank')
a.setAttribute('rel', 'noopener')

a.innerHTML = `${item.project} - ${item.id}: `
bold.appendChild(a)

return this.buildColumn([bold])
}

private buildSubjectColumn(item: CompletionResult) {
return this.buildColumn([document.createTextNode(item.subject)])
}

private buildDeletionButtonColumn(item: CompletionResult) {
const span = document.createElement('span')
const icon = document.createElement('i')
const input = document.createElement('input')

span.classList.add('text-danger')
span.classList.add('input-group-text')
span.setAttribute('data-action', 'click->list#removeItem')
icon.classList.add('icon-only')
icon.classList.add('icon-del')
span.appendChild(icon)
input.setAttribute('id', `timer_session_issue_id_${item.id}`)
input.setAttribute('readonly', '')
input.setAttribute('hidden', '')
input.setAttribute('name', 'timer_session[issue_ids][]')
input.setAttribute('value', item.id.toString())

return this.buildColumn([span, input])
}

private buildColumn(elements: (Element | Text)[]) {
const column = document.createElement('td')
elements.forEach((element) => column.appendChild(element))
return column
const issue = this.tableTarget
.querySelector('template')!
.content.cloneNode(true) as DocumentFragment
const link = issue.querySelector('a')!
const input = issue.querySelector('input')!

link.href = `/issues/${item.id}`
link.innerHTML = `${item.project} - ${item.id}: `
input.id = `timer_session_issue_id_${item.id}`
input.value = item.id.toString()
issue.querySelector('tr')!.setAttribute('data-issue-id', item.id.toString())
issue.querySelector('[data-issue-subject]')!.innerHTML = item.subject

return issue
}
}
4 changes: 4 additions & 0 deletions assets.src/src/styles/timer_container.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
column-count: 2;
}

.timer-container button svg {
stroke: #fff;
}

input:disabled,
button:disabled {
background-color: #e9ecef;
Expand Down
3 changes: 1 addition & 2 deletions assets.src/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ const path = require('path')
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')

module.exports = {
mode: 'development',
devtool: 'inline-source-map',
mode: 'production',
entry: {
main: './src/redmine-tracky.ts',
},
Expand Down
Loading