0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-25 10:40:28 +01:00

Add pagination to submissions

Dieser Commit ist enthalten in:
angusmcleod 2021-07-14 14:04:19 +08:00
Ursprung 7375c63403
Commit 34fee3729c
9 geänderte Dateien mit 146 neuen und 72 gelöschten Zeilen

Datei anzeigen

@ -1,6 +1,34 @@
import Controller from "@ember/controller"; import Controller from "@ember/controller";
import { fmt } from "discourse/lib/computed"; import { fmt } from "discourse/lib/computed";
import { empty } from '@ember/object/computed';
import CustomWizard from "../models/custom-wizard";
export default Controller.extend({ export default Controller.extend({
downloadUrl: fmt("wizard.id", "/admin/wizards/submissions/%@/download"), downloadUrl: fmt("wizard.id", "/admin/wizards/submissions/%@/download"),
noResults: empty('submissions'),
page: 0,
total: 0,
loadMoreSubmissions() {
const page = this.get('page');
const wizardId = this.get('wizard.id');
this.set('loadingMore', true);
CustomWizard.submissions(wizardId, page).then(result => {
if (result.submissions) {
this.get('submissions').pushObjects(result.submissions);
}
}).finally(() => {
this.set('loadingMore', false);
});
},
actions: {
loadMore() {
if (!this.loadingMore && (this.submissions.length < this.total)) {
this.set('page', this.get('page') + 1);
this.loadMoreSubmissions();
}
}
}
}); });

Datei anzeigen

@ -211,9 +211,51 @@ CustomWizard.reopenClass({
.catch(popupAjaxError); .catch(popupAjaxError);
}, },
submissions(wizardId) { submissions(wizardId, page = null) {
let data = {};
if (page) {
data.page = page;
}
return ajax(`/admin/wizards/submissions/${wizardId}`, { return ajax(`/admin/wizards/submissions/${wizardId}`, {
type: "GET", type: "GET",
data
}).then(result => {
if (result.wizard) {
let fields = ["username"];
let submissions = [];
let wizard = result.wizard;
let total = result.total;
result.submissions.forEach((s) => {
let submission = {
username: s.username,
};
Object.keys(s.fields).forEach((f) => {
if (fields.indexOf(f) < 0) {
fields.push(f);
}
if (fields.includes(f)) {
submission[f] = s.fields[f];
}
});
submission['submitted_at'] = s.submitted_at;
submissions.push(submission);
});
fields.push("submitted_at");
return {
wizard,
fields,
submissions,
total
};
}
}).catch(popupAjaxError); }).catch(popupAjaxError);
}, },

Datei anzeigen

