mirror of
https://github.com/usetrmnl/plugins.git
synced 2026-08-13 14:26:58 -07:00
Todoist
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
module Plugins
|
||||
class Todoist < Base
|
||||
|
||||
def locals
|
||||
{ tasks: }
|
||||
end
|
||||
|
||||
class << self
|
||||
def redirect_url
|
||||
query = {
|
||||
response_type: 'code',
|
||||
client_id: Rails.application.credentials.plugins[:todoist][:client_id],
|
||||
scope: 'data:read',
|
||||
redirect_uri: "#{Rails.application.credentials.base_url}/plugin_settings/todoist/redirect"
|
||||
}.to_query
|
||||
"https://todoist.com/oauth/authorize?#{query}"
|
||||
end
|
||||
|
||||
def fetch_access_token(code)
|
||||
body = {
|
||||
grant_type: "authorization_code",
|
||||
client_id: Rails.application.credentials.plugins[:todoist][:client_id],
|
||||
client_secret: Rails.application.credentials.plugins[:todoist][:client_secret],
|
||||
redirect_uri: "#{Rails.application.credentials.base_url}/plugin_settings/todoist/redirect",
|
||||
code: code
|
||||
}
|
||||
response = HTTParty.post("https://todoist.com/oauth/access_token", body:)
|
||||
response.parsed_response['access_token']
|
||||
end
|
||||
|
||||
def projects(access_token)
|
||||
response = HTTParty.get('https://api.todoist.com/rest/v2/projects', headers: headers(access_token))
|
||||
response.map { |m| { m['name'] => m['id'] } }&.push({ 'Today' => 'today' })
|
||||
end
|
||||
|
||||
def headers(access_token) = { "Authorization" => "Bearer #{access_token}" }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def task_url = "https://api.todoist.com/rest/v2/tasks"
|
||||
|
||||
def tasks
|
||||
fetch(task_url, query:, headers: Plugins::Todoist.headers(access_token))
|
||||
.sort_by { Date.parse(it.dig('due', 'date') || (Date.today + 100.days).to_s) }
|
||||
.reject { today_view? ? (it.dig('due', 'date').blank? || Date.parse(it.dig('due', 'date')) > today) : false }
|
||||
.map do |it|
|
||||
{
|
||||
content: it['content'],
|
||||
due: it.dig('due', 'date').present? ? Date.parse(it.dig('due', 'date')).strftime("%d %b") : it.dig('due', 'string')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def query = today_view? ? {} : { project_id: settings['todoist_project_id'] }
|
||||
|
||||
def access_token = settings.dig('todoist', 'access_token')
|
||||
|
||||
def today_view? = settings['todoist_project_id'] == 'today'
|
||||
|
||||
def today = user.datetime_now.end_of_day
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
<div class="view view--full">
|
||||
<div class="layout">
|
||||
<div class="columns">
|
||||
<% todos.reverse.each_with_index do |doing_and_done, list_index| %>
|
||||
<div class="column gap--large">
|
||||
<span class="label label--large <%= 'label--gray-out' if list_index == 0 %>"><%= doing_and_done[:label].titleize %></span>
|
||||
<% visible_items = doing_and_done[:items] %>
|
||||
<% hidden_items_count = doing_and_done[:items].size - visible_items.size %>
|
||||
<div class="list gap" data-list-limit="true" data-list-hidden-count="true" data-list-max-height="310">
|
||||
<% visible_items.each_with_index do |item, idx| %>
|
||||
<div class="item">
|
||||
<div class="meta">
|
||||
<span class="index"><%= idx + 1 %></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="label truncate-none <%= 'label--gray-out' if list_index == 0 %>"><%= item %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render 'plugins/todo_list/shared/title_bar', instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
<div class="view view--half_horizontal">
|
||||
<div class="layout layout--row">
|
||||
<% todos.reverse.each_with_index do |doing_and_done, list_index| %>
|
||||
<div class="grid grid--cols-1">
|
||||
<span class="label <%= 'label--gray-out' if list_index == 0 %>"><%= doing_and_done[:label].titleize %></span>
|
||||
<div class="list" data-list-limit="true" data-list-hidden-count="true" data-list-max-height="140">
|
||||
<% doing_and_done[:items].each_with_index do |item, idx| %>
|
||||
<div class="item">
|
||||
<div class="meta">
|
||||
<span class="index"><%= idx + 1 %></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="label truncate-none <%= 'label--gray-out' if list_index == 0 %>"><%= item %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= render 'plugins/todo_list/shared/title_bar', instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
<div class="view view--half_vertical">
|
||||
<div class="layout layout--col gap--space-between">
|
||||
<% todos.each_with_index do |doing_and_done, list_index| %>
|
||||
<div class="list" data-list-limit="true" data-list-hidden-count="true" data-list-max-height="160">
|
||||
<span class="label <%= 'label--gray-out' if list_index == 1 %>"><%= doing_and_done[:label].titleize %></span>
|
||||
<% doing_and_done[:items].each_with_index do |item, idx| %>
|
||||
<div class="item">
|
||||
<div class="meta">
|
||||
<span class="index"><%= idx + 1 %></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="label truncate-none <%= 'label--gray-out' if list_index == 1 %>"><%= item %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% hidden_items_count = doing_and_done[:items].size - 3 %>
|
||||
</div>
|
||||
<% if list_index == 0 %>
|
||||
<div class="w-full b-h-gray-5"></div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= render 'plugins/todo_list/shared/title_bar', instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<div class="view view--quadrant">
|
||||
<div class="layout layout--col">
|
||||
<div class="list" data-list-limit="true" data-list-hidden-count="true" data-list-max-height="150">
|
||||
<% todos = todos.first %>
|
||||
<% todos[:items].each_with_index do |item, idx| %>
|
||||
<div class="item">
|
||||
<div class="meta">
|
||||
<span class="index"><%= idx + 1 %></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="label truncate-none"><%= item %></span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render 'plugins/todo_list/shared/title_bar', instance_name: instance_name %>
|
||||
</div>
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="title_bar">
|
||||
<img class="image" src="<%= Rails.application.credentials.base_url %>/images/plugins/todo_list--render.svg" />
|
||||
<span class="title">Todo List</span>
|
||||
<span class="instance"><%= instance_name %></span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user