faalis_contacts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +339 -0
  3. data/README.md +3 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/faalis_contacts/application.js +1 -0
  6. data/app/assets/javascripts/faalis_contacts/modules/contact.js +360 -0
  7. data/app/assets/javascripts/faalis_contacts/modules/contact_field.js +180 -0
  8. data/app/assets/javascripts/faalis_contacts/modules/contact_type.js +180 -0
  9. data/app/controllers/api/v1/contact_fields_controller.rb +52 -0
  10. data/app/controllers/api/v1/contact_types_controller.rb +52 -0
  11. data/app/controllers/api/v1/contacts_controller.rb +71 -0
  12. data/app/models/contact.rb +6 -0
  13. data/app/models/contact_details.rb +5 -0
  14. data/app/models/contact_field.rb +2 -0
  15. data/app/models/contact_type.rb +2 -0
  16. data/app/views/angularjs_templates/contact/details.html +36 -0
  17. data/app/views/angularjs_templates/contact/index.html +62 -0
  18. data/app/views/angularjs_templates/contact/new.html +120 -0
  19. data/app/views/angularjs_templates/contact_field/details.html +12 -0
  20. data/app/views/angularjs_templates/contact_field/index.html +9 -0
  21. data/app/views/angularjs_templates/contact_field/new.html +37 -0
  22. data/app/views/angularjs_templates/contact_type/details.html +12 -0
  23. data/app/views/angularjs_templates/contact_type/index.html +9 -0
  24. data/app/views/angularjs_templates/contact_type/new.html +37 -0
  25. data/app/views/api/v1/contact_fields/create.json.jbuilder +2 -0
  26. data/app/views/api/v1/contact_fields/destroy.json.jbuilder +1 -0
  27. data/app/views/api/v1/contact_fields/index.json.jbuilder +3 -0
  28. data/app/views/api/v1/contact_fields/show.json.jbuilder +2 -0
  29. data/app/views/api/v1/contact_fields/update.json.jbuilder +2 -0
  30. data/app/views/api/v1/contact_types/create.json.jbuilder +2 -0
  31. data/app/views/api/v1/contact_types/destroy.json.jbuilder +1 -0
  32. data/app/views/api/v1/contact_types/index.json.jbuilder +3 -0
  33. data/app/views/api/v1/contact_types/show.json.jbuilder +2 -0
  34. data/app/views/api/v1/contact_types/update.json.jbuilder +2 -0
  35. data/app/views/api/v1/contacts/create.json.jbuilder +2 -0
  36. data/app/views/api/v1/contacts/destroy.json.jbuilder +1 -0
  37. data/app/views/api/v1/contacts/index.json.jbuilder +9 -0
  38. data/app/views/api/v1/contacts/show.json.jbuilder +7 -0
  39. data/app/views/api/v1/contacts/update.json.jbuilder +2 -0
  40. data/config/routes.rb +9 -0
  41. data/db/migrate/20140109115319_create_contacts.rb +15 -0
  42. data/db/migrate/20140111082843_create_contact_details.rb +13 -0
  43. data/db/migrate/20140113071029_create_contact_fields.rb +9 -0
  44. data/db/migrate/20140113071738_create_contact_types.rb +9 -0
  45. data/db/seeds.rb +9 -0
  46. data/lib/faalis_contacts.rb +6 -0
  47. data/lib/faalis_contacts/engine.rb +17 -0
  48. data/lib/faalis_contacts/version.rb +3 -0
  49. data/lib/tasks/build.rake +18 -0
  50. data/lib/tasks/faalis_contacts_tasks.rake +4 -0
  51. metadata +193 -0