@ -1,7 +1,6 @@
import CustomWizard from "../models/custom-wizard"; import CustomWizard from "../models/custom-wizard";
import DiscourseRoute from "discourse/routes/discourse"; import DiscourseRoute from "discourse/routes/discourse";
import { A } from "@ember/array";
const excludedMetaFields = ["route_to", "redirect_on_complete", "redirect_to"];
export default DiscourseRoute.extend({ export default DiscourseRoute.extend({
model(params) { model(params) {
@ -9,34 +8,11 @@ export default DiscourseRoute.extend({
}, },
setupController(controller, model) { setupController(controller, model) {
if (model && model.submissions) { controller.setProperties({
let fields = ["username"]; wizard: model.wizard,
model.submissions.forEach((s) => { fields: model.fields,
Object.keys(s.fields).forEach((k) => { submissions: A(model.submissions),
if (!excludedMetaFields.includes(k) && fields.indexOf(k) < 0) { total: model.total
fields.push(k); });
}
});
});
let submissions = [];
model.submissions.forEach((s) => {
let submission = {
username: s.username,
};
Object.keys(s.fields).forEach((f) => {
if (fields.includes(f)) {
submission[f] = s.fields[f];
}
});
submissions.push(submission);
});
controller.setProperties({
wizard: model.wizard,
submissions,
fields,
});
}
}, },
}); });

Datei anzeigen

@ -11,23 +11,31 @@
</div> </div>
<div class="wizard-submissions"> <div class="wizard-submissions">
<table> {{#load-more selector=".wizard-submissions tr" action=(action "loadMore")}}
<thead> {{#if noResults}}
<tr> <p>{{i18n "search.no_results"}}</p>
{{#each fields as |f|}} {{else}}
<th>{{f}}</th> <table>
{{/each}} <thead>
</tr> <tr>
</thead> {{#each fields as |f|}}
<tbody> <th>{{f}}</th>
{{#each submissions as |s|}} {{/each}}
<tr> </tr>
{{#each-in s as |k v|}} </thead>
<td>{{v}}</td> <tbody>
{{/each-in}} {{#each submissions as |s|}}
</tr> <tr>
{{/each}} {{#each-in s as |k v|}}
</tbody> <td>{{v}}</td>
</table> {{/each-in}}
</tr>
{{/each}}
</tbody>
</table>
{{/if}}
{{conditional-loading-spinner condition=loadingMore}}
{{/load-more}}
</div> </div>
{{/if}} {{/if}}

Datei anzeigen

@ -13,12 +13,16 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
def show def show
render_json_dump( render_json_dump(
wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false), wizard: CustomWizard::BasicWizardSerializer.new(@wizard, root: false),
submissions: ActiveModel::ArraySerializer.new(ordered_submissions, each_serializer: CustomWizard::SubmissionSerializer) submissions: ActiveModel::ArraySerializer.new(
submission_list.submissions,
each_serializer: CustomWizard::SubmissionSerializer
),
total: submission_list.total
) )
end end
def download def download
send_data ordered_submissions.to_json, send_data submission_list.submissions.to_json,
filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json", filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json",
content_type: "application/json", content_type: "application/json",
disposition: "attachment" disposition: "attachment"
@ -26,7 +30,7 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
protected protected
def ordered_submissions def submission_list
CustomWizard::Submission.list(@wizard, order_by: 'id') CustomWizard::Submission.list(@wizard, page: params[:page].to_i)
end end
end end

Datei anzeigen

@ -1,7 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::Submission class CustomWizard::Submission
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
PAGE_LIMIT = 50
KEY ||= "submissions" KEY ||= "submissions"
META ||= %w(submitted_at route_to redirect_on_complete redirect_to) META ||= %w(submitted_at route_to redirect_on_complete redirect_to)
@ -44,7 +45,7 @@ class CustomWizard::Submission
validate validate
submission_list = self.class.list(wizard, user_id: user.id) submission_list = self.class.list(wizard, user_id: user.id)
submissions = submission_list.select { |submission| submission.id != self.id } submissions = submission_list.submissions.select { |submission| submission.id != self.id }
submissions.push(self) submissions.push(self)
submission_data = submissions.map { |submission| data_to_save(submission) } submission_data = submissions.map { |submission| data_to_save(submission) }
@ -92,27 +93,38 @@ class CustomWizard::Submission
end end
def self.get(wizard, user_id) def self.get(wizard, user_id)
data = PluginStore.get("#{wizard.id}_#{KEY}", user_id).first data = PluginStore.get("#{wizard.id}_#{KEY}", user_id).last
new(wizard, data, user_id) new(wizard, data, user_id)
end end
def self.list(wizard, user_id: nil, order_by: nil) def self.list(wizard, user_id: nil, page: nil)
params = { plugin_name: "#{wizard.id}_#{KEY}" } params = { plugin_name: "#{wizard.id}_#{KEY}" }
params[:key] = user_id if user_id.present? params[:key] = user_id if user_id.present?
query = PluginStoreRow.where(params) query = PluginStoreRow.where(params)
query = query.order("#{order_by} DESC") if order_by.present? result = OpenStruct.new(submissions: [], total: nil)
result = []
query.each do |record| query.each do |record|
if (submission_data = ::JSON.parse(record.value)).any? if (submission_data = ::JSON.parse(record.value)).any?
submission_data.each do |data| submission_data.each do |data|
result.push(new(wizard, data, record.key)) result.submissions.push(new(wizard, data, record.key))
end end
end end
end end
result.total = result.submissions.size
if !page.nil?
start = page * PAGE_LIMIT
length = PAGE_LIMIT
if result.submissions.length > start
result.submissions = result.submissions[start, length]
else
result.submissions = []
end
end
result result
end end
end end

Datei anzeigen

@ -272,7 +272,7 @@ class CustomWizard::Wizard
def submissions def submissions
return nil unless user.present? return nil unless user.present?
@submissions ||= CustomWizard::Submission.list(self, user_id: user.id) @submissions ||= CustomWizard::Submission.list(self, user_id: user.id).submissions
end end
def current_submission def current_submission

Datei anzeigen

@ -3,10 +3,7 @@ class CustomWizard::SubmissionSerializer < ApplicationSerializer
attributes :id, attributes :id,
:username, :username,
:fields, :fields,
:submitted_at, :submitted_at
:route_to,
:redirect_on_complete,
:redirect_to
def username def username
object.user.present? ? object.user.present? ?

Datei anzeigen

@ -21,8 +21,11 @@ describe CustomWizard::Submission do
@wizard = CustomWizard::Wizard.create(template_json["id"], user) @wizard = CustomWizard::Wizard.create(template_json["id"], user)
@wizard2 = CustomWizard::Wizard.create(template_json["id"], user2) @wizard2 = CustomWizard::Wizard.create(template_json["id"], user2)
@wizard3 = CustomWizard::Wizard.create(template_json_2["id"], user) @wizard3 = CustomWizard::Wizard.create(template_json_2["id"], user)
@count = CustomWizard::Submission::PAGE_LIMIT + 20
described_class.new(@wizard, step_1_field_1: "I am a user submission").save @count.times do |index|
described_class.new(@wizard, step_1_field_1: "I am user submission #{index+1}").save
end
described_class.new(@wizard2, step_1_field_1: "I am another user's submission").save described_class.new(@wizard2, step_1_field_1: "I am another user's submission").save
described_class.new(@wizard3, step_1_field_1: "I am a user submission on another wizard").save described_class.new(@wizard3, step_1_field_1: "I am a user submission on another wizard").save
end end
@ -30,14 +33,18 @@ describe CustomWizard::Submission do
it "saves a user's submission" do it "saves a user's submission" do
expect( expect(
described_class.get(@wizard, user.id).fields["step_1_field_1"] described_class.get(@wizard, user.id).fields["step_1_field_1"]
).to eq("I am a user submission") ).to eq("I am user submission #{@count}")
end end
it "list submissions by wizard" do it "list submissions by wizard" do
expect(described_class.list(@wizard).size).to eq(2) expect(described_class.list(@wizard).total).to eq(@count + 1)
end end
it "list submissions by wizard and user" do it "list submissions by wizard and user" do
expect(described_class.list(@wizard, user_id: user.id).size).to eq(1) expect(described_class.list(@wizard, user_id: user.id).total).to eq(@count)
end
it "paginates submission lists" do
expect(described_class.list(@wizard, page: 1).submissions.size).to eq((@count + 1) - CustomWizard::Submission::PAGE_LIMIT)
end end
end end