inner_plan 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +28 -0
  3. data/Rakefile +8 -0
  4. data/app/assets/config/inner_plan_manifest.js +6 -0
  5. data/app/assets/stylesheets/inner_plan/application.css +24 -0
  6. data/app/components/application_view.rb +4 -0
  7. data/app/components/inner_plan/breadcrumbs_component.rb +26 -0
  8. data/app/components/inner_plan/groups/edit_view.rb +72 -0
  9. data/app/components/inner_plan/groups/new_view.rb +66 -0
  10. data/app/components/inner_plan/groups/row/handle_component.rb +30 -0
  11. data/app/components/inner_plan/groups/row_component.rb +31 -0
  12. data/app/components/inner_plan/groups/rows_component.rb +17 -0
  13. data/app/components/inner_plan/groups/show_menu_component.rb +30 -0
  14. data/app/components/inner_plan/groups/show_view.rb +77 -0
  15. data/app/components/inner_plan/lists/completed_tasks_component.rb +30 -0
  16. data/app/components/inner_plan/lists/edit_view.rb +62 -0
  17. data/app/components/inner_plan/lists/index_view.rb +57 -0
  18. data/app/components/inner_plan/lists/new_view.rb +49 -0
  19. data/app/components/inner_plan/lists/ongoing_tasks_component.rb +17 -0
  20. data/app/components/inner_plan/lists/row/handle_component.rb +37 -0
  21. data/app/components/inner_plan/lists/row_component.rb +55 -0
  22. data/app/components/inner_plan/lists/show_menu_component.rb +37 -0
  23. data/app/components/inner_plan/lists/show_view.rb +76 -0
  24. data/app/components/inner_plan/progress_bar_separator_component.rb +20 -0
  25. data/app/components/inner_plan/tasks/completed_toggler_component.rb +27 -0
  26. data/app/components/inner_plan/tasks/edit_view.rb +82 -0
  27. data/app/components/inner_plan/tasks/form/item_component.rb +21 -0
  28. data/app/components/inner_plan/tasks/form/row_component.rb +19 -0
  29. data/app/components/inner_plan/tasks/inline_form_view.rb +62 -0
  30. data/app/components/inner_plan/tasks/row/addons_component.rb +22 -0
  31. data/app/components/inner_plan/tasks/row/base_addon_component.rb +19 -0
  32. data/app/components/inner_plan/tasks/row/description_addon_component.rb +13 -0
  33. data/app/components/inner_plan/tasks/row/due_on_addon_component.rb +14 -0
  34. data/app/components/inner_plan/tasks/row/group_addon_component.rb +11 -0
  35. data/app/components/inner_plan/tasks/row/handle_component.rb +40 -0
  36. data/app/components/inner_plan/tasks/row_component.rb +35 -0
  37. data/app/components/inner_plan/tasks/rows_component.rb +22 -0
  38. data/app/components/inner_plan/tasks/show/item_component.rb +20 -0
  39. data/app/components/inner_plan/tasks/show/row_component.rb +19 -0
  40. data/app/components/inner_plan/tasks/show_menu_component.rb +30 -0
  41. data/app/components/inner_plan/tasks/show_view.rb +76 -0
  42. data/app/components/inner_plan/user_with_avatar_component.rb +17 -0
  43. data/app/concepts/inner_plan/list/operation/index.rb +11 -0
  44. data/app/concepts/inner_plan/task/operation/complete.rb +12 -0
  45. data/app/concepts/inner_plan/task/operation/create.rb +46 -0
  46. data/app/concepts/inner_plan/task/operation/reopen.rb +12 -0
  47. data/app/concepts/inner_plan/task/operation/update.rb +25 -0
  48. data/app/concepts/inner_plan/task/operation/update_position.rb +25 -0
  49. data/app/controllers/inner_plan/application_controller.rb +12 -0
  50. data/app/controllers/inner_plan/groups_controller.rb +59 -0
  51. data/app/controllers/inner_plan/lists_controller.rb +59 -0
  52. data/app/controllers/inner_plan/tasks_controller.rb +73 -0
  53. data/app/helpers/inner_plan/application_helper.rb +4 -0
  54. data/app/javascript/inner_plan/application.js +15 -0
  55. data/app/javascript/inner_plan/controllers/groups_controller.js +47 -0
  56. data/app/javascript/inner_plan/controllers/lists_controller.js +30 -0
  57. data/app/javascript/inner_plan/controllers/task_inline_form_controller.js +40 -0
  58. data/app/javascript/inner_plan/controllers/tasks_controller.js +47 -0
  59. data/app/jobs/inner_plan/application_job.rb +4 -0
  60. data/app/mailers/inner_plan/application_mailer.rb +6 -0
  61. data/app/models/inner_plan/application_record.rb +5 -0
  62. data/app/models/inner_plan/list.rb +29 -0
  63. data/app/models/inner_plan/task.rb +36 -0
  64. data/app/services/inner_plan/tasks/description_renderer.rb +18 -0
  65. data/app/services/inner_plan/tasks/title_renderer.rb +18 -0
  66. data/app/views/inner_plan/shared/_blankslate.svg.erb +1 -0
  67. data/app/views/inner_plan/tasks/complete.turbo_stream.erb +16 -0
  68. data/app/views/inner_plan/tasks/create.turbo_stream.erb +11 -0
  69. data/app/views/inner_plan/tasks/create_failure.turbo_stream.erb +5 -0
  70. data/app/views/layouts/action_text/contents/_content.html.erb +3 -0
  71. data/app/views/layouts/inner_plan/application.html.erb +38 -0
  72. data/config/importmap.rb +8 -0
  73. data/config/routes.rb +17 -0
  74. data/db/migrate/20241205203943_create_inner_plan_tables.rb +37 -0
  75. data/db/seeds.rb +14 -0
  76. data/lib/inner_plan/configuration.rb +116 -0
  77. data/lib/inner_plan/engine.rb +22 -0
  78. data/lib/inner_plan/smart_array.rb +66 -0
  79. data/lib/inner_plan/version.rb +3 -0
  80. data/lib/inner_plan.rb +28 -0
  81. data/lib/tasks/inner_plan_tasks.rake +4 -0
  82. metadata +265 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a9d0ba39c610bddad96347deadb301272052f07ce5cd2d698fa701530781bbb3
