-
Notifications
You must be signed in to change notification settings - Fork 0
FEATURE: Can edit category/host relationships for embedding #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rest-serializer-enhancement-pre
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import RestAdapter from 'discourse/adapters/rest'; | ||
|
|
||
| export default RestAdapter.extend({ | ||
| pathFor() { | ||
| return "/admin/customize/embedding"; | ||
| } | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import { bufferedProperty } from 'discourse/mixins/buffered-content'; | ||
| import computed from 'ember-addons/ember-computed-decorators'; | ||
| import { on, observes } from 'ember-addons/ember-computed-decorators'; | ||
| import { popupAjaxError } from 'discourse/lib/ajax-error'; | ||
|
|
||
| export default Ember.Component.extend(bufferedProperty('host'), { | ||
| editToggled: false, | ||
| tagName: 'tr', | ||
| categoryId: null, | ||
|
|
||
| editing: Ember.computed.or('host.isNew', 'editToggled'), | ||
|
|
||
| @on('didInsertElement') | ||
| @observes('editing') | ||
| _focusOnInput() { | ||
| Ember.run.schedule('afterRender', () => { this.$('.host-name').focus(); }); | ||
| }, | ||
|
|
||
| @computed('buffered.host', 'host.isSaving') | ||
| cantSave(host, isSaving) { | ||
| return isSaving || Ember.isEmpty(host); | ||
| }, | ||
|
|
||
| actions: { | ||
| edit() { | ||
| this.set('categoryId', this.get('host.category.id')); | ||
| this.set('editToggled', true); | ||
| }, | ||
|
|
||
| save() { | ||
| if (this.get('cantSave')) { return; } | ||
|
|
||
| const props = this.get('buffered').getProperties('host'); | ||
| props.category_id = this.get('categoryId'); | ||
|
|
||
| const host = this.get('host'); | ||
| host.save(props).then(() => { | ||
| host.set('category', Discourse.Category.findById(this.get('categoryId'))); | ||
| this.set('editToggled', false); | ||
| }).catch(popupAjaxError); | ||
| }, | ||
|
|
||
| delete() { | ||
| bootbox.confirm(I18n.t('admin.embedding.confirm_delete'), (result) => { | ||
| if (result) { | ||
| this.get('host').destroyRecord().then(() => { | ||
| this.sendAction('deleteHost', this.get('host')); | ||
| }); | ||
| } | ||
| }); | ||
| }, | ||
|
|
||
| cancel() { | ||
| const host = this.get('host'); | ||
| if (host.get('isNew')) { | ||
| this.sendAction('deleteHost', host); | ||
| } else { | ||
| this.rollbackBuffer(); | ||
| this.set('editToggled', false); | ||
| } | ||
| } | ||
| } | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| export default Ember.Controller.extend({ | ||
| embedding: null, | ||
|
|
||
| actions: { | ||
| saveChanges() { | ||
| this.get('embedding').update({}); | ||
| }, | ||
|
|
||
| addHost() { | ||
| const host = this.store.createRecord('embeddable-host'); | ||
| this.get('embedding.embeddable_hosts').pushObject(host); | ||
| }, | ||
|
|
||
| deleteHost(host) { | ||
| this.get('embedding.embeddable_hosts').removeObject(host); | ||
| } | ||
| } | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| export default Ember.Route.extend({ | ||
| model() { | ||
| return this.store.find('embedding'); | ||
| }, | ||
|
|
||
| setupController(controller, model) { | ||
| controller.set('embedding', model); | ||
| } | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| {{#if editing}} | ||
| <td> | ||
| {{input value=buffered.host placeholder="example.com" enter="save" class="host-name"}} | ||
| </td> | ||
| <td> | ||
| {{category-chooser value=categoryId}} | ||
| </td> | ||
| <td> | ||
| {{d-button icon="check" action="save" class="btn-primary" disabled=cantSave}} | ||
| {{d-button icon="times" action="cancel" class="btn-danger" disabled=host.isSaving}} | ||
| </td> | ||
| {{else}} | ||
| <td>{{host.host}}</td> | ||
| <td>{{category-badge host.category}}</td> | ||
| <td> | ||
| {{d-button icon="pencil" action="edit"}} | ||
| {{d-button icon="trash-o" action="delete" class='btn-danger'}} | ||
| </td> | ||
| {{/if}} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| {{#if embedding.embeddable_hosts}} | ||
| <table> | ||
| <tr> | ||
| <th style='width: 50%'>{{i18n "admin.embedding.host"}}</th> | ||
| <th style='width: 30%'>{{i18n "admin.embedding.category"}}</th> | ||
| <th style='width: 20%'> </th> | ||
| </tr> | ||
| {{#each embedding.embeddable_hosts as |host|}} | ||
| {{embeddable-host host=host deleteHost="deleteHost"}} | ||
| {{/each}} | ||
| </table> | ||
| {{/if}} | ||
|
|
||
| {{d-button label="admin.embedding.add_host" action="addHost" icon="plus" class="btn-primary"}} | ||
|
|
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,34 @@ | ||||||||||||
| class Admin::EmbeddableHostsController < Admin::AdminController | ||||||||||||
|
|
||||||||||||
| before_filter :ensure_logged_in, :ensure_staff | ||||||||||||
|
|
||||||||||||
| def create | ||||||||||||
| save_host(EmbeddableHost.new) | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| def update | ||||||||||||
| host = EmbeddableHost.where(id: params[:id]).first | ||||||||||||
| save_host(host) | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| def destroy | ||||||||||||
| host = EmbeddableHost.where(id: params[:id]).first | ||||||||||||
|
Comment on lines
+14
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic: missing nil check -
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: app/controllers/admin/embeddable_hosts_controller.rb
Line: 14:15
Comment:
**logic:** missing nil check - `host` will be nil if id not found
```suggestion
host = EmbeddableHost.where(id: params[:id]).first
return render json: { errors: ['Host not found'] }, status: 404 unless host
host.destroy
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||
| host.destroy | ||||||||||||
| render json: success_json | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| protected | ||||||||||||
|
|
||||||||||||
| def save_host(host) | ||||||||||||
| host.host = params[:embeddable_host][:host] | ||||||||||||
| host.category_id = params[:embeddable_host][:category_id] | ||||||||||||
|
Comment on lines
+23
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: missing strong parameters - direct access to Prompt To Fix With AIThis is a comment left during a code review.
Path: app/controllers/admin/embeddable_hosts_controller.rb
Line: 23:24
Comment:
**style:** missing strong parameters - direct access to `params[:embeddable_host]` without filtering
How can I resolve this? If you propose a fix, please make it concise. |
||||||||||||
| host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank? | ||||||||||||
|
|
||||||||||||
| if host.save | ||||||||||||
| render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true) | ||||||||||||
| else | ||||||||||||
| render_json_error(host) | ||||||||||||
| end | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| end | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Admin::EmbeddingController < Admin::AdminController | ||
|
|
||
| before_filter :ensure_logged_in, :ensure_staff, :fetch_embedding | ||
|
|
||
| def show | ||
| render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true) | ||
| end | ||
|
|
||
| def update | ||
| render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true) | ||
| end | ||
|
|
||
| protected | ||
|
|
||
| def fetch_embedding | ||
| @embedding = OpenStruct.new({ | ||
| id: 'default', | ||
| embeddable_hosts: EmbeddableHost.all.order(:host) | ||
| }) | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||
| class EmbeddableHost < ActiveRecord::Base | ||||||||
| validates_format_of :host, :with => /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?\Z/i | ||||||||
| belongs_to :category | ||||||||
|
|
||||||||
| before_validation do | ||||||||
| self.host.sub!(/^https?:\/\//, '') | ||||||||
| self.host.sub!(/\/.*$/, '') | ||||||||
|
Comment on lines
+6
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logic:
Suggested change
Prompt To Fix With AIThis is a comment left during a code review.
Path: app/models/embeddable_host.rb
Line: 6:7
Comment:
**logic:** `self.host` might be nil - calling `sub!` on nil will raise NoMethodError
```suggestion
self.host = host.to_s.sub(/^https?:\/\//, '').sub(/\/.*$/, '') if host.present?
```
How can I resolve this? If you propose a fix, please make it concise. |
||||||||
| end | ||||||||
|
|
||||||||
| def self.record_for_host(host) | ||||||||
| uri = URI(host) rescue nil | ||||||||
| return false unless uri.present? | ||||||||
|
|
||||||||
| host = uri.host | ||||||||
| return false unless host.present? | ||||||||
|
|
||||||||
| where("lower(host) = ?", host).first | ||||||||
| end | ||||||||
|
|
||||||||
| def self.host_allowed?(host) | ||||||||
| record_for_host(host).present? | ||||||||
| end | ||||||||
|
|
||||||||
| end | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| class EmbeddableHostSerializer < ApplicationSerializer | ||
| attributes :id, :host, :category_id | ||
|
|
||
| def id | ||
| object.id | ||
| end | ||
|
|
||
| def host | ||
| object.host | ||
| end | ||
|
|
||
| def category_id | ||
| object.category_id | ||
| end | ||
| end | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| class EmbeddingSerializer < ApplicationSerializer | ||
| attributes :id | ||
| has_many :embeddable_hosts, serializer: EmbeddableHostSerializer, embed: :ids | ||
|
|
||
| def id | ||
| object.id | ||
| end | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: missing nil check -
hostwill be nil if id not found, causing error on line 11Prompt To Fix With AI