mirror of
https://github.com/owncloudarchive/contacts.git
synced 2024-12-01 13:24:10 +01:00
Merge remote-tracking branch 'origin/import-new-ui' into import-new-ui
This commit is contained in:
commit
c80714f1d7
@ -446,16 +446,16 @@ dt[data-element="org"] { margin-top: 4px; }
|
||||
}
|
||||
|
||||
/* Single elements */
|
||||
#file_upload_form, #file_upload_target, #import_upload_target, #crop_target { display:none; }
|
||||
#import_upload_start, .import-upload-button {
|
||||
#file_upload_form { display:none; }
|
||||
#contacts-import-upload-start, .import-upload-button {
|
||||
width: 30px !important; height: 30px !important;
|
||||
display:block;
|
||||
position: absolute;
|
||||
right: 0; top: 0;
|
||||
right: 0; bottom: 0;
|
||||
margin: 5px !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
#import_upload_start {
|
||||
#contacts-import-upload-start {
|
||||
cursor: pointer;
|
||||
z-index: 1001;
|
||||
}
|
||||
@ -530,7 +530,7 @@ input[type=checkbox].propertytype { width: 10px; }
|
||||
background-size: 80%;
|
||||
}
|
||||
#phototools li a:hover { opacity: 0.8; }
|
||||
#contactphoto_fileupload, #import_upload_start { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; z-index:1001; }
|
||||
#contactphoto_fileupload, #contacts-import-upload-start { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; z-index:1001; }
|
||||
|
||||
#dialog-merge-contacts .mergelist {
|
||||
margin: 10px;
|
||||
@ -871,6 +871,17 @@ tbody tr.contact.active, tbody tr.contact:hover {
|
||||
}
|
||||
}
|
||||
|
||||
#contacts-import-div > p > select {
|
||||
width:200px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#contacts-import-div > p > label {
|
||||
vertical-align:top;
|
||||
width:200px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1400px) {
|
||||
#contactlist tr td.categories { display: none; }
|
||||
#contactsHeader tr td.categories { display: none; }
|
||||
|
@ -9,6 +9,11 @@ OC.Contacts = OC.Contacts || {};
|
||||
this.storage = storage;
|
||||
this.book = book;
|
||||
this.$template = template;
|
||||
this.addressBooks = new OC.Contacts.AddressBookList(
|
||||
this.storage,
|
||||
$('#app-settings-content'),
|
||||
$('#addressBookTemplate')
|
||||
);
|
||||
};
|
||||
|
||||
AddressBook.prototype.render = function() {
|
||||
@ -335,16 +340,16 @@ OC.Contacts = OC.Contacts || {};
|
||||
this.$bookTemplate = bookTemplate;
|
||||
this.$bookList = this.$bookTemplate.find('.addressbooklist');
|
||||
this.$bookItemTemplate = bookItemTemplate;
|
||||
this.$importIntoSelect = this.$bookTemplate.find('#import_into');
|
||||
this.$importFormatSelect = this.$bookTemplate.find('#import_format');
|
||||
this.$importProgress = this.$bookTemplate.find('#import-status-progress');
|
||||
this.$importStatusText = this.$bookTemplate.find('#import-status-text');
|
||||
this.$importIntoSelect = $('#contacts-import-into');
|
||||
this.$importFormatSelect = $('#contacts-import-format');
|
||||
this.$importProgress = $('#import-status-progress');
|
||||
this.$importStatusText = $('#import-status-text');
|
||||
this.addressBooks = [];
|
||||
|
||||
if(this.isFileAction) {
|
||||
return;
|
||||
}
|
||||
this.$importFileInput = this.$bookTemplate.find('#import_upload_start');
|
||||
this.$importFileInput = $('#contacts-import-upload-start');
|
||||
var $addInput = this.$bookTemplate.find('#add-address-book');
|
||||
$addInput.addnew({
|
||||
ok: function(event, name) {
|
||||
@ -365,68 +370,141 @@ OC.Contacts = OC.Contacts || {};
|
||||
$(document).bind('status.addressbook.removed', function(e, data) {
|
||||
var addressBook = data.addressbook;
|
||||
self.addressBooks.splice(self.addressBooks.indexOf(addressBook), 1);
|
||||
self.buildImportSelect();
|
||||
});
|
||||
$(document).bind('status.addressbook.added', function() {
|
||||
self.buildImportSelect();
|
||||
})
|
||||
this.$importFormatSelect.on('change', function() {
|
||||
self.$importIntoSelect.trigger('change');
|
||||
$('#oc-import-nocontact').unbind('click').click(function(event) {
|
||||
console.log("triggered", event);
|
||||
self.importDialog();
|
||||
});
|
||||
this.$importIntoSelect.on('change', function() {
|
||||
// Disable file input if no address book selected
|
||||
var value = $(this).val();
|
||||
self.$importFileInput.prop('disabled', value === '-1' );
|
||||
if(value !== '-1') {
|
||||
var url = OC.generateUrl(
|
||||
'apps/contacts/addressbook/{backend}/{addressBookId}/{importType}/import/upload',
|
||||
$('#import-contacts').unbind('click').click(function() {
|
||||
console.log("Import clicked");
|
||||
self.importDialog();
|
||||
});
|
||||
};
|
||||
|
||||
AddressBookList.prototype.importDialog = function() {
|
||||
var $rightContent = $('#app-content');
|
||||
$rightContent.append('<div id="import-dialog"></div>');
|
||||
var $dlg = $('#contactsImportTemplate').clone().octemplate();
|
||||
var $divDlg = $('#import-dialog');
|
||||
var self = this;
|
||||
$divDlg.html($dlg).ocdialog({
|
||||
modal: true,
|
||||
closeOnEscape: true,
|
||||
title: t('contacts', 'Import contacts'),
|
||||
height: '220',
|
||||
width: 'auto',
|
||||
buttons: [
|
||||
{
|
||||
addressBookId:value,
|
||||
importType:self.$importFormatSelect.find('option:selected').val(),
|
||||
backend: $(this).find('option:selected').data('backend')
|
||||
text: t('contacts', 'Close'),
|
||||
click: function() {
|
||||
$('#import-dialog').ocdialog('close').ocdialog('destroy').remove();
|
||||
}
|
||||
);
|
||||
self.$importFileInput.fileupload('option', 'url', url);
|
||||
}
|
||||
],
|
||||
close: function(/*event, ui*/) {
|
||||
$('#import-dialog').ocdialog('close').ocdialog('destroy').remove();
|
||||
},
|
||||
open: function(/*event, ui*/) {
|
||||
self.openImportDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AddressBookList.prototype.openImportDialog = function() {
|
||||
this.$importIntoSelect = $('#contacts-import-into');
|
||||
this.$importFormatSelect = $('#contacts-import-format');
|
||||
this.$importProgress = $('#import-status-progress');
|
||||
this.$importStatusText = $('#import-status-text');
|
||||
this.$importFileInput = $('#contacts-import-upload-start');
|
||||
var me = this;
|
||||
var self = this;
|
||||
this.$importFileInput.fileupload({
|
||||
dataType: 'json',
|
||||
start: function(/*e, data*/) {
|
||||
self.$importProgress.progressbar({value:false});
|
||||
start: function(e, data) {
|
||||
me.$importProgress.progressbar({value:false});
|
||||
$('.tipsy').remove();
|
||||
$('.import-upload').hide();
|
||||
$('.import-status').show();
|
||||
self.$importProgress.fadeIn();
|
||||
self.$importStatusText.text(t('contacts', 'Starting file import'));
|
||||
me.$importProgress.fadeIn();
|
||||
me.$importStatusText.text(t('contacts', 'Starting file import'));
|
||||
},
|
||||
done: function (e, data) {
|
||||
if ($('#import_format').find('option:selected').val() != 'automatic') {
|
||||
$('#import-status-text').text(t('contacts', 'Format selected: {format}',
|
||||
{format: $('#import_format').find('option:selected').text() }));
|
||||
if (me.$importFormatSelect.find('option:selected').val() != 'automatic') {
|
||||
me.$importStatusText.text(t('contacts', 'Format selected: {format}',
|
||||
{format: $('#contacts-import-format').find('option:selected').text() }));
|
||||
} else {
|
||||
$('#import-status-text').text(t('contacts', 'Automatic format detection'));
|
||||
me.$importStatusText.text(t('contacts', 'Automatic format detection'));
|
||||
}
|
||||
console.log('Upload done:', data);
|
||||
console.log('Upload done:', self.addressBooks);
|
||||
self.doImport(self.storage.formatResponse(data.jqXHR));
|
||||
},
|
||||
fail: function(e, data) {
|
||||
console.log('fail', data);
|
||||
OC.notify({message:data.errorThrown + ': ' + data.textStatus});
|
||||
$('.import-upload').show();
|
||||
$('.import-status').hide();
|
||||
}
|
||||
});
|
||||
};
|
||||
var $import_into = $('#contacts-import-into');
|
||||
$import_into.change(function() {
|
||||
if ($(this).val() != '-1') {
|
||||
var url = OC.generateUrl(
|
||||
'apps/contacts/addressbook/{backend}/{addressBookId}/{importType}/import/upload',
|
||||
{
|
||||
addressBookId:$import_into.val(),
|
||||
importType:me.$importFormatSelect.find('option:selected').val(),
|
||||
backend: $import_into.find('option:selected').attr('backend')
|
||||
}
|
||||
);
|
||||
me.$importFileInput.fileupload('option', 'url', url);
|
||||
me.$importFileInput.attr('disabled', false);
|
||||
} else {
|
||||
me.$importFileInput.attr('disabled', true);
|
||||
}
|
||||
});
|
||||
$.when(self.storage.getAddressBooksForUser()).then(function(response) {
|
||||
if(!response.error) {
|
||||
$import_into.empty();
|
||||
var $option = $('<option value="-1">' + t('contacts', 'Import into...') + '</option>');
|
||||
$import_into.append($option);
|
||||
var nbOptions = 0;
|
||||
$.each(response.data.addressbooks, function(idx, addressBook) {
|
||||
if (addressBook.permissions & OC.PERMISSION_UPDATE) {
|
||||
var $option=$('<option></option>').val(addressBook.id).html(addressBook.displayname).attr('backend', addressBook.backend);
|
||||
self.insertAddressBook(addressBook, false);
|
||||
$import_into.append($option);
|
||||
nbOptions++;
|
||||
}
|
||||
});
|
||||
if (nbOptions === 1) {
|
||||
$import_into.val($import_into.find('option:not([value="-1"])').first().val());
|
||||
$import_into.attr('disabled', true);
|
||||
me.$importFileInput.attr('disabled', false);
|
||||
var url = OC.generateUrl(
|
||||
'apps/contacts/addressbook/{backend}/{addressBookId}/{importType}/import/upload',
|
||||
{
|
||||
addressBookId:$import_into.val(),
|
||||
importType:me.$importFormatSelect.find('option:selected').val(),
|
||||
backend: $import_into.find('option:selected').attr('backend')
|
||||
}
|
||||
);
|
||||
me.$importFileInput.fileupload('option', 'url', url);
|
||||
}
|
||||
} else {
|
||||
console.log('status.contacts.error', response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AddressBookList.prototype.count = function() {
|
||||
return this.addressBooks.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* For importing from oC filesyatem
|
||||
* For importing from oC filesystem
|
||||
*/
|
||||
AddressBookList.prototype.prepareImport = function(backend, addressBookId, importType, path, fileName) {
|
||||
console.log('prepareImport', backend, addressBookId, importType, path, fileName);
|
||||
this.$importStatusText = $('#import-status-text');
|
||||
this.$importProgress = $('#import-status-progress');
|
||||
this.$importProgress.progressbar({value:false});
|
||||
if (importType != 'automatic') {
|
||||
this.$importStatusText.text(t('contacts', 'Format selected: {format}',
|
||||
@ -442,21 +520,14 @@ OC.Contacts = OC.Contacts || {};
|
||||
|
||||
AddressBookList.prototype.doImport = function(response) {
|
||||
console.log('doImport', response);
|
||||
this.$importProgress = $('#import-status-progress');
|
||||
this.$importStatusText = $('#import-status-text');
|
||||
var defer = $.Deferred();
|
||||
var done = false;
|
||||
var interval = null, isChecking = false;
|
||||
var self = this;
|
||||
var closeImport = function() {
|
||||
defer.resolve();
|
||||
self.$importProgress.fadeOut();
|
||||
setTimeout(function() {
|
||||
$('.import-upload').show();
|
||||
$('.import-status').hide();
|
||||
self.importCount = null;
|
||||
if(self.$importProgress.hasClass('ui-progressbar')) {
|
||||
self.$importProgress.progressbar('destroy');
|
||||
}
|
||||
}, 3000);
|
||||
};
|
||||
if(!response.error) {
|
||||
this.$importProgress.progressbar('value', 0);
|
||||
@ -480,6 +551,7 @@ OC.Contacts = OC.Contacts || {};
|
||||
if(!response.error) {
|
||||
console.log('status, response: ', response);
|
||||
if (response.data.total != null && response.data.progress != null) {
|
||||
console.log('response.data', response.data);
|
||||
self.$importProgress.progressbar('option', 'max', Number(response.data.total));
|
||||
self.$importProgress.progressbar('value', Number(response.data.progress));
|
||||
self.$importStatusText.text(t('contacts', 'Processing {count}/{total} cards',
|
||||
@ -496,6 +568,7 @@ OC.Contacts = OC.Contacts || {};
|
||||
isChecking = false;
|
||||
});
|
||||
};
|
||||
console.log('vertige', data);
|
||||
$.when(
|
||||
self.storage.startImport(
|
||||
data.backend, data.addressBookId, data.importType,
|
||||
@ -506,9 +579,13 @@ OC.Contacts = OC.Contacts || {};
|
||||
console.log('response', response);
|
||||
if(!response.error) {
|
||||
console.log('Import done');
|
||||
$('#contacts-import-upload').hide();
|
||||
self.$importStatusText.text(t('contacts', 'Total:{total}, Success:{imported}, Errors:{failed}',
|
||||
{total: response.data.total, imported:response.data.imported, failed: response.data.failed}));
|
||||
var addressBook = self.find({id:response.data.addressBookId, backend: response.data.backend});
|
||||
self.$importProgress.progressbar('option', 'max', response.data.total);
|
||||
self.$importProgress.progressbar('value', response.data.total);
|
||||
var addressBook = self.find({id:data.addressBookId, backend: data.backend});
|
||||
console.log('addressBook', self.count(), self.addressBooks);
|
||||
$(document).trigger('status.addressbook.imported', {
|
||||
addressbook: addressBook
|
||||
});
|
||||
@ -525,9 +602,6 @@ OC.Contacts = OC.Contacts || {};
|
||||
$(document).trigger('status.contacts.error', response);
|
||||
done = true;
|
||||
});
|
||||
interval = setInterval(function() {
|
||||
getStatus(data.backend, data.addressBookId, data.importType, data.progresskey, interval, done);
|
||||
}, 1500);
|
||||
} else {
|
||||
defer.reject(response);
|
||||
done = true;
|
||||
@ -538,41 +612,16 @@ OC.Contacts = OC.Contacts || {};
|
||||
return defer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Rebuild the select to choose which address book to import into.
|
||||
*/
|
||||
AddressBookList.prototype.buildImportSelect = function() {
|
||||
console.log('buildImportSelect');
|
||||
var self = this;
|
||||
this.$importIntoSelect.find('option:not([value="-1"])').remove();
|
||||
var addressBooks = this.selectByPermission(OC.PERMISSION_UPDATE);
|
||||
$.each(addressBooks, function(idx, book) {
|
||||
var $opt = $('<option />');
|
||||
$opt.val(book.getId()).text(book.getDisplayName()).data('backend', book.getBackend());
|
||||
self.$importIntoSelect.append($opt);
|
||||
console.log('appending', $opt, 'to', self.$importIntoSelect);
|
||||
});
|
||||
if(!this.isFileAction) {
|
||||
if(addressBooks.length === 1) {
|
||||
this.$importIntoSelect.val(this.$importIntoSelect.find('option:not([value="-1"])').first().val()).hide().trigger('change');
|
||||
self.$importFileInput.prop('disabled', false);
|
||||
} else {
|
||||
this.$importIntoSelect.show();
|
||||
self.$importFileInput.prop('disabled', true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an AddressBook object, save it in internal list and append it's rendered result to the list
|
||||
*
|
||||
* @param object addressBook
|
||||
* @param bool rebuild If true rebuild the address book select for import.
|
||||
* @param bool rendered If true add the addressbook to the addressbook list
|
||||
* @return AddressBook
|
||||
*/
|
||||
AddressBookList.prototype.insertAddressBook = function(addressBook) {
|
||||
AddressBookList.prototype.insertAddressBook = function(addressBook, rendered = true) {
|
||||
var book = new AddressBook(this.storage, addressBook, this.$bookItemTemplate, this.isFileAction);
|
||||
if(!this.isFileAction) {
|
||||
if(!this.isFileAction && rendered) {
|
||||
var result = book.render();
|
||||
this.$bookList.append(result);
|
||||
}
|
||||
@ -714,8 +763,6 @@ OC.Contacts = OC.Contacts || {};
|
||||
$.each(response.data.addressbooks, function(idx, addressBook) {
|
||||
self.insertAddressBook(addressBook);
|
||||
});
|
||||
self.buildImportSelect();
|
||||
console.log('After buildImportSelect');
|
||||
if(!self.isFileAction) {
|
||||
if(typeof OC.Share !== 'undefined') {
|
||||
OC.Share.loadIcons('addressbook');
|
||||
|
@ -51,7 +51,7 @@ OC.ContactsImporter = OC.ContactsImporter || {
|
||||
self.$dialog = null;
|
||||
}
|
||||
});
|
||||
self.$importIntoSelect = self.$dialog.find('#import_into');
|
||||
self.$importIntoSelect = $('#contacts-import-into');
|
||||
self.$importIntoSelect.on('change', function() {
|
||||
var $selected = $(this).find('option:selected');
|
||||
if($(this).val() === '-1') {
|
||||
|
@ -45,7 +45,10 @@ class ImportVCardConnector extends ImportConnector{
|
||||
|
||||
$elements = array();
|
||||
foreach($parts as $part) {
|
||||
$elements[] = $this->convertElementToVCard($part);
|
||||
$converted = $this->convertElementToVCard($part);
|
||||
if ($converted) {
|
||||
$elements[] = $converted;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($elements);
|
||||
@ -100,10 +103,14 @@ class ImportVCardConnector extends ImportConnector{
|
||||
/**
|
||||
* @brief converts a VCard into a owncloud VCard
|
||||
* @param $element the VCard element to convert
|
||||
* @return VCard
|
||||
* @return VCard|false
|
||||
*/
|
||||
public function convertElementToVCard($element) {
|
||||
$source = VObject\Reader::read($element);
|
||||
try {
|
||||
$source = VObject\Reader::read($element, VObject\Reader::OPTION_FORGIVING);
|
||||
} catch (VObject\ParseException $error) {
|
||||
return false;
|
||||
}
|
||||
$dest = \Sabre\VObject\Component::create('VCARD');
|
||||
|
||||
foreach ($source->children() as $sourceProperty) {
|
||||
|
@ -258,7 +258,7 @@ class ImportController extends Controller {
|
||||
$favourites = $part->select('X-FAVOURITES');
|
||||
foreach ($favourites as $favourite) {
|
||||
if ($favourite->getValue() == 'yes') {
|
||||
$tagMgr = $this->server->getTagManager()->load('contact');
|
||||
$tagMgr = \OC::$server->getTagManager()->load('contact');
|
||||
$tagMgr->addToFavorites($id);
|
||||
}
|
||||
}
|
||||
@ -307,8 +307,6 @@ class ImportController extends Controller {
|
||||
$response->bailOut(App::$l10n->t('Progress key missing from request.'));
|
||||
return $response;
|
||||
}
|
||||
|
||||
error_log("progresskey: ".$this->cache->get($progresskey)." total: ".$this->cache->get($progresskey.'_total') );
|
||||
$response->setParams(array('progress' => $this->cache->get($progresskey), 'total' => $this->cache->get($progresskey.'_total') ));
|
||||
return $response;
|
||||
}
|
||||
|
@ -34,29 +34,8 @@ use OCA\Contacts\ImportManager;
|
||||
?>
|
||||
</div>
|
||||
<div id="import">
|
||||
<h2 data-id="import" tabindex="0" role="button"><?php p($l->t('Import')); ?></h2>
|
||||
<ul>
|
||||
<li class="import-upload">
|
||||
<select id="import_into">
|
||||
<option value="-1"><?php p($l->t('Import into...')); ?></option>
|
||||
</select>
|
||||
<select id="import_format">
|
||||
<option value="automatic"><?php p($l->t('Automatic format')); ?></option>
|
||||
<?php
|
||||
$importManager = new ImportManager();
|
||||
$types = $importManager->getTypes();
|
||||
foreach ($types as $id => $label) {
|
||||
echo "<option value=\"$id\">$label</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<button class="icon-upload svg tooltipped rightwards import-upload-button" title="<?php p($l->t('Select file...')); ?>"></button>
|
||||
<input id="import_upload_start" class="tooltipped rightwards" title="<?php p($l->t('Select file...')); ?>" type="file" accept="text/vcard,text/x-vcard,text/directory" name="file" disabled />
|
||||
</li>
|
||||
<li class="import-status">
|
||||
<label id="import-status-text"></label>
|
||||
<div id="import-status-progress"></div>
|
||||
</li>
|
||||
<ul class="oc-addnew">
|
||||
<li id="import-contacts"><a class="oc-addnew-init"><?php p($l->t('Import')); ?></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div> <!-- app-settings-content -->
|
||||
@ -136,6 +115,7 @@ use OCA\Contacts\ImportManager;
|
||||
<p><?php p($l->t('Add a new contact or import existing contacts from a VCF file.')); ?></p>
|
||||
<div id="selections">
|
||||
<input type="button" class="add-contact text" value="<?php p($l->t('New contact')) ?>">
|
||||
<input type="button" id="oc-import-nocontact" value="<?php p($l->t('Import contacts')); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -517,6 +497,41 @@ use OCA\Contacts\ImportManager;
|
||||
</li>
|
||||
</script>
|
||||
|
||||
<script id="contactsImportTemplate" class="hidden" type="text/template">
|
||||
<div id="contacts-import-div" class="contacts-import-class">
|
||||
<p id="contacts-import-into-p">
|
||||
<label for="contacts-import-into"><?php p($l->t('Addresbook')); ?></label>
|
||||
<select id="contacts-import-into">
|
||||
<option value="-1"><?php p($l->t('Import into...')); ?></option>
|
||||
</select>
|
||||
</p>
|
||||
<p id="contacts-import-format-p">
|
||||
<label for="contacts-import-into"><?php p($l->t('Format')); ?></label>
|
||||
<select id="contacts-import-format">
|
||||
<option value="automatic"><?php p($l->t('Automatic format')); ?></option>
|
||||
<?php
|
||||
$importManager = new ImportManager();
|
||||
$types = $importManager->getTypes();
|
||||
foreach ($types as $id => $label) {
|
||||
echo "<option value=\"$id\">$label</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</p>
|
||||
<p id="contacts-import-upload">
|
||||
<!--<label for="contacts-import-upload"><?php p($l->t('Select file')); ?></label>-->
|
||||
<button class="icon-upload svg tooltipped import-upload-button" title="<?php p($l->t('Select file...')); ?>"></button>
|
||||
<input id="contacts-import-upload-start" class="tooltipped" title="<?php p($l->t('Select file...')); ?>" type="file" name="file" disabled />
|
||||
</p>
|
||||
<p id="contacts-import-status">
|
||||
<div class="import-status">
|
||||
<label id="import-status-text"></label>
|
||||
<div id="import-status-progress"></div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="addressBookConfigTemplate" class="hidden" type="text/template">
|
||||
<div id="addressbooks-ui-div" class="addressbooks-ui-class">
|
||||
<input type="hidden" id="addressbooks-ui-addressbookid" />
|
||||
|
Loading…
Reference in New Issue
Block a user