inner_plan 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/inner_plan_manifest.js +6 -0
- data/app/assets/stylesheets/inner_plan/application.css +24 -0
- data/app/components/application_view.rb +4 -0
- data/app/components/inner_plan/breadcrumbs_component.rb +26 -0
- data/app/components/inner_plan/groups/edit_view.rb +72 -0
- data/app/components/inner_plan/groups/new_view.rb +66 -0
- data/app/components/inner_plan/groups/row/handle_component.rb +30 -0
- data/app/components/inner_plan/groups/row_component.rb +31 -0
- data/app/components/inner_plan/groups/rows_component.rb +17 -0
- data/app/components/inner_plan/groups/show_menu_component.rb +30 -0
- data/app/components/inner_plan/groups/show_view.rb +77 -0
- data/app/components/inner_plan/lists/completed_tasks_component.rb +30 -0
- data/app/components/inner_plan/lists/edit_view.rb +62 -0
- data/app/components/inner_plan/lists/index_view.rb +57 -0
- data/app/components/inner_plan/lists/new_view.rb +49 -0
- data/app/components/inner_plan/lists/ongoing_tasks_component.rb +17 -0
- data/app/components/inner_plan/lists/row/handle_component.rb +37 -0
- data/app/components/inner_plan/lists/row_component.rb +55 -0
- data/app/components/inner_plan/lists/show_menu_component.rb +37 -0
- data/app/components/inner_plan/lists/show_view.rb +76 -0
- data/app/components/inner_plan/progress_bar_separator_component.rb +20 -0
- data/app/components/inner_plan/tasks/completed_toggler_component.rb +27 -0
- data/app/components/inner_plan/tasks/edit_view.rb +82 -0
- data/app/components/inner_plan/tasks/form/item_component.rb +21 -0
- data/app/components/inner_plan/tasks/form/row_component.rb +19 -0
- data/app/components/inner_plan/tasks/inline_form_view.rb +62 -0
- data/app/components/inner_plan/tasks/row/addons_component.rb +22 -0
- data/app/components/inner_plan/tasks/row/base_addon_component.rb +19 -0
- data/app/components/inner_plan/tasks/row/description_addon_component.rb +13 -0
- data/app/components/inner_plan/tasks/row/due_on_addon_component.rb +14 -0
- data/app/components/inner_plan/tasks/row/group_addon_component.rb +11 -0
- data/app/components/inner_plan/tasks/row/handle_component.rb +40 -0
- data/app/components/inner_plan/tasks/row_component.rb +35 -0
- data/app/components/inner_plan/tasks/rows_component.rb +22 -0
- data/app/components/inner_plan/tasks/show/item_component.rb +20 -0
- data/app/components/inner_plan/tasks/show/row_component.rb +19 -0
- data/app/components/inner_plan/tasks/show_menu_component.rb +30 -0
- data/app/components/inner_plan/tasks/show_view.rb +76 -0
- data/app/components/inner_plan/user_with_avatar_component.rb +17 -0
- data/app/concepts/inner_plan/list/operation/index.rb +11 -0
- data/app/concepts/inner_plan/task/operation/complete.rb +12 -0
- data/app/concepts/inner_plan/task/operation/create.rb +46 -0
- data/app/concepts/inner_plan/task/operation/reopen.rb +12 -0
- data/app/concepts/inner_plan/task/operation/update.rb +25 -0
- data/app/concepts/inner_plan/task/operation/update_position.rb +25 -0
- data/app/controllers/inner_plan/application_controller.rb +12 -0
- data/app/controllers/inner_plan/groups_controller.rb +59 -0
- data/app/controllers/inner_plan/lists_controller.rb +59 -0
- data/app/controllers/inner_plan/tasks_controller.rb +73 -0
- data/app/helpers/inner_plan/application_helper.rb +4 -0
- data/app/javascript/inner_plan/application.js +15 -0
- data/app/javascript/inner_plan/controllers/groups_controller.js +47 -0
- data/app/javascript/inner_plan/controllers/lists_controller.js +30 -0
- data/app/javascript/inner_plan/controllers/task_inline_form_controller.js +40 -0
- data/app/javascript/inner_plan/controllers/tasks_controller.js +47 -0
- data/app/jobs/inner_plan/application_job.rb +4 -0
- data/app/mailers/inner_plan/application_mailer.rb +6 -0
- data/app/models/inner_plan/application_record.rb +5 -0
- data/app/models/inner_plan/list.rb +29 -0
- data/app/models/inner_plan/task.rb +36 -0
- data/app/services/inner_plan/tasks/description_renderer.rb +18 -0
- data/app/services/inner_plan/tasks/title_renderer.rb +18 -0
- data/app/views/inner_plan/shared/_blankslate.svg.erb +1 -0
- data/app/views/inner_plan/tasks/complete.turbo_stream.erb +16 -0
- data/app/views/inner_plan/tasks/create.turbo_stream.erb +11 -0
- data/app/views/inner_plan/tasks/create_failure.turbo_stream.erb +5 -0
- data/app/views/layouts/action_text/contents/_content.html.erb +3 -0
- data/app/views/layouts/inner_plan/application.html.erb +38 -0
- data/config/importmap.rb +8 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20241205203943_create_inner_plan_tables.rb +37 -0
- data/db/seeds.rb +14 -0
- data/lib/inner_plan/configuration.rb +116 -0
- data/lib/inner_plan/engine.rb +22 -0
- data/lib/inner_plan/smart_array.rb +66 -0
- data/lib/inner_plan/version.rb +3 -0
- data/lib/inner_plan.rb +28 -0
- data/lib/tasks/inner_plan_tasks.rake +4 -0
- 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,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,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
|