faalis_contacts 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+