Skip to content

Commit 154d706

Browse files
authored
Merge from docusealco/wip
2 parents 0741a6f + aaae257 commit 154d706

File tree

58 files changed

+615
-169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+615
-169
lines changed

app/controllers/api/form_events_controller.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ def index
1111
params[:before] = Time.zone.at(params[:before].to_i) if params[:before].present?
1212

1313
submitters = paginate(
14-
submitters.preload(template: :folder, submission: [:submitters, { audit_trail_attachment: :blob,
15-
combined_document_attachment: :blob }],
14+
submitters.preload(template: { folder: :parent_folder },
15+
submission: [:submitters, { audit_trail_attachment: :blob,
16+
combined_document_attachment: :blob }],
1617
documents_attachments: :blob, attachments_attachments: :blob),
1718
field: :completed_at
1819
)

app/controllers/api/submissions_controller.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def index
1414
submissions = filter_submissions(submissions, params)
1515

1616
submissions = paginate(submissions.preload(:created_by_user, :submitters,
17-
template: :folder,
17+
template: { folder: :parent_folder },
1818
combined_document_attachment: :blob,
1919
audit_trail_attachment: :blob))
2020

@@ -104,9 +104,10 @@ def filter_submissions(submissions, params)
104104
submissions = submissions.where(slug: params[:slug]) if params[:slug].present?
105105

106106
if params[:template_folder].present?
107-
folder_ids = TemplateFolder.accessible_by(current_ability).where(name: params[:template_folder]).pluck(:id)
107+
folders =
108+
TemplateFolders.filter_by_full_name(TemplateFolder.accessible_by(current_ability), params[:template_folder])
108109

109-
submissions = submissions.joins(:template).where(template: { folder_id: folder_ids })
110+
submissions = submissions.joins(:template).where(template: { folder_id: folders.pluck(:id) })
110111
end
111112

112113
if params.key?(:archived)

app/controllers/api/templates_controller.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class TemplatesController < ApiBaseController
77
def index
88
templates = filter_templates(@templates, params)
99

10-
templates = paginate(templates.preload(:author, :folder))
10+
templates = paginate(templates.preload(:author, folder: :parent_folder))
1111

1212
schema_documents =
1313
ActiveStorage::Attachment.where(record_id: templates.map(&:id),
@@ -92,9 +92,9 @@ def filter_templates(templates, params)
9292
templates = templates.where(slug: params[:slug]) if params[:slug].present?
9393

9494
if params[:folder].present?
95-
folder_ids = TemplateFolder.accessible_by(current_ability).where(name: params[:folder]).pluck(:id)
95+
folders = TemplateFolders.filter_by_full_name(TemplateFolder.accessible_by(current_ability), params[:folder])
9696

97-
templates = templates.where(folder_id: folder_ids)
97+
templates = templates.where(folder_id: folders.pluck(:id))
9898
end
9999

100100
templates

app/controllers/template_folders_autocomplete_controller.rb

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,31 @@
33
class TemplateFoldersAutocompleteController < ApplicationController
44
load_and_authorize_resource :template_folder, parent: false
55

6-
LIMIT = 100
6+
LIMIT = 30
77

88
def index
9-
templates_query = Template.accessible_by(current_ability).where(archived_at: nil)
9+
parent_name, name =
10+
if params[:parent_name].present?
11+
[params[:parent_name], params[:q]]
12+
else
13+
params[:q].to_s.split(' /', 2).map(&:squish)
14+
end
1015

11-
template_folders = @template_folders.where(id: templates_query.select(:folder_id))
12-
template_folders = TemplateFolders.search(template_folders, params[:q]).limit(LIMIT)
16+
if name
17+
parent_folder = @template_folders.find_by(name: parent_name, parent_folder_id: nil)
18+
else
19+
name = parent_name
20+
end
1321

14-
render json: template_folders.as_json(only: %i[name archived_at])
22+
template_folders = TemplateFolders.filter_active_folders(@template_folders.where(parent_folder:),
23+
Template.accessible_by(current_ability))
24+
25+
name = name.to_s.downcase
26+
27+
template_folders = TemplateFolders.search(template_folders, name).order(id: :desc).limit(LIMIT)
28+
29+
render json: template_folders.preload(:parent_folder)
30+
.sort_by { |e| e.name.downcase.index(name) || Float::MAX }
31+
.as_json(only: %i[name archived_at], methods: %i[full_name])
1532
end
1633
end

app/controllers/template_folders_controller.rb

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,39 @@ class TemplateFoldersController < ApplicationController
55

66
helper_method :selected_order
77

8+
TEMPLATES_PER_PAGE = 12
9+
FOLDERS_PER_PAGE = 18
10+
811
def show
9-
@templates = @template_folder.templates.active.accessible_by(current_ability)
10-
.preload(:author, :template_accesses)
11-
@templates = Templates.search(current_user, @templates, params[:q])
12-
@templates = Templates::Order.call(@templates, current_user, selected_order)
12+
@templates = Template.active.accessible_by(current_ability)
13+
.where(folder: [@template_folder, *(params[:q].present? ? @template_folder.subfolders : [])])
14+
.preload(:author, :template_accesses)
15+
16+
@template_folders =
17+
@template_folder.subfolders.where(id: Template.accessible_by(current_ability).active.select(:folder_id))
18+
19+
@template_folders = TemplateFolders.search(@template_folders, params[:q])
20+
@template_folders = TemplateFolders.sort(@template_folders, current_user, selected_order)
21+
22+
if @templates.exists?
23+
@templates = Templates.search(current_user, @templates, params[:q])
24+
@templates = Templates::Order.call(@templates, current_user, selected_order)
1325

14-
@pagy, @templates = pagy_auto(@templates, limit: 12)
26+
limit =
27+
if @template_folders.size < 4
28+
TEMPLATES_PER_PAGE
29+
else
30+
(@template_folders.size < 7 ? 9 : 6)
31+
end
32+
33+
@pagy, @templates = pagy_auto(@templates, limit:)
34+
35+
load_related_submissions if params[:q].present? && @templates.blank?
36+
else
37+
@pagy, @template_folders = pagy(@template_folders, limit: FOLDERS_PER_PAGE)
38+
39+
@templates = @templates.none
40+
end
1541
end
1642

1743
def edit; end
@@ -40,4 +66,21 @@ def selected_order
4066
def template_folder_params
4167
params.require(:template_folder).permit(:name)
4268
end
69+
70+
def load_related_submissions
71+
@related_submissions =
72+
Submission.accessible_by(current_ability)
73+
.where(archived_at: nil)
74+
.where(template_id: current_account.templates.active
75+
.where(folder: [@template_folder, *@template_folder.subfolders])
76+
.select(:id))
77+
.preload(:template_accesses, :created_by_user,
78+
template: :author,
79+
submitters: :start_form_submission_events)
80+
81+
@related_submissions = Submissions.search(current_user, @related_submissions, params[:q])
82+
.order(id: :desc)
83+
84+
@related_submissions_pagy, @related_submissions = pagy_auto(@related_submissions, limit: 5)
85+
end
4386
end

app/controllers/templates_archived_controller.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,27 @@ class TemplatesArchivedController < ApplicationController
44
load_and_authorize_resource :template, parent: false
55

66
def index
7-
@templates = @templates.where.not(archived_at: nil).preload(:author, :folder, :template_accesses).order(id: :desc)
7+
@templates = @templates.where.not(archived_at: nil)
8+
.preload(:author, :template_accesses, folder: :parent_folder)
9+
.order(id: :desc)
10+
811
@templates = Templates.search(current_user, @templates, params[:q])
912

1013
@pagy, @templates = pagy_auto(@templates, limit: 12)
14+
15+
return unless params[:q].present? && @templates.blank?
16+
17+
@related_submissions =
18+
Submission.accessible_by(current_ability)
19+
.joins(:template)
20+
.where.not(templates: { archived_at: nil })
21+
.preload(:template_accesses, :created_by_user,
22+
template: :author,
23+
submitters: :start_form_submission_events)
24+
25+
@related_submissions = Submissions.search(current_user, @related_submissions, params[:q])
26+
.order(id: :desc)
27+
28+
@related_submissions_pagy, @related_submissions = pagy_auto(@related_submissions, limit: 5)
1129
end
1230
end

app/controllers/templates_dashboard_controller.rb

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ class TemplatesDashboardController < ApplicationController
1111
helper_method :selected_order
1212

1313
def index
14-
@template_folders = @template_folders.where(id: @templates.active.select(:folder_id))
14+
@template_folders =
15+
TemplateFolders.filter_active_folders(@template_folders.where(parent_folder_id: nil), @templates)
1516

1617
@template_folders = TemplateFolders.search(@template_folders, params[:q])
17-
@template_folders = sort_template_folders(@template_folders, current_user, selected_order)
18+
@template_folders = TemplateFolders.sort(@template_folders, current_user, selected_order)
1819

1920
@pagy, @template_folders = pagy(
2021
@template_folders,
@@ -68,40 +69,6 @@ def filter_templates(templates)
6869
Templates.search(current_user, rel, params[:q])
6970
end
7071

71-
def sort_template_folders(template_folders, current_user, order)
72-
case order
73-
when 'used_at'
74-
subquery =
75-
Template.left_joins(:submissions)
76-
.group(:folder_id)
77-
.where(account_id: current_user.account_id)
78-
.select(
79-
:folder_id,
80-
Template.arel_table[:updated_at].maximum.as('updated_at_max'),
81-
Submission.arel_table[:created_at].maximum.as('submission_created_at_max')
82-
)
83-
84-
template_folders = template_folders.joins(
85-
Template.arel_table
86-
.join(subquery.arel.as('templates'), Arel::Nodes::OuterJoin)
87-
.on(TemplateFolder.arel_table[:id].eq(Template.arel_table[:folder_id]))
88-
.join_sources
89-
)
90-
91-
template_folders.order(
92-
Arel::Nodes::Case.new
93-
.when(Template.arel_table[:submission_created_at_max].gt(Template.arel_table[:updated_at_max]))
94-
.then(Template.arel_table[:submission_created_at_max])
95-
.else(Template.arel_table[:updated_at_max])
96-
.desc
97-
)
98-
when 'name'
99-
template_folders.order(name: :asc)
100-
else
101-
template_folders.order(id: :desc)
102-
end
103-
end
104-
10572
def selected_order
10673
@selected_order ||=
10774
if cookies.permanent[:dashboard_templates_order].blank? ||

app/controllers/templates_folders_controller.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ class TemplatesFoldersController < ApplicationController
66
def edit; end
77

88
def update
9-
@template.folder = TemplateFolders.find_or_create_by_name(current_user, params[:name])
9+
name = [params[:parent_name], params[:name]].compact_blank.join(' / ')
10+
11+
@template.folder = TemplateFolders.find_or_create_by_name(current_user, name)
1012

1113
if @template.save
1214
redirect_back(fallback_location: template_path(@template), notice: I18n.t('document_template_has_been_moved'))

app/javascript/elements/dashboard_dropzone.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default targetable(class extends HTMLElement {
1515
static [target.static] = [
1616
'form',
1717
'fileDropzone',
18+
'folderDropzone',
1819
'fileDropzoneLoading'
1920
]
2021

@@ -25,12 +26,13 @@ export default targetable(class extends HTMLElement {
2526
window.addEventListener('dragleave', this.onWindowDragleave)
2627

2728
this.fileDropzone?.addEventListener('drop', this.onDropFile)
29+
this.folderDropzone?.addEventListener('drop', this.onDropNewFolder)
2830

2931
this.folderCards.forEach((el) => el.addEventListener('drop', (e) => this.onDropFolder(e, el)))
3032
this.templateCards.forEach((el) => el.addEventListener('drop', this.onDropTemplate))
3133
this.templateCards.forEach((el) => el.addEventListener('dragstart', this.onTemplateDragStart))
3234

33-
return [this.fileDropzone, ...this.folderCards, ...this.templateCards].forEach((el) => {
35+
return [this.fileDropzone, this.folderDropzone, ...this.folderCards, ...this.templateCards].forEach((el) => {
3436
el?.addEventListener('dragover', this.onDragover)
3537
el?.addEventListener('dragleave', this.onDragleave)
3638
})
@@ -46,6 +48,10 @@ export default targetable(class extends HTMLElement {
4648
onTemplateDragStart = (e) => {
4749
const id = e.target.href.split('/').pop()
4850

51+
this.folderCards.forEach((el) => el.classList.remove('bg-base-200', 'before:hidden'))
52+
this.folderDropzone?.classList?.remove('hidden')
53+
window.flash?.remove()
54+
4955
e.dataTransfer.effectAllowed = 'move'
5056

5157
if (id) {
@@ -104,7 +110,7 @@ export default targetable(class extends HTMLElement {
104110
} else {
105111
const formData = new FormData()
106112

107-
formData.append('name', el.innerText.trim())
113+
formData.append('name', el.dataset.fullName)
108114

109115
fetch(`/templates/${templateId}/folder`, {
110116
method: 'PUT',
@@ -176,6 +182,24 @@ export default targetable(class extends HTMLElement {
176182
}
177183
}
178184

185+
onDropNewFolder (e) {
186+
e.preventDefault()
187+
188+
const templateId = e.dataTransfer.getData('template_id')
189+
190+
const a = document.createElement('a')
191+
192+
a.href = `/templates/${templateId}/folder/edit?autocomplete=false`
193+
a.dataset.turboFrame = 'modal'
194+
a.classList.add('hidden')
195+
196+
document.body.append(a)
197+
198+
a.click()
199+
200+
a.remove()
201+
}
202+
179203
onDragleave () {
180204
this.style.backgroundColor = null
181205

@@ -199,6 +223,7 @@ export default targetable(class extends HTMLElement {
199223

200224
this.isDrag = true
201225

226+
window.flash?.remove()
202227
this.fileDropzone?.classList?.remove('hidden')
203228

204229
this.hiddenOnDrag.forEach((el) => { el.style.display = 'none' })
@@ -212,6 +237,7 @@ export default targetable(class extends HTMLElement {
212237
this.isDrag = false
213238

214239
this.fileDropzone?.classList?.add('hidden')
240+
this.folderDropzone?.classList?.add('hidden')
215241

216242
this.hiddenOnDrag.forEach((el) => { el.style.display = null })
217243

app/javascript/elements/folder_autocomplete.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import autocomplete from 'autocompleter'
22

33
export default class extends HTMLElement {
44
connectedCallback () {
5+
if (this.dataset.enabled === 'false') return
6+
57
autocomplete({
68
input: this.input,
79
preventSubmit: this.dataset.submitOnSelect === 'true' ? 0 : 1,
@@ -14,12 +16,16 @@ export default class extends HTMLElement {
1416
}
1517

1618
onSelect = (item) => {
17-
this.input.value = item.name
19+
this.input.value = this.dataset.parentName ? item.name : item.full_name
1820
}
1921

2022
fetch = (text, resolve) => {
2123
const queryParams = new URLSearchParams({ q: text })
2224

25+
if (this.dataset.parentName) {
26+
queryParams.append('parent_name', this.dataset.parentName)
27+
}
28+
2329
fetch('/template_folders_autocomplete?' + queryParams).then(async (resp) => {
2430
const items = await resp.json()
2531

@@ -34,7 +40,7 @@ export default class extends HTMLElement {
3440

3541
div.setAttribute('dir', 'auto')
3642

37-
div.textContent = item.name
43+
div.textContent = this.dataset.parentName ? item.name : item.full_name
3844

3945
return div
4046
}

0 commit comments

Comments
 (0)