Merge pull request #134 from paviliondev/admin-ui-support
IMPROVE: Admin UI support
Dieser Commit ist enthalten in:
Commit
5f5adf93e4
9 geänderte Dateien mit 149 neuen und 71 gelöschten Zeilen
|
@ -1,6 +1,36 @@
|
|||
import Controller from "@ember/controller";
|
||||
import { fmt } from "discourse/lib/computed";
|
||||
import { empty } from "@ember/object/computed";
|
||||
import CustomWizard from "../models/custom-wizard";
|
||||
|
||||
export default Controller.extend({
|
||||
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();
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -211,10 +211,54 @@ CustomWizard.reopenClass({
|
|||
.catch(popupAjaxError);
|
||||
},
|
||||
|
||||
submissions(wizardId) {
|
||||
submissions(wizardId, page = null) {
|
||||
let data = {};
|
||||
|
||||
if (page) {
|
||||
data.page = page;
|
||||
}
|
||||
|
||||
return ajax(`/admin/wizards/submissions/${wizardId}`, {
|
||||
type: "GET",
|
||||
}).catch(popupAjaxError);
|
||||
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);
|
||||
},
|
||||
|
||||
create(wizardJson = {}) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import CustomWizard from "../models/custom-wizard";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
const excludedMetaFields = ["route_to", "redirect_on_complete", "redirect_to"];
|
||||
import { A } from "@ember/array";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
model(params) {
|
||||
|
@ -9,34 +8,11 @@ export default DiscourseRoute.extend({
|
|||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
if (model && model.submissions) {
|
||||
let fields = ["username"];
|
||||
model.submissions.forEach((s) => {
|
||||
Object.keys(s.fields).forEach((k) => {
|
||||
if (!excludedMetaFields.includes(k) && fields.indexOf(k) < 0) {
|
||||
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,
|
||||
fields: model.fields,
|
||||
submissions: A(model.submissions),
|
||||
total: model.total,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
</div>
|
||||
|
||||
<div class="wizard-submissions">
|
||||
{{#load-more selector=".wizard-submissions tr" action=(action "loadMore")}}
|
||||
{{#if noResults}}
|
||||
<p>{{i18n "search.no_results"}}</p>
|
||||
{{else}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -29,5 +33,9 @@
|
|||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{/if}}
|
||||
|
||||
{{conditional-loading-spinner condition=loadingMore}}
|
||||
{{/load-more}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -13,12 +13,16 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
|
|||
def show
|
||||
render_json_dump(
|
||||
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
|
||||
|
||||
def download
|
||||
send_data ordered_submissions.to_json,
|
||||
send_data submission_list.submissions.to_json,
|
||||
filename: "#{Discourse.current_hostname}-wizard-submissions-#{@wizard.name}.json",
|
||||
content_type: "application/json",
|
||||
disposition: "attachment"
|
||||
|
@ -26,7 +30,7 @@ class CustomWizard::AdminSubmissionsController < CustomWizard::AdminController
|
|||
|
||||
protected
|
||||
|
||||
def ordered_submissions
|
||||
CustomWizard::Submission.list(@wizard, order_by: 'id')
|
||||
def submission_list
|
||||
CustomWizard::Submission.list(@wizard, page: params[:page].to_i)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
class CustomWizard::Submission
|
||||
include ActiveModel::SerializerSupport
|
||||
|
||||
PAGE_LIMIT = 50
|
||||
KEY ||= "submissions"
|
||||
META ||= %w(submitted_at route_to redirect_on_complete redirect_to)
|
||||
|
||||
|
@ -44,7 +45,7 @@ class CustomWizard::Submission
|
|||
validate
|
||||
|
||||
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)
|
||||
|
||||
submission_data = submissions.map { |submission| data_to_save(submission) }
|
||||
|
@ -92,27 +93,38 @@ class CustomWizard::Submission
|
|||
end
|
||||
|
||||
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)
|
||||
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[:key] = user_id if user_id.present?
|
||||
|
||||
query = PluginStoreRow.where(params)
|
||||
query = query.order("#{order_by} DESC") if order_by.present?
|
||||
|
||||
result = []
|
||||
result = OpenStruct.new(submissions: [], total: nil)
|
||||
|
||||
query.each do |record|
|
||||
if (submission_data = ::JSON.parse(record.value)).any?
|
||||
submission_data.each do |data|
|
||||
result.push(new(wizard, data, record.key))
|
||||
result.submissions.push(new(wizard, data, record.key))
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -272,7 +272,7 @@ class CustomWizard::Wizard
|
|||
|
||||
def submissions
|
||||
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
|
||||
|
||||
def current_submission
|
||||
|
|
|
@ -3,10 +3,7 @@ class CustomWizard::SubmissionSerializer < ApplicationSerializer
|
|||
attributes :id,
|
||||
:username,
|
||||
:fields,
|
||||
:submitted_at,
|
||||
:route_to,
|
||||
:redirect_on_complete,
|
||||
:redirect_to
|
||||
:submitted_at
|
||||
|
||||
def username
|
||||
object.user.present? ?
|
||||
|
|
|
@ -21,8 +21,11 @@ describe CustomWizard::Submission do
|
|||
@wizard = CustomWizard::Wizard.create(template_json["id"], user)
|
||||
@wizard2 = CustomWizard::Wizard.create(template_json["id"], user2)
|
||||
@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(@wizard3, step_1_field_1: "I am a user submission on another wizard").save
|
||||
end
|
||||
|
@ -30,14 +33,18 @@ describe CustomWizard::Submission do
|
|||
it "saves a user's submission" do
|
||||
expect(
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
|
Laden …
In neuem Issue referenzieren