profile-pane 3.1.2-8a70896f → 3.1.2-c5f42c7e
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.
- package/lib/ContactsCard.d.ts +1 -0
- package/lib/ContactsCard.d.ts.map +1 -1
- package/lib/ContactsCard.js +130 -79
- package/lib/addMeToYourContacts.d.ts.map +1 -1
- package/lib/addMeToYourContacts.js +4 -1
- package/lib/contactsHelpers.d.ts +2 -2
- package/lib/contactsHelpers.d.ts.map +1 -1
- package/lib/contactsHelpers.js +24 -88
- package/lib/profile-pane.js +5645 -5820
- package/lib/profile-pane.js.map +1 -1
- package/lib/profile-pane.min.js +70 -70
- package/lib/profile-pane.min.js.map +1 -1
- package/lib/styles/ContactsCard.css +13 -9
- package/lib/styles/utilities.css +4 -0
- package/lib/texts.d.ts +1 -0
- package/lib/texts.d.ts.map +1 -1
- package/lib/texts.js +2 -1
- package/package.json +3 -3
- package/lib/ttl.d.js +0 -1
package/lib/ContactsCard.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import { DataBrowserContext } from 'pane-registry';
|
|
|
2
2
|
import { AddressBooksData, ContactData } from './contactsTypes';
|
|
3
3
|
import ContactsModuleRdfLib from '@solid-data-modules/contacts-rdflib';
|
|
4
4
|
export declare const createAddressBookUriSelectorDialog: (context: DataBrowserContext, contactsModule: ContactsModuleRdfLib, contactData: ContactData, addressBooksData: AddressBooksData) => HTMLDialogElement;
|
|
5
|
+
export declare const handleContactExistsByName: (context: DataBrowserContext, addressBooksData: AddressBooksData, contactData: ContactData, contactExistsByNameUri: string, fromRegisteredAddressBook: boolean) => Boolean;
|
|
5
6
|
export declare function getButtonContainer(context: DataBrowserContext): HTMLDivElement;
|
|
6
7
|
//# sourceMappingURL=ContactsCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactsCard.d.ts","sourceRoot":"","sources":["../src/ContactsCard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAsB,gBAAgB,EAAE,WAAW,EAAa,MAAM,iBAAiB,CAAA;AAC9F,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;
|
|
1
|
+
{"version":3,"file":"ContactsCard.d.ts","sourceRoot":"","sources":["../src/ContactsCard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAsB,gBAAgB,EAAE,WAAW,EAAa,MAAM,iBAAiB,CAAA;AAC9F,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAUtE,eAAO,MAAM,kCAAkC,GAAI,SAAS,kBAAkB,EAC5E,gBAAgB,oBAAoB,EACpC,aAAa,WAAW,EACxB,kBAAkB,gBAAgB,KACjC,iBAuCF,CAAA;AAgvBD,eAAO,MAAM,yBAAyB,GACpC,SAAS,kBAAkB,EAC3B,kBAAkB,gBAAgB,EAClC,aAAa,WAAW,EACxB,wBAAwB,MAAM,EAC9B,2BAA2B,OAAO,KACjC,OAkEF,CAAA;AAqDD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,GAC1B,cAAc,CAIhB"}
|
package/lib/ContactsCard.js
CHANGED
|
@@ -5,10 +5,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.createAddressBookUriSelectorDialog = void 0;
|
|
7
7
|
exports.getButtonContainer = getButtonContainer;
|
|
8
|
+
exports.handleContactExistsByName = void 0;
|
|
8
9
|
var _contactsHelpers = require("./contactsHelpers");
|
|
10
|
+
var _contactsPane = require("contacts-pane");
|
|
9
11
|
var _buttonsHelper = require("./buttonsHelper");
|
|
10
12
|
var _texts = require("./texts");
|
|
11
13
|
var _contactsErrors = require("./contactsErrors");
|
|
14
|
+
var _rdflib = require("rdflib");
|
|
12
15
|
const CONTACTS_POPUP_OVERLAY_ID = 'contacts-popup-overlay';
|
|
13
16
|
const CONTACTS_OVERLAY_ACTIVE_CLASS = 'contactsOverlayActive';
|
|
14
17
|
const createAddressBookUriSelectorDialog = (context, contactsModule, contactData, addressBooksData) => {
|
|
@@ -269,8 +272,8 @@ const createNewContactCreationButton = (context, contactsModule, addressBooksDat
|
|
|
269
272
|
const setButtonOnClickHandler = async event => {
|
|
270
273
|
event.preventDefault();
|
|
271
274
|
const contactExistsByWebID = (0, _contactsHelpers.checkIfContactExistsByWebID)(addressBooksData, contactData.webID);
|
|
272
|
-
const
|
|
273
|
-
const contactExistsHandled =
|
|
275
|
+
const contactExistsByNameUri = (0, _contactsHelpers.checkIfContactExistsByName)(addressBooksData, contactData.name);
|
|
276
|
+
const contactExistsHandled = handleContactExistsFromNonRegisteredAddressBook(context, addressBooksData, contactData, contactExistsByWebID, contactExistsByNameUri);
|
|
274
277
|
if (contactExistsHandled) return;
|
|
275
278
|
let selectedAddressBookUri = null;
|
|
276
279
|
let selectedGroupUris = [];
|
|
@@ -288,7 +291,7 @@ const createNewContactCreationButton = (context, contactsModule, addressBooksDat
|
|
|
288
291
|
groupUris: selectedGroupUris
|
|
289
292
|
};
|
|
290
293
|
try {
|
|
291
|
-
const contactUri = await (0, _contactsHelpers.createContactInAddressBook)(context, contactsModule,
|
|
294
|
+
const contactUri = await (0, _contactsHelpers.createContactInAddressBook)(context, contactsModule, contactData, selectedAddressBookUris);
|
|
292
295
|
finalizeContactEntry(context, addressBooksData, contactData, contactUri);
|
|
293
296
|
} catch (error) {
|
|
294
297
|
(0, _contactsErrors.addErrorToErrorDisplay)(context, `${_texts.errorContactCreation}\n${error}`);
|
|
@@ -368,31 +371,35 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
|
|
|
368
371
|
const newAddressBookEventListener = async event => {
|
|
369
372
|
event.preventDefault();
|
|
370
373
|
let enteredAddressBookUri = null;
|
|
371
|
-
let
|
|
374
|
+
let newGroupNode = null;
|
|
372
375
|
const addressNameField = context.dom.querySelector('#addressBookNameInput');
|
|
373
376
|
|
|
374
377
|
// @ts-ignore
|
|
375
|
-
const enteredAddressName = addressNameField.value;
|
|
378
|
+
const enteredAddressName = sanitizeInput(addressNameField.value);
|
|
379
|
+
// @ts-ignore
|
|
380
|
+
addressNameField.value = enteredAddressName;
|
|
376
381
|
const addressContainerField = context.dom.querySelector('#addressBookContainerInput');
|
|
377
382
|
|
|
378
383
|
// @ts-ignore
|
|
379
|
-
const enteredAddressContainer = addressContainerField.value;
|
|
384
|
+
const enteredAddressContainer = sanitizeInput(addressContainerField.value);
|
|
385
|
+
// @ts-ignore
|
|
386
|
+
addressContainerField.value = enteredAddressContainer;
|
|
380
387
|
const groupNameField = context.dom.querySelector('#groupNameInput');
|
|
381
388
|
// @ts-ignore
|
|
382
|
-
const enteredGroupName = groupNameField.value;
|
|
389
|
+
const enteredGroupName = sanitizeInput(groupNameField.value);
|
|
390
|
+
// @ts-ignore
|
|
391
|
+
groupNameField.value = enteredGroupName;
|
|
383
392
|
if (enteredAddressName) {
|
|
384
393
|
// add addressbook first
|
|
385
394
|
try {
|
|
386
395
|
enteredAddressBookUri = await (0, _contactsHelpers.handleAddressBookCreation)(context, enteredAddressContainer, enteredAddressName);
|
|
387
396
|
const books = await (0, _contactsHelpers.addANewAddressBookUriToAddressBooks)(context, contactsModule, addressBooksData, enteredAddressBookUri);
|
|
388
397
|
if (enteredGroupName) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
groupName: enteredGroupName
|
|
392
|
-
});
|
|
398
|
+
const selectedAddressBookNode = new _rdflib.NamedNode(enteredAddressBookUri);
|
|
399
|
+
newGroupNode = await (0, _contactsPane.saveNewGroup)(selectedAddressBookNode, enteredGroupName);
|
|
393
400
|
const groupAdded = await (0, _contactsHelpers.addGroupToAddressBookData)(addressBooksData, enteredAddressBookUri, {
|
|
394
401
|
name: enteredGroupName,
|
|
395
|
-
uri:
|
|
402
|
+
uri: newGroupNode.value
|
|
396
403
|
});
|
|
397
404
|
if (!groupAdded) {
|
|
398
405
|
(0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.errorGroupCreation);
|
|
@@ -416,7 +423,7 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
|
|
|
416
423
|
const groupCreationButton = context.dom.getElementById('contacts-create-group-button');
|
|
417
424
|
groupCreationButton.remove();
|
|
418
425
|
groupListDiv.appendChild(createGroupButton(context, {
|
|
419
|
-
uri:
|
|
426
|
+
uri: newGroupNode.value,
|
|
420
427
|
name: enteredGroupName
|
|
421
428
|
}));
|
|
422
429
|
groupListDiv.appendChild(groupCreationButton);
|
|
@@ -465,6 +472,10 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
|
|
|
465
472
|
groupNameInputBox.placeholder = 'New group name';
|
|
466
473
|
groupNameInputBox.classList.add('input', 'contactsGroupInput');
|
|
467
474
|
groupNameInputBox.required = true;
|
|
475
|
+
const validationMessage = createValidationMessage(context);
|
|
476
|
+
attachSanitizingValidation(addressBookNameInputBox, validationMessage);
|
|
477
|
+
attachSanitizingValidation(addressBookContainerInputBox, validationMessage);
|
|
478
|
+
attachSanitizingValidation(groupNameInputBox, validationMessage);
|
|
468
479
|
const submitButton = context.dom.createElement('button');
|
|
469
480
|
submitButton.setAttribute('id', 'submit-addressbook');
|
|
470
481
|
submitButton.setAttribute('role', 'button');
|
|
@@ -482,11 +493,13 @@ const createNewAddressBookForm = (context, addressBooksData, contactsModule, con
|
|
|
482
493
|
newAddressBookForm.appendChild(addressBookContainerInputBox);
|
|
483
494
|
newAddressBookForm.appendChild(groupNameLabel);
|
|
484
495
|
newAddressBookForm.appendChild(groupNameInputBox);
|
|
496
|
+
newAddressBookForm.appendChild(validationMessage);
|
|
485
497
|
newAddressBookForm.appendChild(submitButton);
|
|
486
498
|
newAddressBookForm.addEventListener('submit', newAddressBookEventListener);
|
|
487
499
|
return newAddressBookForm;
|
|
488
500
|
};
|
|
489
501
|
const createCloseButton = (context, element, specialClass) => {
|
|
502
|
+
const buttonID = `${element.id}-close-button`;
|
|
490
503
|
const setButtonOnClickHandler = event => {
|
|
491
504
|
event.preventDefault();
|
|
492
505
|
if (element) {
|
|
@@ -499,7 +512,7 @@ const createCloseButton = (context, element, specialClass) => {
|
|
|
499
512
|
}
|
|
500
513
|
};
|
|
501
514
|
const closeButton = context.dom.createElement('button');
|
|
502
|
-
closeButton.setAttribute('id',
|
|
515
|
+
closeButton.setAttribute('id', buttonID);
|
|
503
516
|
closeButton.setAttribute('role', 'button');
|
|
504
517
|
closeButton.setAttribute('type', 'button');
|
|
505
518
|
const ariaLabel = specialClass === 'contactsCloseButton' ? 'Close contacts dialog' : 'Close dialog';
|
|
@@ -520,7 +533,9 @@ const createGroupNameForm = (context, contactsModule, addressBooksData, contactD
|
|
|
520
533
|
});
|
|
521
534
|
const groupNameField = context.dom.querySelector('#groupNameInput');
|
|
522
535
|
// @ts-ignore
|
|
523
|
-
const enteredGroupName = groupNameField.value;
|
|
536
|
+
const enteredGroupName = sanitizeInput(groupNameField.value);
|
|
537
|
+
// @ts-ignore
|
|
538
|
+
groupNameField.value = enteredGroupName;
|
|
524
539
|
if (!selectedAddressBookUri) {
|
|
525
540
|
(0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.errorNotExistsAddressBookUri);
|
|
526
541
|
return;
|
|
@@ -528,13 +543,11 @@ const createGroupNameForm = (context, contactsModule, addressBooksData, contactD
|
|
|
528
543
|
if (enteredGroupName) {
|
|
529
544
|
// add group first
|
|
530
545
|
try {
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
groupName: enteredGroupName
|
|
534
|
-
});
|
|
546
|
+
const selectedAddressBookNode = new _rdflib.NamedNode(selectedAddressBookUri);
|
|
547
|
+
const newGroupNode = await (0, _contactsPane.saveNewGroup)(selectedAddressBookNode, enteredGroupName);
|
|
535
548
|
const newGroup = {
|
|
536
549
|
name: enteredGroupName,
|
|
537
|
-
uri:
|
|
550
|
+
uri: newGroupNode.value
|
|
538
551
|
};
|
|
539
552
|
const wasUpdated = (0, _contactsHelpers.addGroupToAddressBookData)(addressBooksData, selectedAddressBookUri, newGroup);
|
|
540
553
|
if (!wasUpdated) {
|
|
@@ -569,10 +582,13 @@ const createGroupNameForm = (context, contactsModule, addressBooksData, contactD
|
|
|
569
582
|
groupNameInputBox.id = 'groupNameInput';
|
|
570
583
|
groupNameInputBox.placeholder = 'New group name';
|
|
571
584
|
groupNameInputBox.classList.add('input', 'contactsGroupInput');
|
|
585
|
+
const validationMessage = createValidationMessage(context);
|
|
586
|
+
attachSanitizingValidation(groupNameInputBox, validationMessage);
|
|
572
587
|
const submitButton = createAddGroupButton(context, newGroupForm);
|
|
573
588
|
const closeButton = createCloseButton(context, newGroupForm, 'contactsGroupCreationCloseButton');
|
|
574
589
|
newGroupForm.appendChild(groupNameLabel);
|
|
575
590
|
newGroupForm.appendChild(groupNameInputBox);
|
|
591
|
+
newGroupForm.appendChild(validationMessage);
|
|
576
592
|
newGroupForm.appendChild(submitButton);
|
|
577
593
|
newGroupForm.appendChild(closeButton);
|
|
578
594
|
return newGroupForm;
|
|
@@ -593,75 +609,85 @@ const createAddGroupButton = (context, form) => {
|
|
|
593
609
|
button.addEventListener('click', setButtonOnClickHandler);
|
|
594
610
|
return button;
|
|
595
611
|
};
|
|
596
|
-
const
|
|
612
|
+
const handleContactExistsFromNonRegisteredAddressBook = (context, addressBooksData, contactData, contactExistsByWebID, contactExistsByNameUri) => {
|
|
597
613
|
if (contactExistsByWebID) {
|
|
598
614
|
(0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.contactExistsMessage);
|
|
599
615
|
return true;
|
|
600
|
-
} else if (
|
|
601
|
-
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
contactExistsDiv.setAttribute('role', 'alert');
|
|
605
|
-
contactExistsDiv.setAttribute('aria-live', 'assertive');
|
|
606
|
-
contactExistsDiv.setAttribute('tabindex', '0');
|
|
607
|
-
contactExistsDiv.setAttribute('aria-label', 'Alert message indicating that the contact already exists');
|
|
608
|
-
contactExistsDiv.setAttribute('id', 'contacts-contact-exists');
|
|
609
|
-
contactExistsDiv.classList.add('contactsContactExistsAlert');
|
|
610
|
-
contactExistsDiv.innerHTML = `${contactData.name} already exists. \n Do you want to add their WebID?`;
|
|
611
|
-
const confirmButton = context.dom.createElement('button');
|
|
612
|
-
confirmButton.setAttribute('id', 'contacts-confirm-add-webid-button');
|
|
613
|
-
confirmButton.setAttribute('role', 'button');
|
|
614
|
-
confirmButton.setAttribute('type', 'button');
|
|
615
|
-
confirmButton.setAttribute('aria-label', 'Confirm adding the contact webID to the existing contact');
|
|
616
|
-
confirmButton.setAttribute('tabindex', '0');
|
|
617
|
-
confirmButton.classList.add('contactsConfirmButton');
|
|
618
|
-
confirmButton.innerHTML = 'Yes';
|
|
619
|
-
confirmButton.addEventListener('click', async event => {
|
|
620
|
-
event.preventDefault();
|
|
621
|
-
await (0, _contactsHelpers.addWebIDToExistingContact)(context, contactsModule, addressBooksData, contactData.webID, contactExistsByName);
|
|
622
|
-
finalizeContactEntry(context, addressBooksData, contactData, addressBooksData.contactWebIDs.get(contactData.webID));
|
|
623
|
-
(0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
|
|
624
|
-
});
|
|
625
|
-
const cancelButton = context.dom.createElement('button');
|
|
626
|
-
cancelButton.setAttribute('id', 'contacts-cancel-add-webid-button');
|
|
627
|
-
cancelButton.setAttribute('role', 'button');
|
|
628
|
-
cancelButton.setAttribute('type', 'button');
|
|
629
|
-
cancelButton.setAttribute('aria-label', 'Cancel adding the contact webID to the existing contact');
|
|
630
|
-
cancelButton.setAttribute('tabindex', '0');
|
|
631
|
-
cancelButton.classList.add('contactsCancelButton');
|
|
632
|
-
cancelButton.innerHTML = 'No';
|
|
633
|
-
cancelButton.addEventListener('click', event => {
|
|
634
|
-
event.preventDefault();
|
|
635
|
-
selectorDialog.remove();
|
|
636
|
-
(0, _buttonsHelper.complain)(getButtonContainer(context), context, 'Contact was not added');
|
|
637
|
-
setTimeout(() => {
|
|
638
|
-
(0, _buttonsHelper.clearPreviousMessage)(getButtonContainer(context));
|
|
639
|
-
}, 2000);
|
|
640
|
-
(0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
|
|
641
|
-
});
|
|
642
|
-
const actionsDiv = context.dom.createElement('div');
|
|
643
|
-
actionsDiv.setAttribute('id', 'contacts-contact-exists-actions');
|
|
644
|
-
actionsDiv.setAttribute('role', 'group');
|
|
645
|
-
actionsDiv.setAttribute('aria-label', 'Actions for existing contact alert');
|
|
646
|
-
actionsDiv.setAttribute('tabindex', '0');
|
|
647
|
-
actionsDiv.classList.add('contactsContactExistsActions');
|
|
648
|
-
actionsDiv.appendChild(confirmButton);
|
|
649
|
-
actionsDiv.appendChild(cancelButton);
|
|
650
|
-
contactExistsDiv.appendChild(actionsDiv);
|
|
651
|
-
showPopupOverlay(context);
|
|
652
|
-
selectorDialog.appendChild(contactExistsDiv);
|
|
653
|
-
return true;
|
|
616
|
+
} else if (contactExistsByNameUri) {
|
|
617
|
+
const fromRegisteredAddressBook = false;
|
|
618
|
+
const handled = handleContactExistsByName(context, addressBooksData, contactData, contactExistsByNameUri, fromRegisteredAddressBook);
|
|
619
|
+
return handled;
|
|
654
620
|
}
|
|
655
621
|
return false;
|
|
656
622
|
};
|
|
623
|
+
const handleContactExistsByName = (context, addressBooksData, contactData, contactExistsByNameUri, fromRegisteredAddressBook) => {
|
|
624
|
+
const selectorDialog = context.dom.getElementById('contacts-selector-dialog');
|
|
625
|
+
const buttonContainer = getButtonContainer(context);
|
|
626
|
+
const contactExistsDiv = context.dom.createElement('div');
|
|
627
|
+
contactExistsDiv.setAttribute('role', 'alert');
|
|
628
|
+
contactExistsDiv.setAttribute('aria-live', 'assertive');
|
|
629
|
+
contactExistsDiv.setAttribute('tabindex', '0');
|
|
630
|
+
contactExistsDiv.setAttribute('aria-label', 'Alert message indicating that the contact already exists');
|
|
631
|
+
contactExistsDiv.setAttribute('id', 'contacts-contact-exists');
|
|
632
|
+
contactExistsDiv.classList.add('contactsContactExistsAlert');
|
|
633
|
+
contactExistsDiv.innerHTML = `${contactData.name} already exists. \n Do you want to add their WebID?`;
|
|
634
|
+
const confirmButton = context.dom.createElement('button');
|
|
635
|
+
confirmButton.setAttribute('id', 'contacts-confirm-add-webid-button');
|
|
636
|
+
confirmButton.setAttribute('role', 'button');
|
|
637
|
+
confirmButton.setAttribute('type', 'button');
|
|
638
|
+
confirmButton.setAttribute('aria-label', 'Confirm adding the contact webID to the existing contact');
|
|
639
|
+
confirmButton.setAttribute('tabindex', '0');
|
|
640
|
+
confirmButton.classList.add('contactsConfirmButton');
|
|
641
|
+
confirmButton.innerHTML = 'Yes';
|
|
642
|
+
confirmButton.addEventListener('click', async event => {
|
|
643
|
+
event.preventDefault();
|
|
644
|
+
await (0, _contactsHelpers.addWebIDToExistingContact)(context, contactData, contactExistsByNameUri);
|
|
645
|
+
contactExistsDiv.remove();
|
|
646
|
+
finalizeContactEntry(context, addressBooksData, contactData, addressBooksData.contactWebIDs.get(contactData.webID));
|
|
647
|
+
(0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
|
|
648
|
+
});
|
|
649
|
+
const cancelButton = context.dom.createElement('button');
|
|
650
|
+
cancelButton.setAttribute('id', 'contacts-cancel-add-webid-button');
|
|
651
|
+
cancelButton.setAttribute('role', 'button');
|
|
652
|
+
cancelButton.setAttribute('type', 'button');
|
|
653
|
+
cancelButton.setAttribute('aria-label', 'Cancel adding the contact webID to the existing contact');
|
|
654
|
+
cancelButton.setAttribute('tabindex', '0');
|
|
655
|
+
cancelButton.classList.add('contactsCancelButton');
|
|
656
|
+
cancelButton.innerHTML = 'No';
|
|
657
|
+
cancelButton.addEventListener('click', event => {
|
|
658
|
+
event.preventDefault();
|
|
659
|
+
if (!fromRegisteredAddressBook) selectorDialog.remove();
|
|
660
|
+
contactExistsDiv.remove();
|
|
661
|
+
(0, _buttonsHelper.complain)(getButtonContainer(context), context, 'Contact was not added');
|
|
662
|
+
setTimeout(() => {
|
|
663
|
+
(0, _buttonsHelper.clearPreviousMessage)(getButtonContainer(context));
|
|
664
|
+
}, 2000);
|
|
665
|
+
(0, _contactsHelpers.refreshButton)(context, addressBooksData, contactData);
|
|
666
|
+
});
|
|
667
|
+
const actionsDiv = context.dom.createElement('div');
|
|
668
|
+
actionsDiv.setAttribute('id', 'contacts-contact-exists-actions');
|
|
669
|
+
actionsDiv.setAttribute('role', 'group');
|
|
670
|
+
actionsDiv.setAttribute('aria-label', 'Actions for existing contact alert');
|
|
671
|
+
actionsDiv.setAttribute('tabindex', '0');
|
|
672
|
+
actionsDiv.classList.add('contactsContactExistsActions');
|
|
673
|
+
actionsDiv.appendChild(confirmButton);
|
|
674
|
+
actionsDiv.appendChild(cancelButton);
|
|
675
|
+
contactExistsDiv.appendChild(actionsDiv);
|
|
676
|
+
showPopupOverlay(context);
|
|
677
|
+
if (fromRegisteredAddressBook) {
|
|
678
|
+
buttonContainer.appendChild(contactExistsDiv);
|
|
679
|
+
} else {
|
|
680
|
+
selectorDialog.appendChild(contactExistsDiv);
|
|
681
|
+
}
|
|
682
|
+
return true;
|
|
683
|
+
};
|
|
684
|
+
exports.handleContactExistsByName = handleContactExistsByName;
|
|
657
685
|
const finalizeContactEntry = (context, addressBooksData, contactData, contactUri) => {
|
|
658
686
|
addressBooksData.contactWebIDs.set(contactData.webID, contactUri);
|
|
659
687
|
const selectorDialog = context.dom.getElementById('contacts-selector-dialog');
|
|
660
|
-
selectorDialog.remove();
|
|
688
|
+
if (selectorDialog) selectorDialog.remove();
|
|
661
689
|
const buttonContainer = getButtonContainer(context);
|
|
662
690
|
(0, _buttonsHelper.mention)(buttonContainer, _texts.contactWasAddedSuccesMessage);
|
|
663
|
-
const button = context.dom.getElementById('add-to-contacts-button');
|
|
664
|
-
button.removeAttribute('disabled');
|
|
665
691
|
setTimeout(() => {
|
|
666
692
|
(0, _buttonsHelper.clearPreviousMessage)(buttonContainer);
|
|
667
693
|
}, 2000);
|
|
@@ -718,4 +744,29 @@ const removePopupOverlayIfNoPopup = context => {
|
|
|
718
744
|
const overlay = selectorDialog.querySelector(`#${CONTACTS_POPUP_OVERLAY_ID}`);
|
|
719
745
|
if (overlay) overlay.remove();
|
|
720
746
|
selectorDialog.classList.remove(CONTACTS_OVERLAY_ACTIVE_CLASS);
|
|
721
|
-
};
|
|
747
|
+
};
|
|
748
|
+
/* Sanitization and validation */
|
|
749
|
+
function sanitizeInput(input) {
|
|
750
|
+
return (input || '').replace(/[^a-zA-Z0-9 ]+/g, '').replace(/\s+/g, ' ').trim();
|
|
751
|
+
}
|
|
752
|
+
function attachSanitizingValidation(input, feedbackElement) {
|
|
753
|
+
input.addEventListener('input', () => {
|
|
754
|
+
const rawValue = input.value;
|
|
755
|
+
const sanitizedValue = sanitizeInput(rawValue);
|
|
756
|
+
if (rawValue !== sanitizedValue) {
|
|
757
|
+
input.value = sanitizedValue;
|
|
758
|
+
input.setAttribute('aria-invalid', 'true');
|
|
759
|
+
feedbackElement.textContent = 'Only letters, numbers, and spaces are allowed.';
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
input.removeAttribute('aria-invalid');
|
|
763
|
+
feedbackElement.textContent = '';
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
function createValidationMessage(context) {
|
|
767
|
+
const validationMessage = context.dom.createElement('p');
|
|
768
|
+
validationMessage.setAttribute('role', 'status');
|
|
769
|
+
validationMessage.setAttribute('aria-live', 'polite');
|
|
770
|
+
validationMessage.classList.add('contactsInputValidationMessage');
|
|
771
|
+
return validationMessage;
|
|
772
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addMeToYourContacts.d.ts","sourceRoot":"","sources":["../src/addMeToYourContacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAa,SAAS,EAAE,MAAM,QAAQ,CAAA;AAM7C,OAAO,EAAE,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"addMeToYourContacts.d.ts","sourceRoot":"","sources":["../src/addMeToYourContacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAa,SAAS,EAAE,MAAM,QAAQ,CAAA;AAM7C,OAAO,EAAE,gBAAgB,EAAe,MAAM,iBAAiB,CAAA;AAK/D,OAAO,0BAA0B,CAAA;AACjC,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAMtE,QAAA,MAAM,sBAAsB,GAC1B,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,cAAc,CAmBxB,CAAA;AAED,QAAA,MAAM,+BAA+B,GACnC,SAAS,SAAS,EAClB,SAAS,kBAAkB,KAC1B,OAAO,CAAC,iBAAiB,CA2D3B,CAAA;AAED,iBAAe,cAAc,CAC3B,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,GACjC,OAAO,CAAC,IAAI,CAAC,CA4Bf;AAED,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,cAAc,EACf,CAAA"}
|
|
@@ -14,6 +14,7 @@ var _texts = require("./texts");
|
|
|
14
14
|
require("./styles/ProfileCard.css");
|
|
15
15
|
var _contactsRdflib = _interopRequireDefault(require("@solid-data-modules/contacts-rdflib"));
|
|
16
16
|
var _contactsErrors = require("./contactsErrors");
|
|
17
|
+
var _ContactsCard = require("./ContactsCard");
|
|
17
18
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
19
|
let buttonContainer = document.createElement('section');
|
|
19
20
|
const addMeToYourContactsDiv = async (subject, context) => {
|
|
@@ -104,7 +105,9 @@ async function saveNewContact(subject, context, contactsModule, addressBooksData
|
|
|
104
105
|
const contactData = await (0, _contactsHelpers.getContactData)(store, subject);
|
|
105
106
|
const contactExistsByNameUri = (0, _contactsHelpers.checkIfContactExistsByName)(addressBooksData, contactData.name);
|
|
106
107
|
if (contactExistsByNameUri) {
|
|
107
|
-
|
|
108
|
+
const fromRegisteredAddressBook = true;
|
|
109
|
+
const handled = (0, _ContactsCard.handleContactExistsByName)(context, addressBooksData, contactData, contactExistsByNameUri, fromRegisteredAddressBook);
|
|
110
|
+
if (!handled) (0, _contactsErrors.addErrorToErrorDisplay)(context, _texts.errorAddingContactWebIDToAddressBook);
|
|
108
111
|
} else {
|
|
109
112
|
await (0, _contactsHelpers.addContactToAddressBook)(context, contactsModule, contactData, addressBooksData, buttonContainer);
|
|
110
113
|
}
|
package/lib/contactsHelpers.d.ts
CHANGED
|
@@ -10,13 +10,13 @@ declare function addANewAddressBookUriToAddressBooks(context: DataBrowserContext
|
|
|
10
10
|
addressBooksData: AddressBooksData;
|
|
11
11
|
addressBook: AddressBookDetails;
|
|
12
12
|
}>;
|
|
13
|
-
declare function createContactInAddressBook(context: DataBrowserContext, contactsModule: ContactsModuleRdfLib,
|
|
13
|
+
declare function createContactInAddressBook(context: DataBrowserContext, contactsModule: ContactsModuleRdfLib, contactData: ContactData, selectedAddressBookUris: SelectedAddressBookUris): Promise<string>;
|
|
14
14
|
declare function addAddressToTypeIndex(context: DataBrowserContext, typeOfIndex: string, addressBookUri: string): Promise<boolean>;
|
|
15
15
|
declare function updateAddressBookName(context: DataBrowserContext, addressBookUri: string, newName: string): Promise<void>;
|
|
16
16
|
declare function refreshButton(context: DataBrowserContext, addressBooksData: AddressBooksData, contactData: ContactData): void;
|
|
17
17
|
declare function checkIfContactExistsByWebID(addressBooksData: AddressBooksData, subjectUri: string): boolean;
|
|
18
18
|
declare function checkIfContactExistsByName(addressBooksData: AddressBooksData, name: string): string | null;
|
|
19
|
-
declare function addWebIDToExistingContact(context: DataBrowserContext,
|
|
19
|
+
declare function addWebIDToExistingContact(context: DataBrowserContext, contactData: ContactData, contactUri: string): Promise<void>;
|
|
20
20
|
declare function addGroupToAddressBookData(addressBooksData: AddressBooksData, addressBookUri: string, group: GroupData): boolean;
|
|
21
21
|
declare function handleAddressBookCreation(dataBrowserContext: DataBrowserContext, containerName: string, enteredAddressName: string): Promise<string>;
|
|
22
22
|
export { getAddressBooksData, getContactData, addContactToAddressBook, createContactInAddressBook, addAddressToTypeIndex, refreshButton, checkIfContactExistsByWebID, checkIfContactExistsByName, addWebIDToExistingContact, addANewAddressBookUriToAddressBooks, addGroupToAddressBookData, updateAddressBookName, handleAddressBookCreation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contactsHelpers.d.ts","sourceRoot":"","sources":["../src/contactsHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,QAAQ,CAAA;AAE/D,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,2BAA2B,CAAA;AAElC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAgB,SAAS,EAAgB,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAMnJ,iBAAe,uBAAuB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,cAAc,iBAM1B;
|
|
1
|
+
{"version":3,"file":"contactsHelpers.d.ts","sourceRoot":"","sources":["../src/contactsHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAoB,MAAM,QAAQ,CAAA;AAE/D,OAAO,oBAAoB,MAAM,qCAAqC,CAAA;AAEtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,2BAA2B,CAAA;AAElC,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,WAAW,EAAgB,SAAS,EAAgB,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAMnJ,iBAAe,uBAAuB,CACpC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,cAAc,iBAM1B;AAgGD,iBAAe,mBAAmB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,oBAAoB,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAkBD,iBAAe,cAAc,CAC3B,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,WAAW,CAAC,CA8BtB;AAED,iBAAe,mCAAmC,CAChD,OAAO,EAAC,kBAAkB,EAC1B,cAAc,EAAE,oBAAoB,EACpC,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,MAAM,GAC5B,OAAO,CAAC;IAAE,gBAAgB,EAAE,gBAAgB,CAAC;IAAC,WAAW,EAAE,kBAAkB,CAAA;CAAE,CAAC,CA2BlF;AAED,iBAAe,0BAA0B,CACvC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,oBAAoB,EACpC,WAAW,EAAE,WAAW,EACxB,uBAAuB,EAAE,uBAAuB,GAC/C,OAAO,CAAC,MAAM,CAAC,CA0BjB;AA0CD,iBAAe,qBAAqB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED,iBAAe,qBAAqB,CAClC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,iBA0BhB;AAED,iBAAS,aAAa,CACpB,OAAO,EAAE,kBAAkB,EAC3B,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,WAAW,QAwBvB;AAEH,iBAAS,2BAA2B,CAClC,gBAAgB,EAAE,gBAAgB,EAClC,UAAU,EAAE,MAAM,GACjB,OAAO,CAGT;AAED,iBAAS,0BAA0B,CACjC,gBAAgB,EAAE,gBAAgB,EAClC,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAYf;AAED,iBAAe,yBAAyB,CACtC,OAAO,EAAE,kBAAkB,EAC3B,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,iBAUnB;AAED,iBAAS,yBAAyB,CAChC,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,SAAS,GACf,OAAO,CA0BT;AASD,iBAAe,yBAAyB,CACtC,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,CAAC,CA8CjB;AAED,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,EACrB,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,qBAAqB,EACrB,yBAAyB,EAC1B,CAAA"}
|
package/lib/contactsHelpers.js
CHANGED
|
@@ -24,8 +24,8 @@ var _solidLogic = require("solid-logic");
|
|
|
24
24
|
var _texts = require("./texts");
|
|
25
25
|
var _buttonsHelper = require("./buttonsHelper");
|
|
26
26
|
var _contactsErrors = require("./contactsErrors");
|
|
27
|
-
var _contactsPane =
|
|
28
|
-
function
|
|
27
|
+
var _contactsPane = _interopRequireWildcard(require("contacts-pane"));
|
|
28
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
29
29
|
async function addContactToAddressBook(context, contactsModule, contactData, addressBooksData, container) {
|
|
30
30
|
const addressBookUriSelectorDialog = (0, _ContactsCard.createAddressBookUriSelectorDialog)(context, contactsModule, contactData, addressBooksData);
|
|
31
31
|
container.appendChild(addressBookUriSelectorDialog);
|
|
@@ -63,15 +63,6 @@ async function getWebID(context, contact) {
|
|
|
63
63
|
async function getAddressBooks(context, contactsModule) {
|
|
64
64
|
const allContacts = [];
|
|
65
65
|
const me = _solidLogic.authn.currentUser();
|
|
66
|
-
const dom = context.dom;
|
|
67
|
-
const div = dom.getElementById('add-to-contacts-button-container');
|
|
68
|
-
const contextForFindAppInstances = {
|
|
69
|
-
target: me,
|
|
70
|
-
me,
|
|
71
|
-
noun: 'address book',
|
|
72
|
-
div,
|
|
73
|
-
dom
|
|
74
|
-
};
|
|
75
66
|
let addressBooksData = {
|
|
76
67
|
public: new Map(),
|
|
77
68
|
private: new Map(),
|
|
@@ -80,14 +71,7 @@ async function getAddressBooks(context, contactsModule) {
|
|
|
80
71
|
};
|
|
81
72
|
try {
|
|
82
73
|
await context.session.store.fetcher.load(me);
|
|
83
|
-
|
|
84
|
-
const addressBookNodes = addressBookContext.instances;
|
|
85
|
-
let addressBookUris = {
|
|
86
|
-
publicUris: (addressBookNodes || []).map(node => node.value),
|
|
87
|
-
privateUris: []
|
|
88
|
-
};
|
|
89
|
-
// let addressBookUris = await contactsModule.listAddressBooks(me.value)
|
|
90
|
-
|
|
74
|
+
let addressBookUris = await contactsModule.listAddressBooks(me.value);
|
|
91
75
|
const publicAddressBookPromises = addressBookUris.publicUris.map(addressBook => getAddressData(context, contactsModule, addressBook));
|
|
92
76
|
const publicAddressBooksData = await Promise.all(publicAddressBookPromises);
|
|
93
77
|
publicAddressBooksData.map(addressBook => {
|
|
@@ -204,8 +188,9 @@ async function addANewAddressBookUriToAddressBooks(context, contactsModule, addr
|
|
|
204
188
|
addressBook: contactsAddressBook
|
|
205
189
|
};
|
|
206
190
|
}
|
|
207
|
-
async function createContactInAddressBook(context, contactsModule,
|
|
191
|
+
async function createContactInAddressBook(context, contactsModule, contactData, selectedAddressBookUris) {
|
|
208
192
|
let contactUri = null;
|
|
193
|
+
const store = context.session.store;
|
|
209
194
|
const newContact = {
|
|
210
195
|
name: contactData.name
|
|
211
196
|
};
|
|
@@ -222,7 +207,8 @@ async function createContactInAddressBook(context, contactsModule, addressBooksD
|
|
|
222
207
|
return;
|
|
223
208
|
}
|
|
224
209
|
await context.session.store.fetcher.load(contactUri);
|
|
225
|
-
|
|
210
|
+
const contactNode = new _rdflib.NamedNode(contactUri);
|
|
211
|
+
await (0, _contactsPane.addWebIDToContacts)(contactNode, contactData.webID, _solidUi.ns.vcard('WebID'), store);
|
|
226
212
|
if (contactData.emails.length || contactData.phoneNumbers.length) {
|
|
227
213
|
await addContactDetails(context, contactUri, contactData);
|
|
228
214
|
}
|
|
@@ -261,29 +247,6 @@ async function addContactDetails(context, contactUri, contactData) {
|
|
|
261
247
|
(0, _contactsErrors.addErrorToErrorDisplay)(context, error);
|
|
262
248
|
}
|
|
263
249
|
}
|
|
264
|
-
async function addWebIDToContact(context, groupUris, contactUri, webID) {
|
|
265
|
-
const store = context.session.store;
|
|
266
|
-
const contactNode = new _rdflib.NamedNode(contactUri);
|
|
267
|
-
const webIDNode = (0, _rdflib.sym)(webID);
|
|
268
|
-
const vcardURLNode = store.bnode();
|
|
269
|
-
let groupUriNode = null;
|
|
270
|
-
try {
|
|
271
|
-
if (groupUris?.length) {
|
|
272
|
-
for (const groupUri of groupUris) {
|
|
273
|
-
await context.session.store.fetcher.load(groupUri);
|
|
274
|
-
groupUriNode = new _rdflib.NamedNode(groupUri);
|
|
275
|
-
const groupDoc = groupUriNode.doc();
|
|
276
|
-
const deletions = context.session.store.statementsMatching(groupUriNode, _solidUi.ns.vcard('hasMember'), contactNode, groupDoc);
|
|
277
|
-
const insertions = [(0, _rdflib.st)(groupUriNode, _solidUi.ns.vcard('hasMember'), webIDNode, groupDoc), (0, _rdflib.st)(webIDNode, _solidUi.ns.owl('sameAs'), contactNode, groupDoc)];
|
|
278
|
-
await store.updater.update(deletions, insertions);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
const personInsertions = [(0, _rdflib.st)(contactNode, _solidUi.ns.vcard('url'), vcardURLNode, contactNode.doc()), (0, _rdflib.st)(vcardURLNode, _solidUi.ns.rdf('type'), _solidUi.ns.vcard('WebID'), contactNode.doc()), (0, _rdflib.st)(vcardURLNode, _solidUi.ns.vcard('value'), (0, _rdflib.literal)(webID), contactNode.doc())];
|
|
282
|
-
await store.updater.update([], personInsertions);
|
|
283
|
-
} catch (error) {
|
|
284
|
-
(0, _contactsErrors.addErrorToErrorDisplay)(context, error);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
250
|
async function addAddressToTypeIndex(context, typeOfIndex, addressBookUri) {
|
|
288
251
|
const store = context.session.store;
|
|
289
252
|
const me = _solidLogic.authn.currentUser();
|
|
@@ -332,6 +295,7 @@ function refreshButton(context, addressBooksData, contactData) {
|
|
|
332
295
|
//logged in and friend exists or friend was just added
|
|
333
296
|
button.innerHTML = _texts.contactExistsAlreadyButtonText.toUpperCase();
|
|
334
297
|
button.onclick = null;
|
|
298
|
+
button.setAttribute('disabled', '');
|
|
335
299
|
} else if (contactExistsByName) {
|
|
336
300
|
button.innerHTML = _texts.contactExistsAlreadyByNameButtonText.toUpperCase();
|
|
337
301
|
button.removeAttribute('disabled');
|
|
@@ -358,52 +322,16 @@ function checkIfContactExistsByName(addressBooksData, name) {
|
|
|
358
322
|
});
|
|
359
323
|
return contactUri;
|
|
360
324
|
}
|
|
361
|
-
async function addWebIDToExistingContact(context,
|
|
325
|
+
async function addWebIDToExistingContact(context, contactData, contactUri) {
|
|
326
|
+
const store = context.session.store;
|
|
362
327
|
try {
|
|
363
|
-
|
|
364
|
-
|
|
328
|
+
await context.session.store.fetcher.load(contactUri);
|
|
329
|
+
const contactNode = new _rdflib.NamedNode(contactUri);
|
|
330
|
+
await (0, _contactsPane.addWebIDToContacts)(contactNode, contactData.webID, _solidUi.ns.vcard('WebID'), store);
|
|
365
331
|
} catch (error) {
|
|
366
332
|
(0, _contactsErrors.addErrorToErrorDisplay)(context, error);
|
|
367
333
|
}
|
|
368
334
|
}
|
|
369
|
-
async function getGroupUrisForContact(contactsModule, addressBooksData, contactUri) {
|
|
370
|
-
let groupUrisForContact = [];
|
|
371
|
-
let addressBookForContact = null;
|
|
372
|
-
let allGroupUrisForAddressBook = [];
|
|
373
|
-
addressBooksData.public.forEach((book, uri) => {
|
|
374
|
-
book.contacts.map(contact => {
|
|
375
|
-
if (contact.uri === contactUri) {
|
|
376
|
-
addressBookForContact = book;
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
addressBooksData.private.forEach((book, uri) => {
|
|
381
|
-
book.contacts.map(contact => {
|
|
382
|
-
if (contact.uri === contactUri) {
|
|
383
|
-
addressBookForContact = book;
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
});
|
|
387
|
-
allGroupUrisForAddressBook = addressBookForContact.groups;
|
|
388
|
-
const groupPromises = allGroupUrisForAddressBook.map(async group => {
|
|
389
|
-
group = await contactsModule.readGroup(group.uri);
|
|
390
|
-
return {
|
|
391
|
-
groupUri: group.uri,
|
|
392
|
-
group
|
|
393
|
-
};
|
|
394
|
-
});
|
|
395
|
-
const groups = await Promise.all(groupPromises);
|
|
396
|
-
groups.map(groupInfo => {
|
|
397
|
-
groupInfo.group.members.map(contact => {
|
|
398
|
-
if (contact.uri === contactUri) {
|
|
399
|
-
if (!groupUrisForContact.includes(groupInfo.groupUri)) {
|
|
400
|
-
groupUrisForContact.push(groupInfo.groupUri);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
});
|
|
404
|
-
});
|
|
405
|
-
return groupUrisForContact;
|
|
406
|
-
}
|
|
407
335
|
function addGroupToAddressBookData(addressBooksData, addressBookUri, group) {
|
|
408
336
|
const publicAddressBook = addressBooksData.public.get(addressBookUri);
|
|
409
337
|
if (publicAddressBook) {
|
|
@@ -429,6 +357,9 @@ function addGroupToAddressBookData(addressBooksData, addressBookUri, group) {
|
|
|
429
357
|
}
|
|
430
358
|
return false;
|
|
431
359
|
}
|
|
360
|
+
function sanitizeAlphaNumericSpaces(input) {
|
|
361
|
+
return (input || '').replace(/[^a-zA-Z0-9 ]+/g, '').replace(/\s+/g, ' ').trim();
|
|
362
|
+
}
|
|
432
363
|
async function handleAddressBookCreation(dataBrowserContext, containerName, enteredAddressName) {
|
|
433
364
|
const me = _solidLogic.authn.currentUser();
|
|
434
365
|
const newAddressContainer = me?.site()?.value;
|
|
@@ -438,8 +369,13 @@ async function handleAddressBookCreation(dataBrowserContext, containerName, ente
|
|
|
438
369
|
if (!me || !newAddressContainer) {
|
|
439
370
|
throw new Error(_texts.errorUnableToDetermineUserWorkspace);
|
|
440
371
|
}
|
|
372
|
+
const sanitizedAddressName = sanitizeAlphaNumericSpaces(enteredAddressName);
|
|
373
|
+
if (!sanitizedAddressName) {
|
|
374
|
+
throw new Error('Address book name can only contain letters, numbers, and spaces');
|
|
375
|
+
}
|
|
376
|
+
const sanitizedContainerName = sanitizeAlphaNumericSpaces(containerName);
|
|
441
377
|
const normalizedContainer = newAddressContainer.endsWith('/') ? newAddressContainer : `${newAddressContainer}/`;
|
|
442
|
-
const addressBookSlug = (
|
|
378
|
+
const addressBookSlug = (sanitizedContainerName || 'address-book').trim().toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '') || 'address-book';
|
|
443
379
|
const newBase = `${normalizedContainer}${addressBookSlug}/`;
|
|
444
380
|
const mintResult = await _contactsPane.default.mintNew(dataBrowserContext, {
|
|
445
381
|
me,
|
|
@@ -447,10 +383,10 @@ async function handleAddressBookCreation(dataBrowserContext, containerName, ente
|
|
|
447
383
|
div,
|
|
448
384
|
newBase,
|
|
449
385
|
instanceClass: _solidUi.ns.vcard('AddressBook'),
|
|
450
|
-
instanceName:
|
|
386
|
+
instanceName: sanitizedAddressName
|
|
451
387
|
});
|
|
452
388
|
addressBookUri = mintResult?.newInstance?.uri || `${newBase}index.ttl#this`;
|
|
453
|
-
await updateAddressBookName(dataBrowserContext, addressBookUri,
|
|
389
|
+
await updateAddressBookName(dataBrowserContext, addressBookUri, sanitizedAddressName);
|
|
454
390
|
} catch (error) {
|
|
455
391
|
(0, _contactsErrors.addErrorToErrorDisplay)(dataBrowserContext, _texts.errorAddressBookCreation + '\n' + error);
|
|
456
392
|
}
|