@@ -0,0 +1,71 @@
1
+ class API::V1::ContactsController < Faalis::APIController
2
+ before_filter :build_resource, :only => :create
3
+ load_and_authorize_resource :except => [:destory]
4
+
5
+ # GET /api/v1/contacts
6
+ def index
7
+ respond_with(@contacts)
8
+ end
9
+
10
+ def create
11
+ details = params[:contact][:details] || []
12
+ details_list = []
13
+ details.each do |detail|
14
+ contact_detail = ContactDetails.create!(:detail_field => detail[:field],
15
+ :detail_type => detail[:type],
16
+ :detail_value => detail[:value])
17
+ details_list << contact_detail
18
+ end
19
+
20
+ @contact.details = details_list
21
+
22
+ if @contact.save
23
+ respond_with(@contact)
24
+ else
25
+ respond_to do |format|
26
+ format.json { render :json => {:fields => @contact.errors}, :status => :unprocessable_entity }
27
+ end
28
+ end
29
+ end
30
+
31
+ def show
32
+ respond_with(@contact)
33
+ end
34
+
35
+ def update
36
+ details = params[:contact][:details] || []
37
+ details_list = []
38
+ details.each do |detail|
39
+ contact_detail = ContactDetails.create!(:detail_field => detail[:field],
40
+ :detail_type => detail[:type],
41
+ :detail_value => detail[:value])
42
+ details_list << contact_detail
43
+ end
44
+
45
+ @contact.details = details_list
46
+
47
+ if @contact.update(resource_params)
48
+ respond_with(@contact)
49
+ else
50
+ respond_to do |format|
51
+ format.json { render :json => {:fields => @contact.errors}, :status => :unprocessable_entity }
52
+ end
53
+ end
54
+ end
55
+
56
+ def destroy
57
+ ids = params[:id].split(",")
58
+ @contacts = ::Contact.where(:id => ids)
59
+ authorize! :destroy, @contacts
60
+ @contacts.destroy_all
61
+ end
62
+
63
+ def build_resource
64
+ @contact = ::Contact.new(resource_params)
65
+ end
66
+
67
+ def resource_params
68
+ params.require(:contact).permit(:id, :prefix, :first_name, :middle_name, :last_name, :suffix, :organization, :is_organization)
69
+ end
70
+
71
+ end
@@ -0,0 +1,6 @@
1
+ class Contact < ActiveRecord::Base
2
+ has_many :details, :class_name => "ContactDetails"
3
+
4
+ validates :first_name, :presence => true
5
+ validates :last_name, :presence => true
6
+ end
@@ -0,0 +1,5 @@
1
+ class ContactDetails < ActiveRecord::Base
2
+ belongs_to :contact
3
+
4
+
5
+ end
@@ -0,0 +1,2 @@
1
+ class ContactField < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class ContactType < ActiveRecord::Base
2
+ end
@@ -0,0 +1,36 @@
1
+ <div class="details">
2
+
3
+ <p>
4
+ <b translate>Prefix :</b> {{object.prefix}}
5
+ </p>
6
+
7
+ <p>
8
+ <b translate>First_name :</b> {{object.first_name}}
9
+ </p>
10
+
11
+ <p>
12
+ <b translate>Middle_name :</b> {{object.middle_name}}
13
+ </p>
14
+
15
+ <p>
16
+ <b translate>Last_name :</b> {{object.last_name}}
17
+ </p>
18
+
19
+ <p>
20
+ <b translate>Suffix :</b> {{object.suffix}}
21
+ </p>
22
+
23
+ <p>
24
+ <b translate>Organization :</b> {{object.organization}}
25
+ </p>
26
+
27
+ <p>
28
+ <b translate>Is_organization :</b> {{object.is_organization}}
29
+ </p>
30
+
31
+ <ul class="button-group float-right">
32
+ <a ng-href="#/contacts/{{ object.id }}/edit" class="small">
33
+ <span class="fa fa-edit"></span> <span translated>Edit</span>
34
+ </a>
35
+ </ul>
36
+ </div>
@@ -0,0 +1,62 @@
1
+
2
+ <filter config="filter_config" result="contacts"></filter>
3
+
4
+
5
+ <div ng-if="bulk_edit" class="fade_anim">
6
+ <form id="bulk_form">
7
+ <fieldset class="row clearmargin">
8
+ <legend translate>Bulk Edit</legend>
9
+ <div class="row">
10
+ <div class="small-6 columns">
11
+ <label for="field_name" translate>Field Name:</label>
12
+
13
+ <select id="field_name" ng-model="field_name" ng-change="field_name_change()">
14
+ <option value="0" selected translate>-- Select a field --</option>
15
+ <option ng-repeat="field in fields" value="{{ field.name }}" data-type="{{ field.type }}" data-to="{{ field.to }}"><span translate>{{ field.title }}</span></option>
16
+ </select>
17
+ </div>
18
+ <div class="small-6 columns">
19
+ <label for="field_value" translate>Field Value:</label>
20
+ <div id="value_field">
21
+ <input id="field_value" ng-model="field_value" type="text" ng-if="current_field.type == 'string' || current_field.type == 'integer'">
22
+ <textarea id="field_value" ng-model="field_value" ng-if="current_field.type == 'text'"></textarea>
23
+
24
+ <select id="field_value" ng-model="field_value" ng-if="current_field.type == 'belongs_to'">
25
+ <option ng-repeat="item in cache[current_field.name]" value="{{ item.id }}">{{ item.name }}</option>
26
+ </select>
27
+ <select id="field_value" ng-model="field_value" ng-if="current_field.type == 'has_many'" multiple>
28
+ <option ng-repeat="item in cache[current_field.name]" value="{{ item.id }}">{{ item.name }}</option>
29
+ </select>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ <div class="row progressbar-container" ng-if="view_progressbar">
34
+ <div class="small-12 columns">
35
+ <div class="progressbar">
36
+ <div id="request_filler" class="filler yellow" style="width: {{ rfiller}};"></div>
37
+ <div id="success_filler" class="filler green" style="width: {{ sfiller}};"></div>
38
+ </div>
39
+ </div>
40
+ <div class="row">
41
+ <div class="small-3 columns float-right text-right">
42
+ <small>
43
+ {{ success }} <span translate>of</span> {{ total }}<span ng-if="failed > 0"> - <span translate>field:</span><span class="text-error"> {{ failed }}</span></span>
44
+ </small>
45
+ </div>
46
+ </div>
47
+ </fieldset>
48
+ <br />
49
+ <div class="row">
50
+ <div class="small-6 columns">
51
+ <button class="btn tiny green" ng-click="bulk_save()"><i class="fa fa-check"></i> <span translate>Save</span></button>
52
+ <button class="btn tiny red" ng-click="bulk_cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+
58
+ <list-view buttons="buttons" objects="contacts" title-attribute="full_name" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns">
59
+ <div class="small-6 column text-left clearpadding">
60
+ <h3><i class="fa fa-group"></i> <span translate>Contacts</span></h3>
61
+ </div>
62
+ </list-view>
@@ -0,0 +1,120 @@
1
+ <section class="tabs">
2
+ <ul>
3
+ <li ng-click="activate_tab(1)" ng-class="{active: current_tab == 1, tab1: current_tab == 1}"><span translate>General</span></li> |
4
+ <li ng-click="activate_tab(2)" ng-class="{active: current_tab == 2, tab2: current_tab == 2}"><span translate>Details</span></li> |
5
+ <li ng-click="activate_tab(3)" ng-class="{active: current_tab == 3, tab3: current_tab == 3}"><span translate>Avatar</span></li> |
6
+ </ul>
7
+ </section>
8
+
9
+ <form novalidate name="form">
10
+ <div class="newform">
11
+ <fieldset class="form" ng-show="current_tab == 1">
12
+ <legend><span translate>General</span></legend>
13
+
14
+ <div class="row">
15
+ <div class="small-4 columns ">
16
+ <label><span translate>Prefix</span> :</label>
17
+ <input id="id_prefix" ng-model="prefix" name="prefix" type="text" class="rounded string_field" />
18
+ <small id="id_prefix_msg"></small>
19
+ </div>
20
+
21
+ <div class="small-4 columns float-left small-offset-2">
22
+ <label><span translate>First name</span> :</label>
23
+ <input id="id_first_name" ng-model="first_name" name="first_name" type="text" class="rounded string_field" />
24
+ <small id="id_first_name_msg"></small>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="row">
29
+ <div class="small-4 columns ">
30
+ <label><span translate>Middle name</span> :</label>
31
+ <input id="id_middle_name" ng-model="middle_name" name="middle_name" type="text" class="rounded string_field" />
32
+ <small id="id_middle_name_msg"></small>
33
+ </div>
34
+
35
+ <div class="small-4 columns float-left small-offset-2">
36
+ <label><span translate>Last name</span> :</label>
37
+ <input id="id_last_name" ng-model="last_name" name="last_name" type="text" class="rounded string_field" />
38
+ <small id="id_last_name_msg"></small>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="row">
43
+ <div class="small-4 columns ">
44
+ <label><span translate>Suffix</span> :</label>
45
+ <input id="id_suffix" ng-model="suffix" name="suffix" type="text" class="rounded string_field" />
46
+ <small id="id_suffix_msg"></small>
47
+ </div>
48
+
49
+ <div class="small-4 columns float-left small-offset-2">
50
+ <label><span translate>Organization</span> :</label>
51
+ <input id="id_organization" ng-model="organization" name="organization" type="text" class="rounded string_field" />
52
+ <small id="id_organization_msg"></small>
53
+ </div>
54
+ </div>
55
+
56
+ <div class="row">
57
+ <div class="small-4 columns ">
58
+ <label><span translate>Is organization</span> :</label>
59
+ <input id="id_is_organization" ng-model="is_organization" type="checkbox" name="is_organization" class="rounded boolean_field" />
60
+ <small id="id_is_organization_msg"></small>
61
+ </div>
62
+
63
+ </fieldset>
64
+
65
+ <div class="newform">
66
+ <fieldset class="form" ng-show="current_tab == 2">
67
+ <legend><span translate>Details</span></legend>
68
+
69
+ <div class="row" ng-repeat="detail_number in details_count">
70
+ <div class="small-4 columns">
71
+ <label><span translate>Field</span> :</label>
72
+ <select name="detail_field_{{ detail_number }}" ui-select2="select2options" id="id_detail_field_{{ detail_number }}" ng-model="details[detail_number].field">
73
+ <option ng-repeat="item in detail_fields" value="{{ item.id }}" ng-select="item.id === details[detial_number].type">{{ item.name }}</option>
74
+ </select>
75
+ <small id="id_detail_field_{{ detail_number}}_msg"></small>
76
+ </div>
77
+
78
+ <div class="small-4 columns">
79
+ <label><span translate>Type</span> :</label>
80
+ <select name="detail_type_{{ detail_number }}" ui-select2="select2options" id="id_detail_type_{{ detail_number }}" ng-model="details[detail_number].type">
81
+ <option ng-repeat="item in detail_types" value="{{ item.id }}" ng-select="item.id === details[detial_number].type">{{ item.name }}</option>
82
+ </select>
83
+ <small id="id_detail_type_{{ detail_number}}_msg"></small>
84
+ </div>
85
+
86
+ <div class="small-4 columns">
87
+ <label><span translate>Value</span> :</label>
88
+ <input id="id_detail_value_{{ detail_number }}" ng-model="details[detail_number].value" type="text" name="detail_value_{{ detail_number }}" class="rounded string_field"/>
89
+ <small id="id_detail_value_{{ detail_number}}_msg"></small>
90
+
91
+ </div>
92
+ </div>
93
+
94
+ <div class="row">
95
+ <div class="small-2 columns float-right">
96
+ <span ng-click="add_another_row()" class="btn tiny green"><i class="fa fa-plus"></i></span>
97
+ <span ng-click="remove_row()" class="btn tiny red"><i class="fa fa-minus"></i></span>
98
+ </div>
99
+ </div>
100
+ </fieldset>
101
+ </div>
102
+
103
+ <div class="newform">
104
+ <fieldset class="form" ng-show="current_tab == 3">
105
+ <legend ng-if="!editing"><span translate>New Avatar</span></legend>
106
+ <legend ng-if="editing"><span translate>Edit Avatar</span></legend>
107
+
108
+ </fieldset>
109
+ </div>
110
+ </form>
111
+
112
+
113
+ <div class="row">
114
+ <div class="small-6 columns">
115
+ <button class="btn small green" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
116
+ <button class="btn small blue" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
117
+ <button class="btn small red" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
118
+ </div>
119
+ </div>
120
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="details">
2
+
3
+ <p>
4
+ <b translate>Name :</b> {{object.name}}
5
+ </p>
6
+
7
+ <ul class="button-group float-right">
8
+ <a ng-href="#/contact_fields/{{ object.id }}/edit" class="small">
9
+ <span class="fa fa-edit"></span> <span translated>Edit</span>
10
+ </a>
11
+ </ul>
12
+ </div>
@@ -0,0 +1,9 @@
1
+
2
+ <filter config="filter_config" result="contact_fields"></filter>
3
+
4
+
5
+ <list-view buttons="buttons" objects="contact_fields" title-attribute="'name'" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns">
6
+ <div class="small-6 column text-left clearpadding">
7
+ <h3><i class="fa fa-group"></i> <span translate>Contact fields</span></h3>
8
+ </div>
9
+ </list-view>
@@ -0,0 +1,37 @@
1
+
2
+
3
+ <form novalidate name="form">
4
+ <div class="newform">
5
+ <fieldset class="form">
6
+
7
+ <legend ng-if="!editing"><span translate>New Contact fields</span></legend>
8
+ <legend ng-if="editing"><span translate>Edit Contact fields</span></legend>
9
+
10
+
11
+
12
+ <div class="row">
13
+ <div class="small-4 columns ">
14
+ <label><i class="inline fa fa-asterisk"></i> <span translate>Name</span> :</label>
15
+
16
+ <input id="id_name" ng-model="name" name="name" type="text" class="rounded string_field" required />
17
+
18
+ <small id="id_name_msg"></small>
19
+ </div>
20
+
21
+
22
+
23
+ </fieldset>
24
+ </form>
25
+
26
+
27
+
28
+
29
+
30
+ <div class="row">
31
+ <div class="small-6 columns">
32
+ <button class="btn small green" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
33
+ <button class="btn small blue" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
34
+ <button class="btn small red" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
35
+ </div>
36
+ </div>
37
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="details">
2
+
3
+ <p>
4
+ <b translate>Name :</b> {{object.name}}
5
+ </p>
6
+
7
+ <ul class="button-group float-right">
8
+ <a ng-href="#/contact_types/{{ object.id }}/edit" class="small">
9
+ <span class="fa fa-edit"></span> <span translated>Edit</span>
10
+ </a>
11
+ </ul>
12
+ </div>
@@ -0,0 +1,9 @@
1
+
2
+ <filter config="filter_config" result="contact_types"></filter>
3
+
4
+
5
+ <list-view buttons="buttons" objects="contact_types" title-attribute="'name'" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns">
6
+ <div class="small-6 column text-left clearpadding">
7
+ <h3><i class="fa fa-group"></i> <span translate>Contact types</span></h3>
8
+ </div>
9
+ </list-view>
@@ -0,0 +1,37 @@
1
+
2
+
3
+ <form novalidate name="form">
4
+ <div class="newform">
5
+ <fieldset class="form">
6
+
7
+ <legend ng-if="!editing"><span translate>New Contact types</span></legend>
8
+ <legend ng-if="editing"><span translate>Edit Contact types</span></legend>
9
+
10
+
11
+
12
+ <div class="row">
13
+ <div class="small-4 columns ">
14
+ <label><i class="inline fa fa-asterisk"></i> <span translate>Name</span> :</label>
15
+
16
+ <input id="id_name" ng-model="name" name="name" type="text" class="rounded string_field" required />
17
+
18
+ <small id="id_name_msg"></small>
19
+ </div>
20
+
21
+
22
+
23
+ </fieldset>
24
+ </form>
25
+
26
+
27
+
28
+
29
+
30
+ <div class="row">
31
+ <div class="small-6 columns">
32
+ <button class="btn small green" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
33
+ <button class="btn small blue" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
34
+ <button class="btn small red" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
35
+ </div>
36
+ </div>
37
+ </div>
@@ -0,0 +1,2 @@
1
+ json.extract! @contact_field, :id, :name
2
+