Group.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <template>
  2. <!-- XXX: too much duplication in this template -->
  3. <md-layout class="group-layout" md-col gutter="120" md-align="start">
  4. <md-card v-if="!addNewGroup" md-with-hover @mouseenter.native="focusToNewAttendee()">
  5. <md-card-header class="group-header">
  6. <md-layout md-row>
  7. <div class="md-title">
  8. <md-icon class="group-icon">folder_open</md-icon>&nbsp;Group: {{ group.group }}&nbsp;<span class="counter">{{ counter }}</span>
  9. </div>
  10. </md-layout>
  11. </md-card-header>
  12. <md-card-content>
  13. <md-list md-dense>
  14. <attendee v-for="attendee in group.attendees || []" :attendee="attendee" @updated="reload" />
  15. <md-list-item class="attendee-add">
  16. <md-icon @click.native="addAttendee(group.group)">person_add</md-icon>
  17. <md-input-container class="new-attendee">
  18. <label>new attendee</label>
  19. <md-input ref="newAttendeeInput" @keyup.enter.native="addAttendee(group.group)" v-model="newAttendee" />
  20. </md-input-container>
  21. <md-list-expand>
  22. <md-list>
  23. <md-list-item class="md-inset">
  24. <md-input-container>
  25. <label>notes</label>
  26. <md-input class="new-attendee-notes" @keyup.enter.native="addAttendee(group.group)" v-model="newAttendeeNotes" />
  27. </md-input-container>
  28. </md-list-item>
  29. </md-list>
  30. </md-list-expand>
  31. </md-list-item>
  32. </md-list>
  33. </md-card-content>
  34. </md-card>
  35. <md-card v-if="addNewGroup" md-with-hover @mouseenter.native="focusToNewGroup()" md-align="start">
  36. <md-card-header class="new-group-header">
  37. <div class="md-title">
  38. <md-input-container class="new-group" md-inline>
  39. <md-icon>create_new_folder</md-icon>&nbsp;&nbsp;<md-input ref="newGroup" v-model="newGroup" @keyup.enter.native="focusToNewAttendee()" class="group-add-name" placeholder="new group" />
  40. </md-input-container>
  41. </div>
  42. </md-card-header>
  43. <md-card-content>
  44. <md-list v-show="newGroup">
  45. <md-list-item class="attendee-add">
  46. <md-icon @click.native="addAttendee(newGroup)">person_add</md-icon>
  47. <md-input-container>
  48. <label>new attendee</label>
  49. <md-input ref="newAttendeeInput" @keyup.enter.native="addAttendee(newGroup)" v-model="newAttendee" />
  50. </md-input-container>
  51. <md-list-expand>
  52. <md-list>
  53. <md-list-item class="md-inset">
  54. <md-input-container>
  55. <label>notes</label>
  56. <md-input class="new-attendee-notes" @keyup.enter.native="addAttendee(newGroup)" v-model="newAttendeeNotes" />
  57. </md-input-container>
  58. </md-list-item>
  59. </md-list>
  60. </md-list-expand>
  61. </md-list-item>
  62. </md-list>
  63. </md-card-content>
  64. </md-card>
  65. <ibt-dialog ref="dialogObj" />
  66. </md-layout>
  67. </template>
  68. <script>
  69. import Attendee from './Attendee';
  70. import IbtDialog from './IbtDialog.vue';
  71. export default {
  72. props: {group: {}, day: {}, addNewGroup: {default: false}},
  73. data: function () {
  74. return {
  75. newAttendee: '',
  76. newAttendeeNotes: '',
  77. newGroup: ''
  78. }
  79. },
  80. computed: {
  81. counter: function() {
  82. return (this.group.attendees || []).length;
  83. }
  84. },
  85. beforeCreate: function() {
  86. this.attendeesUrl = this.$resource('attendees{/id}');
  87. },
  88. methods: {
  89. reset() {
  90. this.newAttendee = '';
  91. this.newAttendeeNotes = '';
  92. this.newGroup = '';
  93. },
  94. reload() {
  95. this.$emit('updated');
  96. this.focusToNewAttendee();
  97. },
  98. focusToNewGroup() {
  99. this.$refs.newGroup.$el.focus();
  100. },
  101. focusToNewAttendee() {
  102. this.$refs.newAttendeeInput.$el.focus();
  103. },
  104. addAttendee(group, newAttendee) {
  105. newAttendee = newAttendee || this.newAttendee;
  106. var attendee = {
  107. day: this.day,
  108. group: group,
  109. name: newAttendee,
  110. notes: this.newAttendeeNotes
  111. };
  112. this.attendeesUrl.save(attendee).then((response) => {
  113. return response.json();
  114. }, (response) => {
  115. this.$refs.dialogObj.show({text: 'unable to add the attendee'});
  116. }).then((json) => {
  117. this.reset();
  118. this.$emit('updated');
  119. });
  120. }
  121. },
  122. components: { Attendee, IbtDialog }
  123. };
  124. </script>
  125. <style>
  126. .group-layout {
  127. padding: 10px;
  128. }
  129. .new-group-header {
  130. background-color: lightsteelblue;
  131. padding-top: 0px !important;
  132. padding-bottom: 0px !important;
  133. }
  134. .new-group-header .md-title {
  135. margin-top: 0px !important;
  136. }
  137. .group-header {
  138. background-color: lightblue;
  139. }
  140. .group-icon {
  141. vertical-align: text-top;
  142. }
  143. .new-attendee {
  144. width: 50px;
  145. }
  146. .new-group {
  147. min-width: 250px;
  148. }
  149. .new-group-header i:after {
  150. background-color: initial !important;
  151. }
  152. .counter {
  153. margin-left: 4px;
  154. position: relative;
  155. bottom: 12px;
  156. background-color: #eee;
  157. color: #666;
  158. padding: 2px 5px;
  159. border-radius: 20px;
  160. font-size: 12px;
  161. font-weight: 200;
  162. line-height: 1;
  163. }
  164. .new-attendee-notes {
  165. max-width: 120px;
  166. }
  167. </style>