{"version":3,"file":"views.js","sources":["../../../src/io.ox/participants/views.js"],"sourcesContent":["/**\n * @copyright Copyright (c) Open-Xchange GmbH, Germany \n * @license AGPL-3.0\n *\n * This code is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with OX App Suite. If not, see .\n *\n * Any use of the work other than as authorized under this license or copyright law is prohibited.\n */\n\nimport $ from '@/jquery'\nimport _ from '@/underscore'\nimport Backbone from '@/backbone'\nimport api from '@/io.ox/contacts/api'\nimport * as contactsUtil from '@/io.ox/contacts/util'\nimport * as util from '@/io.ox/core/util'\nimport folderAPI from '@/io.ox/core/folder/api'\nimport capabilities from '@/io.ox/core/capabilities'\nimport ext from '@/io.ox/core/extensions'\nimport { createIcon } from '@/io.ox/core/components'\nimport svg from '@/io.ox/core/svg'\n\nimport biList from 'bootstrap-icons/icons/list.svg'\nimport biPeople from 'bootstrap-icons/icons/people.svg'\nimport biGearWide from 'bootstrap-icons/icons/gear-wide.svg'\n\nimport '@/io.ox/participants/style.scss'\nimport gt from 'gettext'\n\nconst TYPE_LABELS = {\n 0: gt('Unknown'),\n 1: '',\n 2: gt('Group'),\n 3: gt('Resource'),\n 4: gt('Resource group'),\n 5: capabilities.has('gab') ? gt('External contact') : '',\n 6: gt('Distribution list')\n}\n\nexport const ParticipantEntryView = Backbone.View.extend({\n\n tagName: 'div',\n\n className: 'participant-wrapper',\n\n events: {\n 'click .remove': 'onRemove',\n keydown: 'fnKey'\n },\n\n options: {\n halo: false,\n closeButton: false,\n field: false,\n customize: $.noop\n },\n\n nodes: {},\n\n initialize (options) {\n this.options = $.extend({}, this.options, options || {})\n this.listenTo(this.model, 'change', function (model) {\n if (!model || !model.changed) return\n this.$el.empty()\n this.render()\n // make sure lazyload wakes up after updates (there is a debounce on it anyhow)\n $(window).trigger('resize.lazyload')\n })\n this.listenTo(this.model, 'remove', function () {\n this.remove()\n })\n },\n\n render () {\n this.$el.append(\n this.nodes.$img = $('
'),\n this.nodes.$text = $('
'),\n this.options.hideMail ? '' : $('
').append(this.nodes.$mail = this.options.halo ? $('') : $('')),\n this.options.hideMail ? '' : $('
').append(this.nodes.$extra = $('')),\n $('').append(\n $('
').append(\n createIcon('bi/trash.svg').attr('title', gt('Remove contact') + ' ' + this.model.getDisplayName()),\n $('').text(gt('Remove contact') + ' ' + this.model.getDisplayName())\n )\n )\n ).attr({ 'data-cid': this.model.cid }).toggleClass('removable', this.options.closeButton)\n this.setCustomImage()\n this.setDisplayName()\n this.setTypeStyle()\n this.options.customize.call(this)\n ext.point('io.ox/participants/view').invoke('render', this.$el, new ext.Baton({ view: this, model: this.model }))\n this.trigger('render')\n return this\n },\n\n setDisplayName () {\n const options = {\n $el: this.nodes.$text\n }\n if (this.options.asHtml) {\n options.html = this.model.getDisplayName({ asHtml: true, isMail: this.options.isMail })\n } else {\n options.name = this.model.getDisplayName({ asHtml: false, isMail: this.options.isMail })\n }\n util.renderPersonalName(options, this.model.toJSON())\n },\n\n setCustomImage () {\n const data = this.model.toJSON()\n\n this.nodes.$img.attr('aria-hidden', true).addClass('avatar participant-image')\n // fix to work with picture halo (model uses email address as id)\n if (data.type === 5) delete data.id\n if (data.type === 2) return this.nodes.$img.append(biPeople)\n if (data.type === 3) return this.nodes.$img.append(biGearWide)\n if (data.type === 6) return this.nodes.$img.append(biList)\n\n const initials = contactsUtil.getInitials(data)\n this.nodes.$img.append(svg.circleAvatar(initials)).addClass('initials')\n api.pictureHalo(\n this.nodes.$img,\n data,\n { width: 54, height: 54 }\n )\n },\n\n setRows (mail, extra) {\n if (!this.options.hideMail) {\n extra = extra || TYPE_LABELS[this.model.get('type')] || ''\n this.nodes.$mail.text(mail)\n this.nodes.$extra.text(extra)\n if (mail && extra) {\n this.$el.addClass('three-rows')\n }\n }\n },\n\n isOrganizer () {\n if (!this.options.baton) return false\n const appointment = this.options.baton.model.toJSON()\n if (!appointment.organizerId) return false\n return this.model.get('id') === appointment.organizerId\n },\n\n isRemovable () {\n if (!this.options.baton) return false\n const appointment = this.options.baton.model.toJSON()\n // participants can be removed unless they are organizer\n if (this.model.get('id') !== appointment.organizerId) return true\n // special case: organizer can be removed from public folders\n return folderAPI.pool.getModel(appointment.folder_id).is('public')\n },\n\n setTypeStyle () {\n let mail = this.model.getTarget({ strict: this.options.strict })\n let extra = null\n\n if (mail && this.options.field && this.model.getFieldString()) {\n mail += ' (' + this.model.getFieldString() + ')'\n }\n\n switch (this.model.get('type')) {\n case 1:\n case 5:\n // set organizer\n if (this.isOrganizer()) {\n extra = gt('Organizer')\n // don't remove organizer\n if (!this.isRemovable()) this.$el.removeClass('removable')\n }\n\n if (mail && this.options.halo) {\n this.nodes.$mail\n .attr({ href: 'mailto:' + mail, 'data-detail-popup': 'halo' })\n .data({ email1: mail })\n }\n break\n case 3:\n if (this.options.halo && !this.options.hideMail) {\n const data = this.model.toJSON()\n data.callbacks = {}\n if (this.options.baton && this.options.baton.callbacks) {\n data.callbacks = this.options.baton.callbacks\n }\n const link = $('').data(data)\n this.nodes.$extra.replaceWith(link)\n this.nodes.$extra = link\n }\n break\n // no default\n }\n\n this.setRows(mail, extra)\n },\n\n fnKey (e) {\n // del or backspace\n if (e.which === 46 || e.which === 8) this.onRemove(e)\n },\n\n onRemove (e) {\n e.preventDefault()\n // remove from collection\n this.model.collection.remove(this.model)\n }\n})\n\nconst UserContainer = Backbone.View.extend({\n\n tagName: 'div',\n\n className: 'participantsrow col-xs-12',\n\n initialize (options) {\n this.options = _.extend({\n empty: gt('This list has no participants yet')\n }, options)\n this.listenTo(this.collection, 'add', function (model) {\n this.renderLabel()\n this.renderEmptyLabel()\n this.renderParticipant(model)\n })\n this.listenTo(this.collection, 'remove', function () {\n this.renderLabel()\n this.renderEmptyLabel()\n })\n this.listenTo(this.collection, 'reset', function () {\n this.$ul.empty()\n this.renderAll()\n })\n this.$empty = $('
  • ').text(this.options.empty)\n // duck typing\n if (this.options.baton) return\n this.isDistributionList = this.options.baton.model.has('mark_as_distributionlist')\n },\n\n render () {\n this.$el.append(\n $('
    ').append(\n $('').addClass(this.options.labelClass || ''),\n this.$ul = $('
      ')\n )\n )\n this.renderAll()\n return this\n },\n\n renderLabel () {\n const count = this.collection.length\n const label = this.options.label || (this.isDistributionList ? gt('Members (%1$d)', count) : gt('Participants (%1$d)', count))\n this.$('fieldset > legend').text(label)\n },\n\n renderParticipant (participant) {\n const view = new ParticipantEntryView({\n tagName: 'li',\n model: participant,\n baton: this.options.baton,\n halo: this.options.halo !== undefined ? this.options.halo : true,\n closeButton: true,\n hideMail: this.options.hideMail,\n asHtml: this.options.asHtml,\n isMail: this.options.isMail,\n strict: this.options.strict\n })\n\n view.on('render', function () {\n this.collection.trigger('render')\n }.bind(this))\n\n view.render().$el.addClass(this.options.entryClass || 'col-xs-12 col-sm-6')\n\n // bring organizer up\n if (participant.get('id') === this.options.baton.model.get('organizerId')) {\n this.$ul.prepend(view.$el)\n } else {\n this.$ul.append(view.$el)\n }\n },\n\n renderAll () {\n const self = this\n this.renderLabel()\n this.renderEmptyLabel()\n this.collection.each(function (model) {\n self.renderParticipant(model)\n })\n return this\n },\n\n renderEmptyLabel () {\n if (this.options.noEmptyLabel) {\n return\n }\n if (this.collection.length === 0) {\n this.$ul.append(this.$empty)\n } else {\n this.$empty.remove()\n }\n return this.$ul.toggleClass('empty', this.collection.length === 0)\n }\n\n})\n\nexport default {\n ParticipantEntryView,\n UserContainer\n}\n"],"names":["TYPE_LABELS","gt","capabilities","ParticipantEntryView","Backbone","$","options","model","createIcon","ext","util.renderPersonalName","data","biPeople","biGearWide","biList","initials","contactsUtil.getInitials","svg","api","mail","extra","appointment","folderAPI","link","e","UserContainer","_","count","label","participant","view","self","pViews"],"mappings":"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"}