4
+ data.tar.gz: 61eb9a7f7156356365b6660e9d30edb4502a6b1f1c154149ff25d97303c691c4
5
+ SHA512:
6
+ metadata.gz: 3d4427fb9f9569ca75b905d85c0261f1b3d545bb360b65b943b50adebbca3dee016ff4bcb9e75b9db7f1e630e0ffeb3574d574364370ced8721a3435f884647d
7
+ data.tar.gz: 529f948ed886946c239897df32c10e555f2544821cdd50416f0dd341aa2f358bd84eb4a716a268bcee934b980de3d07b37dcce55bf3a8f8b6dfbfc745bf3fe30
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # InnerPlan
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "inner_plan"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install inner_plan
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ //= link_directory ../stylesheets/inner_plan .css
2
+ //= link inner_plan/application.js
3
+ //= link inner_plan/controllers/lists_controller.js
4
+ //= link inner_plan/controllers/groups_controller.js
5
+ //= link inner_plan/controllers/tasks_controller.js
6
+ //= link inner_plan/controllers/task_inline_form_controller.js
@@ -0,0 +1,24 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
16
+
17
+ .ms-tasks-element {
18
+ margin-left: 1.9rem;
19
+ }
20
+
21
+ .cm { cursor: move; }
22
+
23
+ .hw-combobox { max-width: 100%; }
24
+ .hw-combobox__main__wrapper { max-width: 100%; }
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationView < Phlex::HTML
4
+ end
@@ -0,0 +1,26 @@
1
+ module InnerPlan
2
+ class BreadcrumbsComponent < Phlex::HTML
3
+ include Phlex::DeferredRender
4
+ include Phlex::Rails::Helpers::LinkTo
5
+
6
+ def initialize
7
+ @breadcrumbs = []
8
+ end
9
+
10
+ def template
11
+ nav(class: 'mb-1', style: "--bs-breadcrumb-divider: '›';") {
12
+ ol(class: "breadcrumb mb-0") {
13
+ @breadcrumbs.each do |breadcrumb|
14
+ li(class: 'breadcrumb-item text-body-tertiary') {
15
+ breadcrumb[:content].call
16
+ }
17
+ end
18
+ }
19
+ }
20
+ end
21
+
22
+ def with_breadcrumb(active: false, &content)
23
+ @breadcrumbs << { active: active, content: content }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,72 @@
1
+ module InnerPlan::Groups
2
+ class EditView < ApplicationView
3
+ include Phlex::Rails::Helpers::DOMID
4
+ include Phlex::Rails::Helpers::LinkTo
5
+ include Phlex::Rails::Helpers::Routes
6
+ include Phlex::Rails::Helpers::ContentTag
7
+ include Phlex::Rails::Helpers::FormWith
8
+
9
+ def initialize(group:)
10
+ @group = group
11
+ end
12
+
13
+ def template
14
+ content_tag(:turbo_frame, id: (dom_id(@group, :header))) do
15
+ form_with model: @group, url: helpers.group_path(@group) do |f|
16
+ header(class: "mb-3") do
17
+ render(InnerPlan::BreadcrumbsComponent.new) do |c|
18
+ c.with_breadcrumb do
19
+ link_to "Home",
20
+ helpers.root_path,
21
+ class: "text-reset",
22
+ data: {
23
+ turbo_frame: :_top
24
+ }
25
+ end
26
+ c.with_breadcrumb do
27
+ link_to @group.list.title,
28
+ @group.list,
29
+ class: "text-reset",
30
+ data: {
31
+ turbo_frame: :_top
32
+ }
33
+ end
34
+ c.with_breadcrumb do
35
+ link_to @group.title,
36
+ helpers.group_path(@group),
37
+ class: "text-reset",
38
+ data: {
39
+ turbo_frame: :_top
40
+ }
41
+ end
42
+ c.with_breadcrumb(active: true) { plain " Edit sub " }
43
+ end
44
+ div(class: "row") do
45
+ div(class: "col-6") do
46
+ h1(class: "h2") do
47
+ plain f.text_field :title,
48
+ class: "form-control form-control-lg mt-2"
49
+ end
50
+ end
51
+ end
52
+ render(
53
+ InnerPlan::ProgressBarSeparatorComponent.new(
54
+ completed: @group.tasks.completed.count,
55
+ total: @group.tasks.count
56
+ )
57
+ )
58
+ end
59
+ div(class: "mb-2") do
60
+ plain f.text_area :description,
61
+ class: 'form-control',
62
+ placeholder: "Add extra details or attach a file..."
63
+ end
64
+ div(class: "mb-5") do
65
+ plain f.submit "Save changes", class: "btn btn-success btn-sm me-2"
66
+ link_to "Cancel", @list, class: "btn btn-outline-secondary btn-sm"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,66 @@
1
+ module InnerPlan::Groups
2
+ class NewView < ApplicationView
3
+ include Phlex::Rails::Helpers::DOMID
4
+ include Phlex::Rails::Helpers::LinkTo
5
+ include Phlex::Rails::Helpers::Routes
6
+ include Phlex::Rails::Helpers::ContentTag
7
+ include Phlex::Rails::Helpers::FormWith
8
+
9
+ def initialize(group:)
10
+ @group = group
11
+ @list = group.list
12
+ end
13
+
14
+ def template
15
+ form_with model: @group, url: helpers.list_groups_path(@list) do |f|
16
+ header(class: "mb-3") do
17
+ render(InnerPlan::BreadcrumbsComponent.new) do |c|
18
+ c.with_breadcrumb do
19
+ link_to "Home",
20
+ helpers.root_path,
21
+ class: "text-reset",
22
+ data: {
23
+ turbo_frame: :_top
24
+ }
25
+ end
26
+ c.with_breadcrumb do
27
+ link_to @group.list.title,
28
+ @group.list,
29
+ class: "text-reset",
30
+ data: {
31
+ turbo_frame: :_top
32
+ }
33
+ end
34
+ c.with_breadcrumb(active: true) { plain " New group " }
35
+ end
36
+ div(class: "row") do
37
+ div(class: "col-6") do
38
+ h1(class: "h2") do
39
+ plain f.text_field :title,
40
+ placeholder: "Name this group...",
41
+ class: "form-control form-control-lg mt-2"
42
+ end
43
+ end
44
+ end
45
+ render(
46
+ InnerPlan::ProgressBarSeparatorComponent.new(
47
+ completed: @group.tasks.completed.count,
48
+ total: @group.tasks.count
49
+ )
50
+ )
51
+ end
52
+
53
+ div(class: "mb-2") do
54
+ plain f.text_area :description,
55
+ class: 'form-control',
56
+ placeholder: "Add extra details or attach a file..."
57
+ end
58
+
59
+ div(class: "mb-5") do
60
+ plain f.submit "Save changes", class: "btn btn-success btn-sm"
61
+ link_to "Cancel", @list, class: "btn btn-outline-secondary btn-sm"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,30 @@
1
+ module InnerPlan::Groups::Row
2
+ class HandleComponent < Phlex::HTML
3
+ include Phlex::Rails::Helpers::LinkTo
4
+
5
+ def initialize(list)
6
+ @list = list
7
+ end
8
+
9
+ def template
10
+ div(class: "dropstart me-2", style: "margin-top:-0.15rem") {
11
+ a(class: "align-top text-body-tertiary group-handle cm", data: { bs_toggle: :dropdown }) {
12
+ render(Phlex::Icons::Tabler::GripVertical.new(width: 20, height: 20))
13
+ }
14
+
15
+ ul(class: 'dropdown-menu') {
16
+ li {
17
+ link_to(helpers.edit_group_path(list), class: "dropdown-item d-flex gap-2 align-items-center") {
18
+ render(Phlex::Icons::Tabler::Pencil.new(width: 18, height: 18, class: 'text-secondary'))
19
+ span { 'Edit group' }
20
+ }
21
+ }
22
+ }
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :list
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module InnerPlan::Groups
2
+ class RowComponent < Phlex::HTML
3
+ include Phlex::Rails::Helpers::LinkTo
4
+ include Phlex::Rails::Helpers::DOMID
5
+
6
+ def initialize(list, context: nil)
7
+ @list = list
8
+ @context = context
9
+ end
10
+
11
+ def template
12
+ div(data: { update_url: helpers.update_position_group_path(list), id: list.id }) {
13
+ div(class: 'd-flex w-100 mb-1', style: 'line-height: 1.7rem') {
14
+ render(InnerPlan::Groups::Row::HandleComponent.new(list))
15
+
16
+ div(class: "ms-1 w-100") {
17
+ strong {
18
+ link_to(list.title, helpers.group_path(list), class: 'text-reset text-decoration-none')
19
+ }
20
+ }
21
+ }
22
+
23
+ render(InnerPlan::Lists::OngoingTasksComponent.new(list, context: context))
24
+ }
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :list, :context
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ module InnerPlan::Groups
2
+ class RowsComponent < Phlex::HTML
3
+ def initialize(groups, list:, context: nil)
4
+ @groups = groups
5
+ @list = list
6
+ @context = context
7
+ end
8
+
9
+ def template
10
+ div(data: { controller: :groups, tasks_list_id_value: @list.id }) {
11
+ @groups.each do |group|
12
+ render(InnerPlan::Groups::RowComponent.new(group, context: @context))
13
+ end
14
+ }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ module InnerPlan::Groups
2
+ class ShowMenuComponent < Phlex::HTML
3
+ include Phlex::Rails::Helpers::LinkTo
4
+
5
+ def initialize(group)
6
+ @group = group
7
+ end
8
+
9
+ def template
10
+ div(class: "dropdown") {
11
+ button(class: "btn btn-link text-reset p-0 opacity-50", data_bs_toggle: "dropdown") {
12
+ render(Phlex::Icons::Tabler::DotsCircleHorizontal.new(width: 35, height: 35))
13
+ }
14
+
15
+ ul(class: "dropdown-menu dropdown-menu-end") {
16
+ li {
17
+ link_to(helpers.edit_group_path(@group), class: 'dropdown-item d-flex align-items-center gap-2', data: { turbo_frame: :_top }) {
18
+ render(Phlex::Icons::Tabler::Pencil.new(width: 18, height: 18, class: 'text-secondary'))
19
+ span { "Edit group" }
20
+ }
21
+ }
22
+ }
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :task
29
+ end
30
+ end
@@ -0,0 +1,77 @@
1
+ module InnerPlan::Groups
2
+ class ShowView < ApplicationView
3
+ include Phlex::Rails::Helpers::DOMID
4
+ include Phlex::Rails::Helpers::LinkTo
5
+ include Phlex::Rails::Helpers::Routes
6
+ include Phlex::Rails::Helpers::ContentTag
7
+
8
+ def initialize(group:)
9
+ @group = group
10
+ end
11
+
12
+ def template
13
+ content_tag(:turbo_frame, id: dom_id(@group, :header)) do
14
+ header do
15
+ render(InnerPlan::BreadcrumbsComponent.new) do |c|
16
+ c.with_breadcrumb do
17
+ link_to "Home",
18
+ helpers.root_path,
19
+ class: "text-reset",
20
+ data: {
21
+ turbo_frame: :_top
22
+ }
23
+ end
24
+ c.with_breadcrumb(active: true) do
25
+ link_to @group.list.title,
26
+ @group.list,
27
+ class: "text-reset",
28
+ data: {
29
+ turbo_frame: :_top
30
+ }
31
+ end
32
+ end
33
+ div(class: "row") do
34
+ div(class: "col-10") do
35
+ h1(class: "h2") do
36
+ link_to @group.title,
37
+ helpers.edit_group_path(@group),
38
+ class: "text-reset text-decoration-none me-2"
39
+ small(class: "fs-6 text-body-tertiary") do
40
+ plain @group.tasks.completed.count
41
+ plain "/"
42
+ plain @group.tasks.count
43
+ end
44
+ end
45
+ end
46
+ div(class: "col-2 text-end") do
47
+ render(InnerPlan::Groups::ShowMenuComponent.new(@group))
48
+ end
49
+ end
50
+ render(
51
+ InnerPlan::ProgressBarSeparatorComponent.new(
52
+ completed: @group.tasks.completed.count,
53
+ total: @group.tasks.count
54
+ )
55
+ )
56
+ end
57
+ div(class: "mb-4 mt-3") { @group.description }
58
+ end
59
+
60
+ render(
61
+ InnerPlan::Lists::OngoingTasksComponent.new(@group, context: :groups_show)
62
+ )
63
+
64
+ content_tag(:div, class: "mt-2 mb-4", id: dom_id(@group, :add_task)) do
65
+ render InnerPlan::Tasks::InlineFormView.new(list: @group)
66
+ end
67
+
68
+ render(
69
+ InnerPlan::Lists::CompletedTasksComponent.new(
70
+ @group,
71
+ context: :groups_show,
72
+ limit: 0
73
+ )
74
+ )
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,30 @@
1
+ module InnerPlan::Lists
2
+ class CompletedTasksComponent < Phlex::HTML
3
+ def initialize(list, limit: 3, context: nil)
4
+ @list = list
5
+ @limit = limit
6
+ @context = context
7
+ end
8
+
9
+ def template
10
+ truncate = @limit.positive?
11
+ scope = @list.root? ? @list.tasks_including_groups : @list.tasks
12
+ scope = scope.completed
13
+ scope = truncate ? scope.limit(@limit) : scope
14
+
15
+ render InnerPlan::Tasks::RowsComponent.new(scope, list: @list, context: context, id_key: :completed_tasks) do
16
+ if truncate
17
+ completed_tasks_count = @list.tasks.completed.count
18
+
19
+ if (completed_tasks_count - @limit).positive?
20
+ div(class: "mt-2 ms-tasks-element") {
21
+ a(href: helpers.list_path(@list, anchor: :completed), class: "text-body-tertiary") {
22
+ plain "And #{completed_tasks_count - @limit} more completed to-dos..."
23
+ }
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,62 @@
1
+ module InnerPlan::Lists
2
+ class EditView < ApplicationView
3
+ include Phlex::Rails::Helpers::DOMID
4
+ include Phlex::Rails::Helpers::LinkTo
5
+ include Phlex::Rails::Helpers::Routes
6
+ include Phlex::Rails::Helpers::ContentTag
7
+ include Phlex::Rails::Helpers::FormWith
8
+
9
+ def initialize(list:)
10
+ @list = list
11
+ end
12
+
13
+ def template
14
+ content_tag(:turbo_frame, id: dom_id(@list, :header)) do
15
+ form_with model: @list do |f|
16
+ header(class: "mb-3") do
17
+ nav(aria_label: "breadcrumb", style: "--bs-breadcrumb-divider: '›';") do
18
+ ol(class: "breadcrumb mb-0") do
19
+ li(class: "breadcrumb-item text-body-tertiary") do
20
+ a(href: helpers.root_path, class: "text-reset", data_turbo_frame: "_top") do
21
+ "Home"
22
+ end
23
+ end
24
+ li(
25
+ class: "breadcrumb-item text-body-tertiary",
26
+ aria_current: "page"
27
+ ) { link_to "List ##{@list.id}", @list, class: "text-reset" }
28
+ li(
29
+ class: "breadcrumb-item active text-body-tertiary",
30
+ aria_current: "page"
31
+ ) { "Edit" }
32
+ end
33
+ end
34
+ div(class: "row") do
35
+ div(class: "col-6") do
36
+ h1(class: "h2") do
37
+ plain f.text_field :title,
38
+ class: "form-control form-control-lg mt-2"
39
+ end
40
+ end
41
+ end
42
+ render(
43
+ InnerPlan::ProgressBarSeparatorComponent.new(
44
+ completed: @list.tasks.completed.count,
45
+ total: @list.tasks.count
46
+ )
47
+ )
48
+ end
49
+ div(class: "mb-2") do
50
+ plain f.text_area :description,
51
+ class: 'form-control',
52
+ placeholder: "Add extra details or attach a file..."
53
+ end
54
+ div(class: "mb-5") do
55
+ plain f.submit "Save changes", class: "btn btn-success btn-sm"
56
+ link_to "Cancel", @list, class: "btn btn-outline-secondary btn-sm"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,57 @@
1
+ module InnerPlan::Lists
2
+ class IndexView < ApplicationView
3
+ include Phlex::Rails::Helpers::DOMID
4
+ include Phlex::Rails::Helpers::LinkTo
5
+ include Phlex::Rails::Helpers::Routes
6
+
7
+ def initialize(lists:)
8
+ @lists = lists
9
+ end
10
+
11
+ def template
12
+ header(class: %(mb-4)) {
13
+ div(class: %(row)) {
14
+ div(class: %(col-6)) {
15
+ h1(class: %(h2)) {
16
+ plain %(Tasks)
17
+ small(class: %(fs-6 text-body-tertiary ms-2)) {
18
+ plain InnerPlan::Task.completed.count
19
+ plain %(/)
20
+ plain InnerPlan::Task.all.count
21
+ }
22
+ }
23
+ }
24
+ div(class: %(col-6 text-end)) {
25
+ link_to('+ New list', helpers.new_list_path,
26
+ class: 'btn btn-success',
27
+ data: { turbo_frame: dom_id(InnerPlan::List.new, :form) })
28
+ }
29
+ }
30
+
31
+ render(
32
+ InnerPlan::ProgressBarSeparatorComponent.new(
33
+ completed: InnerPlan::Task.completed.count,
34
+ total: InnerPlan::Task.all.count
35
+ )
36
+ )
37
+ }
38
+
39
+ if @lists.none?
40
+ div(class: %(text-center mt-5 pt-5)) {
41
+ render(partial: 'inner_plan/shared/blankslate', formats: [:svg])
42
+
43
+ h3(class: %(mt-5)) { %(Nothing here) }
44
+ p(class: %(text-secondary)) {
45
+ plain %( Looks like there are no tasks here yet. )
46
+ }
47
+ }
48
+ end
49
+
50
+ div(data_controller: %(lists)) {
51
+ @lists.each do |list|
52
+ render(InnerPlan::Lists::RowComponent.new(list, context: :lists_index))
53
+ end
54
+ }
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,49 @@
1
+ module InnerPlan::Lists
2
+ class NewView < ApplicationView
3
+ include Phlex::Rails::Helpers::DOMID
4
+ include Phlex::Rails::Helpers::LinkTo
5
+ include Phlex::Rails::Helpers::Routes
6
+ include Phlex::Rails::Helpers::ContentTag
7
+ include Phlex::Rails::Helpers::FormWith
8
+
9
+ def initialize(list:)
10
+ @list = list
11
+ end
12
+
13
+ def template
14
+ header(class: "mb-3") do
15
+ render(InnerPlan::BreadcrumbsComponent.new) do |c|
16
+ c.with_breadcrumb do
17
+ link_to "Home",
18
+ helpers.root_path,
19
+ class: "text-reset",
20
+ data: {
21
+ turbo_frame: :_top
22
+ }
23
+ end
24
+ end
25
+ div(class: "row") { div(class: "col-6") { h1(class: "h2") { "New list" } } }
26
+ render(InnerPlan::ProgressBarSeparatorComponent.new)
27
+ end
28
+
29
+ form_with model: @list do |f|
30
+ plain f.object.errors.full_messages.to_sentence
31
+ div(class: "mb-3") do
32
+ plain f.text_field :title,
33
+ class: "form-control form-control-lg",
34
+ placeholder: "Name this list...",
35
+ autofocus: true
36
+ end
37
+
38
+ div(class: "mb-3") do
39
+ plain f.text_area :description,
40
+ class: 'form-control',
41
+ placeholder: "Add extra details or attach a file..."
42
+ end
43
+
44
+ plain f.submit "Create list", class: "btn btn-success btn-sm me-2"
45
+ link_to "Cancel", helpers.lists_path, class: "btn btn-outline-secondary btn-sm"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ module InnerPlan::Lists
2
+ class OngoingTasksComponent < Phlex::HTML
3
+ def initialize(list, context: nil)
4
+ @list = list
5
+ @context = context
6
+ end
7
+
8
+ def template
9
+ tasks = @list.tasks.ongoing.ordered_by_position
10
+ render(
11
+ InnerPlan::Tasks::RowsComponent.new(tasks, list: @list,
12
+ context: @context,
13
+ id_key: :ongoing_tasks)
14
+ )
15
+ end
16
+ end
17
+ end