solid-panes 4.2.6 → 4.4.0
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/README.md +42 -0
- package/dist/0314353e28ce6e5539af.svg +9 -0
- package/dist/04567ff683933c35c465.png +0 -0
- package/dist/10163fd9b5a0e00d63a0.png +0 -0
- package/dist/1234dcb2eec2e45f252b.png +0 -0
- package/dist/20899934157df4db56cb.png +0 -0
- package/dist/33760bf79f097f449da5.png +0 -0
- package/dist/4cceba29ab33b1ddd9bb.svg +6 -0
- package/dist/578d2b6ed32e7624164e.png +0 -0
- package/dist/5f62a5b2b7e99b9640c7.png +0 -0
- package/dist/6525766ecd288ec60129.png +0 -0
- package/dist/7800be6f6c4b5b0f4f20.png +0 -0
- package/dist/7b7538c6f6b317968009.svg +9 -0
- package/dist/92d03142abe6efc0b42d.svg +6 -0
- package/dist/976473cf5fe24d657d4b.png +0 -0
- package/dist/RDFXMLPane.js +1 -0
- package/dist/bda84f59e7216675a208.png +0 -0
- package/dist/cd68e8f3990ba8b2139e.png +0 -0
- package/dist/dashboard/basicPreferences.d.ts.map +1 -1
- package/dist/dashboard/basicPreferences.js +1 -0
- package/dist/dashboard/dashboardPane.d.ts.map +1 -1
- package/dist/dashboard/dashboardPane.js +9 -3
- package/dist/dashboard/homepage.d.ts +1 -1
- package/dist/dashboard/homepage.d.ts.map +1 -1
- package/dist/dashboard/homepage.js +5 -35
- package/dist/e7074a7e2cb69e51cfd3.png +0 -0
- package/dist/f3772696fb7ee53c23d8.png +0 -0
- package/dist/form/pane.js +1 -1
- package/dist/home/homePane.d.ts.map +1 -1
- package/dist/home/homePane.js +2 -0
- package/dist/humanReadablePane.js +34 -8
- package/dist/icons/clock.svg +7 -0
- package/dist/icons/comment.svg +6 -0
- package/dist/icons/dashboard.svg +9 -0
- package/dist/icons/downArrow.svg +6 -0
- package/dist/icons/folder.svg +6 -0
- package/dist/icons/friends.svg +9 -0
- package/dist/icons/help.svg +8 -0
- package/dist/icons/iconHelper.d.ts +2 -0
- package/dist/icons/iconHelper.d.ts.map +1 -0
- package/dist/icons/iconHelper.js +23 -0
- package/dist/icons/menu.svg +8 -0
- package/dist/icons/person.svg +6 -0
- package/dist/icons/personInCircle.svg +8 -0
- package/dist/icons/sharing.svg +10 -0
- package/dist/icons/signOut.svg +8 -0
- package/dist/icons/signup.png +0 -0
- package/dist/icons/star.svg +3 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -4
- package/dist/internal/internalPane.d.ts.map +1 -1
- package/dist/internal/internalPane.js +1 -0
- package/dist/mainPage/footer.d.ts +14 -2
- package/dist/mainPage/footer.d.ts.map +1 -1
- package/dist/mainPage/footer.js +21 -13
- package/dist/mainPage/header.d.ts +16 -1
- package/dist/mainPage/header.d.ts.map +1 -1
- package/dist/mainPage/header.js +179 -61
- package/dist/mainPage/index.d.ts +15 -1
- package/dist/mainPage/index.d.ts.map +1 -1
- package/dist/mainPage/index.js +38 -7
- package/dist/mainPage/menu.css +243 -0
- package/dist/mainPage/menu.d.ts +7 -0
- package/dist/mainPage/menu.d.ts.map +1 -0
- package/dist/mainPage/menu.js +409 -0
- package/dist/n3Pane.js +1 -0
- package/dist/outline/context.d.ts +2 -2
- package/dist/outline/context.d.ts.map +1 -1
- package/dist/outline/context.js +5 -2
- package/dist/outline/manager.css +12 -14
- package/dist/outline/manager.js +152 -81
- package/dist/outline/userInput.js +6 -3
- package/dist/pad/padPane.css +36 -0
- package/dist/pad/padPane.d.ts +1 -0
- package/dist/pad/padPane.d.ts.map +1 -1
- package/dist/pad/padPane.js +32 -21
- package/dist/playlist/playlistPane.js +2 -6
- package/dist/profileUtils/ownerProfile.d.ts +5 -0
- package/dist/profileUtils/ownerProfile.d.ts.map +1 -0
- package/dist/profileUtils/ownerProfile.js +84 -0
- package/dist/registerPanes.js +4 -4
- package/dist/slideshow/slideshowPane.js +1 -1
- package/dist/social/editProfileDetails.d.ts +19 -0
- package/dist/social/editProfileDetails.d.ts.map +1 -0
- package/dist/social/editProfileDetails.js +267 -0
- package/dist/social/icons.d.ts +5 -0
- package/dist/social/icons.d.ts.map +1 -0
- package/dist/social/icons.js +60 -0
- package/dist/social/socialPane.css +804 -0
- package/dist/social/socialPane.d.ts +30 -0
- package/dist/social/socialPane.d.ts.map +1 -0
- package/dist/social/socialPane.js +558 -0
- package/dist/social/socialSections.d.ts +66 -0
- package/dist/social/socialSections.d.ts.map +1 -0
- package/dist/social/socialSections.js +317 -0
- package/dist/solid-panes.js +29050 -13866
- package/dist/solid-panes.js.map +1 -1
- package/dist/solid-panes.min.js +2235 -247
- package/dist/solid-panes.min.js.map +1 -1
- package/dist/style/tabbedtab.css +0 -124
- package/dist/tabbed/tabbedPane.d.ts.map +1 -1
- package/dist/tabbed/tabbedPane.js +2 -0
- package/dist/versionInfo.js +3 -3
- package/package.json +13 -8
- package/dist/socialPane.js +0 -430
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownerProfile.d.ts","sourceRoot":"","sources":["../../src/profileUtils/ownerProfile.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAO,MAAM,QAAQ,CAAA;AAKhE,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,SAAS,CAAC,CA0CpB;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED,wBAAgB,OAAO,CAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,GAAG,MAAM,CAMhF"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getName = getName;
|
|
7
|
+
exports.getNameOfPodOwner = getNameOfPodOwner;
|
|
8
|
+
exports.loadProfileFromURI = loadProfileFromURI;
|
|
9
|
+
var _rdflib = require("rdflib");
|
|
10
|
+
var _solidUi = require("solid-ui");
|
|
11
|
+
/*
|
|
12
|
+
* Utility functions to help load the profile
|
|
13
|
+
* especially when I am not logged in
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const DEFAULT_PROFILE_PATH = 'profile/card#me';
|
|
17
|
+
async function loadProfileFromURI(uri, store, fetcher) {
|
|
18
|
+
const pod = uri.site().uri;
|
|
19
|
+
// TODO: This is a hack - we cannot assume that the profile is at this document, but we will live with it for now
|
|
20
|
+
const webId = (0, _rdflib.sym)(`${pod}${DEFAULT_PROFILE_PATH}`);
|
|
21
|
+
try {
|
|
22
|
+
await fetcher.load(webId);
|
|
23
|
+
return webId;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
// continue
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// we try a prefixed pod structure
|
|
29
|
+
try {
|
|
30
|
+
const uriUrl = new URL(uri.uri);
|
|
31
|
+
const pathSegments = uriUrl.pathname.split('/').filter(Boolean);
|
|
32
|
+
if (pathSegments.length > 0) {
|
|
33
|
+
const derivedPod = `${uriUrl.origin}/${pathSegments[0]}/`;
|
|
34
|
+
const derivedWebId = (0, _rdflib.sym)(`${derivedPod}${DEFAULT_PROFILE_PATH}`);
|
|
35
|
+
await fetcher.load(derivedWebId);
|
|
36
|
+
return derivedWebId;
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
// continue
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
await fetcher.load(uri);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
return uri;
|
|
45
|
+
}
|
|
46
|
+
const primaryTopic = store.any(uri, _solidUi.ns.foaf('primaryTopic'), null, uri.doc());
|
|
47
|
+
if (primaryTopic && primaryTopic.termType === 'NamedNode') {
|
|
48
|
+
try {
|
|
49
|
+
await fetcher.load(primaryTopic);
|
|
50
|
+
return primaryTopic;
|
|
51
|
+
} catch (err) {
|
|
52
|
+
return uri;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return uri;
|
|
56
|
+
}
|
|
57
|
+
async function getNameOfPodOwner(pod, store, fetcher) {
|
|
58
|
+
// TODO: This is a hack - we cannot assume that the profile is at this document, but we will live with it for now
|
|
59
|
+
const webId = (0, _rdflib.sym)(`${pod.uri}${DEFAULT_PROFILE_PATH}`);
|
|
60
|
+
try {
|
|
61
|
+
await fetcher.load(webId);
|
|
62
|
+
return getName(store, webId);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
// continue
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// we try a prefixed pod structure
|
|
68
|
+
try {
|
|
69
|
+
const uriUrl = new URL(pod.uri);
|
|
70
|
+
const pathSegments = uriUrl.pathname.split('/').filter(Boolean);
|
|
71
|
+
if (pathSegments.length > 0) {
|
|
72
|
+
const derivedPod = `${uriUrl.origin}/${pathSegments[0]}/`;
|
|
73
|
+
const derivedWebId = (0, _rdflib.sym)(`${derivedPod}${DEFAULT_PROFILE_PATH}`);
|
|
74
|
+
await fetcher.load(derivedWebId);
|
|
75
|
+
return getName(store, derivedWebId);
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
// continue
|
|
79
|
+
}
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
function getName(store, ownersProfile) {
|
|
83
|
+
return store.anyValue(ownersProfile, _solidUi.ns.vcard('fn'), null, ownersProfile.doc()) || store.anyValue(ownersProfile, _solidUi.ns.foaf('name'), null, ownersProfile.doc()) || new URL(ownersProfile.uri).host.split('.')[0];
|
|
84
|
+
}
|
package/dist/registerPanes.js
CHANGED
|
@@ -27,7 +27,7 @@ var _dokieliPane = _interopRequireDefault(require("./dokieli/dokieliPane.js"));
|
|
|
27
27
|
var _folderPane = _interopRequireDefault(require("folder-pane"));
|
|
28
28
|
var _classInstancePane = require("./classInstancePane.js");
|
|
29
29
|
var _slideshowPane = require("./slideshow/slideshowPane.js");
|
|
30
|
-
var _socialPane = require("./socialPane
|
|
30
|
+
var _socialPane = require("./social/socialPane");
|
|
31
31
|
var _humanReadablePane = _interopRequireDefault(require("./humanReadablePane.js"));
|
|
32
32
|
var _dataContentPane = require("./dataContentPane.js");
|
|
33
33
|
var _sourcePane = _interopRequireDefault(require("source-pane"));
|
|
@@ -57,11 +57,11 @@ function registerPanes(register) {
|
|
|
57
57
|
const editProfileView = _profilePane.default.editor;
|
|
58
58
|
if (!editProfileView) {
|
|
59
59
|
console.log('@@@ editProfileView', 'profilePane is not providing an editor pane');
|
|
60
|
+
} else {
|
|
61
|
+
register(editProfileView); // Edit my profile.
|
|
60
62
|
}
|
|
61
|
-
register(editProfileView); // Edit my profile.
|
|
62
|
-
|
|
63
63
|
register(_trustedApplications.default); // must be registered before basicPreferences
|
|
64
|
-
register(
|
|
64
|
+
// register(dashboardPane)
|
|
65
65
|
register(_basicPreferences.default);
|
|
66
66
|
register(_issuePane.default);
|
|
67
67
|
register(_contactsPane.default);
|
|
@@ -62,7 +62,7 @@ const slideshowPane = exports.slideshowPane = {
|
|
|
62
62
|
const objectURL = URL.createObjectURL(myBlob);
|
|
63
63
|
img.setAttribute('src', objectURL); // w640 h480 //
|
|
64
64
|
});
|
|
65
|
-
img.
|
|
65
|
+
img.style.width = '100%';
|
|
66
66
|
figure.appendChild(dom.createElement('figcaption'));
|
|
67
67
|
}
|
|
68
68
|
const options = {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { LiveStore, NamedNode } from 'rdflib';
|
|
2
|
+
type ProfileLinkField = {
|
|
3
|
+
key: 'homepage' | 'weblog' | 'workplaceHomepage' | 'schoolHomepage';
|
|
4
|
+
label: string;
|
|
5
|
+
placeholder: string;
|
|
6
|
+
predicate: NamedNode;
|
|
7
|
+
};
|
|
8
|
+
type EditProfileDetailsButtonOptions = {
|
|
9
|
+
dom: HTMLDocument;
|
|
10
|
+
store: LiveStore;
|
|
11
|
+
subject: NamedNode;
|
|
12
|
+
header: HTMLElement;
|
|
13
|
+
onSaved: () => void;
|
|
14
|
+
};
|
|
15
|
+
export declare const profileLinkFields: ProfileLinkField[];
|
|
16
|
+
export declare function appendProfileLinks(container: HTMLElement, dom: HTMLDocument, store: LiveStore, subject: NamedNode): void;
|
|
17
|
+
export declare function createEditProfileDetailsButton(options: EditProfileDetailsButtonOptions): HTMLButtonElement;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=editProfileDetails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editProfileDetails.d.ts","sourceRoot":"","sources":["../../src/social/editProfileDetails.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAW,MAAM,QAAQ,CAAA;AActD,KAAK,gBAAgB,GAAG;IACtB,GAAG,EAAE,UAAU,GAAG,QAAQ,GAAG,mBAAmB,GAAG,gBAAgB,CAAA;IACnE,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,SAAS,CAAA;CACrB,CAAA;AAID,KAAK,+BAA+B,GAAG;IACrC,GAAG,EAAE,YAAY,CAAA;IACjB,KAAK,EAAE,SAAS,CAAA;IAChB,OAAO,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,WAAW,CAAA;IACnB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,EAyB/C,CAAA;AAuFD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,WAAW,EACtB,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,IAAI,CA2CN;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,iBAAiB,CAiJnB"}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.appendProfileLinks = appendProfileLinks;
|
|
7
|
+
exports.createEditProfileDetailsButton = createEditProfileDetailsButton;
|
|
8
|
+
exports.profileLinkFields = void 0;
|
|
9
|
+
var _rdflib = require("rdflib");
|
|
10
|
+
var _solidUi = require("solid-ui");
|
|
11
|
+
var _icons = require("./icons");
|
|
12
|
+
/* The following code was generated by AI Model: GPT-5.4
|
|
13
|
+
Prompt: can you create me a form to enter this data [
|
|
14
|
+
ns.foaf('homepage'),
|
|
15
|
+
ns.foaf('weblog'),
|
|
16
|
+
ns.foaf('workplaceHomepage'),
|
|
17
|
+
ns.foaf('schoolHomepage')
|
|
18
|
+
] and put an edit button at the top left corner of the header
|
|
19
|
+
that when you click it pops up so you can enter this information
|
|
20
|
+
and save it to the Webid. You can look in
|
|
21
|
+
Dev2025/profile-pane/src/sections/heading/mutations to see how
|
|
22
|
+
to write this data in the profile. */
|
|
23
|
+
|
|
24
|
+
const profileLinkFields = exports.profileLinkFields = [{
|
|
25
|
+
key: 'homepage',
|
|
26
|
+
label: 'Homepage',
|
|
27
|
+
placeholder: 'https://example.com',
|
|
28
|
+
predicate: _solidUi.ns.foaf('homepage')
|
|
29
|
+
}, {
|
|
30
|
+
key: 'weblog',
|
|
31
|
+
label: 'Weblog',
|
|
32
|
+
placeholder: 'https://blog.example.com',
|
|
33
|
+
predicate: _solidUi.ns.foaf('weblog')
|
|
34
|
+
}, {
|
|
35
|
+
key: 'workplaceHomepage',
|
|
36
|
+
label: 'Workplace Homepage',
|
|
37
|
+
placeholder: 'https://company.example.com',
|
|
38
|
+
predicate: _solidUi.ns.foaf('workplaceHomepage')
|
|
39
|
+
}, {
|
|
40
|
+
key: 'schoolHomepage',
|
|
41
|
+
label: 'School Homepage',
|
|
42
|
+
placeholder: 'https://school.example.edu',
|
|
43
|
+
predicate: _solidUi.ns.foaf('schoolHomepage')
|
|
44
|
+
}];
|
|
45
|
+
function readProfileLinkValues(store, subject) {
|
|
46
|
+
const doc = subject.doc();
|
|
47
|
+
return profileLinkFields.reduce((result, field) => {
|
|
48
|
+
const values = store.statementsMatching(subject, field.predicate, undefined, doc).map(statement => statement.object?.value || '').filter(Boolean);
|
|
49
|
+
result[field.key] = values.join('\n');
|
|
50
|
+
return result;
|
|
51
|
+
}, {
|
|
52
|
+
homepage: '',
|
|
53
|
+
weblog: '',
|
|
54
|
+
workplaceHomepage: '',
|
|
55
|
+
schoolHomepage: ''
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function normalizeUrlList(value, fieldLabel) {
|
|
59
|
+
const unique = new Set();
|
|
60
|
+
const lines = value.split('\n').map(entry => entry.trim()).filter(Boolean);
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
let parsed;
|
|
63
|
+
try {
|
|
64
|
+
parsed = new URL(line);
|
|
65
|
+
} catch {
|
|
66
|
+
throw new Error(`${fieldLabel} must contain valid absolute URLs.`);
|
|
67
|
+
}
|
|
68
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
69
|
+
throw new Error(`${fieldLabel} only supports http and https URLs.`);
|
|
70
|
+
}
|
|
71
|
+
unique.add(parsed.toString());
|
|
72
|
+
}
|
|
73
|
+
return [...unique];
|
|
74
|
+
}
|
|
75
|
+
async function saveProfileLinkValues(store, subject, values) {
|
|
76
|
+
const updater = store.updater;
|
|
77
|
+
if (!updater || typeof updater.update !== 'function') {
|
|
78
|
+
throw new Error('This profile cannot be edited with the current store.');
|
|
79
|
+
}
|
|
80
|
+
const doc = subject.doc();
|
|
81
|
+
const deletions = [];
|
|
82
|
+
const insertions = [];
|
|
83
|
+
for (const field of profileLinkFields) {
|
|
84
|
+
const existingStatements = store.statementsMatching(subject, field.predicate, undefined, doc);
|
|
85
|
+
deletions.push(...existingStatements);
|
|
86
|
+
const nextValues = normalizeUrlList(values[field.key], field.label);
|
|
87
|
+
for (const nextValue of nextValues) {
|
|
88
|
+
insertions.push((0, _rdflib.st)(subject, field.predicate, (0, _rdflib.sym)(nextValue), doc));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
await new Promise((resolve, reject) => {
|
|
92
|
+
updater.update(deletions, insertions, (_uri, ok, errorBody) => {
|
|
93
|
+
if (!ok) {
|
|
94
|
+
reject(new Error(errorBody || 'Unable to save profile links.'));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (typeof store.remove === 'function' && deletions.length > 0) {
|
|
98
|
+
;
|
|
99
|
+
store.remove(deletions);
|
|
100
|
+
}
|
|
101
|
+
insertions.forEach(statement => {
|
|
102
|
+
store.add(statement.subject, statement.predicate, statement.object, statement.why);
|
|
103
|
+
});
|
|
104
|
+
resolve();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function appendProfileLinks(container, dom, store, subject) {
|
|
109
|
+
const webLinksSection = dom.createElement('section');
|
|
110
|
+
webLinksSection.className = 'social-profile-links';
|
|
111
|
+
container.appendChild(webLinksSection);
|
|
112
|
+
for (const field of profileLinkFields) {
|
|
113
|
+
const statements = store.statementsMatching(subject, field.predicate);
|
|
114
|
+
if (statements.length === 0) continue;
|
|
115
|
+
const uris = statements.map(statement => statement.object?.value || '').filter(Boolean).sort();
|
|
116
|
+
let previousUri = '';
|
|
117
|
+
for (const uri of uris) {
|
|
118
|
+
if (uri === previousUri) continue;
|
|
119
|
+
previousUri = uri;
|
|
120
|
+
let label = field.label;
|
|
121
|
+
if (uris.length > 1) {
|
|
122
|
+
const schemeIndex = uri.indexOf('//');
|
|
123
|
+
if (schemeIndex > 0) {
|
|
124
|
+
let end = uri.indexOf('/', schemeIndex + 2);
|
|
125
|
+
const dottedEnd = uri.lastIndexOf('.', end);
|
|
126
|
+
if (dottedEnd > 0) end = dottedEnd;
|
|
127
|
+
const hostLabel = uri.slice(schemeIndex + 2, end);
|
|
128
|
+
if (hostLabel) {
|
|
129
|
+
label = `${hostLabel} ${label}`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const textNode = dom.createTextNode(label);
|
|
134
|
+
const anchor = dom.createElement('a');
|
|
135
|
+
anchor.appendChild(textNode);
|
|
136
|
+
anchor.setAttribute('href', uri);
|
|
137
|
+
const item = dom.createElement('div');
|
|
138
|
+
item.className = 'social-pane__link-button';
|
|
139
|
+
item.appendChild(anchor);
|
|
140
|
+
webLinksSection.appendChild(item);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function createEditProfileDetailsButton(options) {
|
|
145
|
+
const {
|
|
146
|
+
dom,
|
|
147
|
+
store,
|
|
148
|
+
subject,
|
|
149
|
+
header,
|
|
150
|
+
onSaved
|
|
151
|
+
} = options;
|
|
152
|
+
const button = dom.createElement('button');
|
|
153
|
+
button.type = 'button';
|
|
154
|
+
button.className = 'social-pane__edit-button';
|
|
155
|
+
const icon = dom.createElement('span');
|
|
156
|
+
icon.className = 'social-pane__edit-button-icon';
|
|
157
|
+
icon.innerHTML = _icons.editIcon;
|
|
158
|
+
button.appendChild(icon);
|
|
159
|
+
const label = dom.createElement('span');
|
|
160
|
+
label.className = 'social-pane__edit-button-label';
|
|
161
|
+
label.textContent = 'Edit';
|
|
162
|
+
button.appendChild(label);
|
|
163
|
+
button.setAttribute('aria-label', 'Edit profile links');
|
|
164
|
+
header.style.position = 'relative';
|
|
165
|
+
const openDialog = () => {
|
|
166
|
+
const initialValues = readProfileLinkValues(store, subject);
|
|
167
|
+
const overlay = dom.createElement('div');
|
|
168
|
+
overlay.classList.add('social-pane__dialog-backdrop', 'flex-center');
|
|
169
|
+
const dialog = dom.createElement('div');
|
|
170
|
+
dialog.classList.add('social-pane__dialog');
|
|
171
|
+
dialog.setAttribute('role', 'dialog');
|
|
172
|
+
dialog.setAttribute('aria-modal', 'true');
|
|
173
|
+
dialog.setAttribute('aria-label', 'Edit profile links');
|
|
174
|
+
overlay.appendChild(dialog);
|
|
175
|
+
const dialogHeader = dom.createElement('div');
|
|
176
|
+
dialogHeader.classList.add('social-pane__dialog-header');
|
|
177
|
+
dialog.appendChild(dialogHeader);
|
|
178
|
+
const title = dom.createElement('h2');
|
|
179
|
+
title.className = 'social-pane__dialog-title';
|
|
180
|
+
title.textContent = 'Edit profile links';
|
|
181
|
+
dialogHeader.appendChild(title);
|
|
182
|
+
const closeIconButton = dom.createElement('button');
|
|
183
|
+
closeIconButton.type = 'button';
|
|
184
|
+
closeIconButton.className = 'social-pane__dialog-close';
|
|
185
|
+
closeIconButton.setAttribute('aria-label', 'Close dialog');
|
|
186
|
+
closeIconButton.innerHTML = _icons.closeIcon;
|
|
187
|
+
dialogHeader.appendChild(closeIconButton);
|
|
188
|
+
const form = dom.createElement('form');
|
|
189
|
+
form.classList.add('social-pane__dialog-form', 'flex-column');
|
|
190
|
+
dialog.appendChild(form);
|
|
191
|
+
const errorMessage = dom.createElement('p');
|
|
192
|
+
errorMessage.className = 'social-pane__dialog-error';
|
|
193
|
+
const fields = new Map();
|
|
194
|
+
for (const field of profileLinkFields) {
|
|
195
|
+
const fieldWrapper = dom.createElement('label');
|
|
196
|
+
fieldWrapper.classList.add('social-pane__dialog-field', 'flex-column');
|
|
197
|
+
const fieldLabel = dom.createElement('span');
|
|
198
|
+
fieldLabel.className = 'social-pane__dialog-label';
|
|
199
|
+
fieldLabel.textContent = field.label;
|
|
200
|
+
fieldWrapper.appendChild(fieldLabel);
|
|
201
|
+
const input = dom.createElement('input');
|
|
202
|
+
input.classList.add('social-pane__dialog-input', 'input');
|
|
203
|
+
input.type = 'url';
|
|
204
|
+
input.placeholder = field.placeholder;
|
|
205
|
+
input.value = initialValues[field.key].split('\n')[0] || '';
|
|
206
|
+
fieldWrapper.appendChild(input);
|
|
207
|
+
fields.set(field.key, input);
|
|
208
|
+
form.appendChild(fieldWrapper);
|
|
209
|
+
}
|
|
210
|
+
form.appendChild(errorMessage);
|
|
211
|
+
const actions = dom.createElement('div');
|
|
212
|
+
actions.className = 'social-pane__dialog-actions';
|
|
213
|
+
form.appendChild(actions);
|
|
214
|
+
const closeButton = dom.createElement('button');
|
|
215
|
+
closeButton.type = 'button';
|
|
216
|
+
closeButton.className = 'social-pane__dialog-button btn-light';
|
|
217
|
+
closeButton.textContent = 'Close';
|
|
218
|
+
actions.appendChild(closeButton);
|
|
219
|
+
const saveButton = dom.createElement('button');
|
|
220
|
+
saveButton.type = 'submit';
|
|
221
|
+
saveButton.className = 'social-pane__dialog-button btn-primary';
|
|
222
|
+
saveButton.textContent = 'Save Changes';
|
|
223
|
+
actions.appendChild(saveButton);
|
|
224
|
+
const closeDialog = () => {
|
|
225
|
+
overlay.remove();
|
|
226
|
+
};
|
|
227
|
+
overlay.addEventListener('click', event => {
|
|
228
|
+
if (event.target === overlay) closeDialog();
|
|
229
|
+
});
|
|
230
|
+
closeIconButton.addEventListener('click', closeDialog);
|
|
231
|
+
closeButton.addEventListener('click', closeDialog);
|
|
232
|
+
overlay.addEventListener('keydown', event => {
|
|
233
|
+
if (event.key === 'Escape') closeDialog();
|
|
234
|
+
});
|
|
235
|
+
form.addEventListener('submit', async event => {
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
errorMessage.textContent = '';
|
|
238
|
+
saveButton.disabled = true;
|
|
239
|
+
closeButton.disabled = true;
|
|
240
|
+
closeIconButton.disabled = true;
|
|
241
|
+
const nextValues = profileLinkFields.reduce((result, field) => {
|
|
242
|
+
result[field.key] = fields.get(field.key)?.value || '';
|
|
243
|
+
return result;
|
|
244
|
+
}, {
|
|
245
|
+
homepage: '',
|
|
246
|
+
weblog: '',
|
|
247
|
+
workplaceHomepage: '',
|
|
248
|
+
schoolHomepage: ''
|
|
249
|
+
});
|
|
250
|
+
try {
|
|
251
|
+
await saveProfileLinkValues(store, subject, nextValues);
|
|
252
|
+
closeDialog();
|
|
253
|
+
onSaved();
|
|
254
|
+
} catch (error) {
|
|
255
|
+
errorMessage.textContent = error instanceof Error ? error.message : 'Unable to save profile links.';
|
|
256
|
+
} finally {
|
|
257
|
+
saveButton.disabled = false;
|
|
258
|
+
closeButton.disabled = false;
|
|
259
|
+
closeIconButton.disabled = false;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
dom.body.appendChild(overlay);
|
|
263
|
+
fields.get('homepage')?.focus();
|
|
264
|
+
};
|
|
265
|
+
button.addEventListener('click', openDialog);
|
|
266
|
+
return button;
|
|
267
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/social/icons.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,kBAAkB,QAa9B,CAAA;AACD,eAAO,MAAM,QAAQ,QAWpB,CAAA;AACD,eAAO,MAAM,YAAY,QAYxB,CAAA;AACD,eAAO,MAAM,SAAS,QAWrB,CAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.personInCircleIcon = exports.locationIcon = exports.editIcon = exports.closeIcon = void 0;
|
|
7
|
+
/* Simpliest solution for now since we are only using it for the symposium
|
|
8
|
+
and then we will use icons from solid-assets */
|
|
9
|
+
const html = String.raw;
|
|
10
|
+
const personInCircleIcon = exports.personInCircleIcon = html`
|
|
11
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
12
|
+
width="64"
|
|
13
|
+
height="64"
|
|
14
|
+
viewBox="0 0 64 64"
|
|
15
|
+
fill="none"
|
|
16
|
+
aria-hidden="true"
|
|
17
|
+
focusable="false"
|
|
18
|
+
>
|
|
19
|
+
<path d="M32.0007 58.6666C46.7282 58.6666 58.6673 46.7275 58.6673 31.9999C58.6673 17.2723 46.7282 5.33325 32.0007 5.33325C17.2731 5.33325 5.33398 17.2723 5.33398 31.9999C5.33398 46.7275 17.2731 58.6666 32.0007 58.6666Z" stroke="#CBD5E1" stroke-width="5.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
|
20
|
+
<path d="M32 34.6667C36.4183 34.6667 40 31.085 40 26.6667C40 22.2485 36.4183 18.6667 32 18.6667C27.5817 18.6667 24 22.2485 24 26.6667C24 31.085 27.5817 34.6667 32 34.6667Z" stroke="#CBD5E1" stroke-width="5.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
|
21
|
+
<path d="M18.666 55.0986V50.6666C18.666 49.2521 19.2279 47.8955 20.2281 46.8954C21.2283 45.8952 22.5849 45.3333 23.9993 45.3333H39.9993C41.4138 45.3333 42.7704 45.8952 43.7706 46.8954C44.7708 47.8955 45.3327 49.2521 45.3327 50.6666V55.0986" stroke="#CBD5E1" stroke-width="5.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
|
22
|
+
</svg>
|
|
23
|
+
`;
|
|
24
|
+
const editIcon = exports.editIcon = html`
|
|
25
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
26
|
+
width="20"
|
|
27
|
+
height="20"
|
|
28
|
+
viewBox="0 0 20 20"
|
|
29
|
+
fill="none"
|
|
30
|
+
aria-hidden="true"
|
|
31
|
+
focusable="false"
|
|
32
|
+
>
|
|
33
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.3063 3.34814C14.9271 3.34832 15.5236 3.59563 15.9625 4.03467C16.4012 4.47362 16.648 5.06935 16.6481 5.68994C16.648 6.31072 16.4004 6.90719 15.9615 7.34619L15.9606 7.34521L7.95373 15.355L7.95275 15.356C7.73845 15.5696 7.47464 15.7278 7.18517 15.8159H7.1842L4.57287 16.6079H4.57092C4.40678 16.6572 4.23224 16.6614 4.06603 16.6196C3.89974 16.5778 3.74793 16.4918 3.62658 16.3706C3.50526 16.2494 3.41865 16.0974 3.37658 15.9312C3.33472 15.7651 3.3383 15.5903 3.38732 15.4263L3.3883 15.4243L4.18127 12.813V12.811C4.27013 12.5215 4.42882 12.2574 4.64318 12.0435L12.651 4.03467V4.03369C13.09 3.59513 13.6857 3.34816 14.3063 3.34814ZM5.56213 12.9634C5.49841 13.0269 5.4509 13.1059 5.42443 13.1919L5.42345 13.1909L4.82189 15.1733L6.80627 14.5718C6.89221 14.5456 6.97114 14.4985 7.03478 14.4351L13.274 8.19482L11.8014 6.72217L5.56213 12.9634ZM14.3063 4.64893C14.0303 4.64894 13.7652 4.75864 13.5699 4.95361L12.7213 5.80225L14.194 7.2749L15.0426 6.42627L15.1119 6.3501C15.2635 6.16488 15.3473 5.93141 15.3473 5.68994C15.3472 5.41394 15.2377 5.14881 15.0426 4.95361C14.8474 4.75846 14.5823 4.64906 14.3063 4.64893Z" fill="#1E2939"/>
|
|
34
|
+
</svg>
|
|
35
|
+
`;
|
|
36
|
+
const locationIcon = exports.locationIcon = html`
|
|
37
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
38
|
+
width="16"
|
|
39
|
+
height="16"
|
|
40
|
+
viewBox="0 0 16 16"
|
|
41
|
+
fill="none"
|
|
42
|
+
aria-hidden="true"
|
|
43
|
+
focusable="false"
|
|
44
|
+
>
|
|
45
|
+
<path d="M13.3327 6.66659C13.3327 9.99525 9.64002 13.4619 8.40002 14.5326C8.2845 14.6194 8.14388 14.6664 7.99935 14.6664C7.85482 14.6664 7.7142 14.6194 7.59868 14.5326C6.35868 13.4619 2.66602 9.99525 2.66602 6.66659C2.66602 5.2521 3.22792 3.89554 4.22811 2.89535C5.22831 1.89516 6.58486 1.33325 7.99935 1.33325C9.41384 1.33325 10.7704 1.89516 11.7706 2.89535C12.7708 3.89554 13.3327 5.2521 13.3327 6.66659Z" stroke="#4A5565" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
|
46
|
+
<path d="M8 8.66675C9.10457 8.66675 10 7.77132 10 6.66675C10 5.56218 9.10457 4.66675 8 4.66675C6.89543 4.66675 6 5.56218 6 6.66675C6 7.77132 6.89543 8.66675 8 8.66675Z" stroke="#4A5565" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
|
47
|
+
</svg>
|
|
48
|
+
`;
|
|
49
|
+
const closeIcon = exports.closeIcon = html`
|
|
50
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
51
|
+
width="12"
|
|
52
|
+
height="12"
|
|
53
|
+
viewBox="0 0 12 12"
|
|
54
|
+
fill="none"
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
focusable="false"
|
|
57
|
+
>
|
|
58
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.5301 0.244005C10.8555 -0.0813835 11.3834 -0.0812864 11.7088 0.244005C12.0338 0.569352 12.0338 1.09639 11.7088 1.42174L7.15416 5.97545L11.7088 10.5301C12.0341 10.8556 12.0342 11.3835 11.7088 11.7088C11.3835 12.0342 10.8556 12.0341 10.5301 11.7088L5.97545 7.15416L1.42174 11.7088C1.09639 12.0338 0.569351 12.0338 0.244004 11.7088C-0.0812866 11.3834 -0.0813828 10.8555 0.244004 10.5301L4.79772 5.97545L0.244004 1.42174C-0.0812866 1.09629 -0.0813828 0.569393 0.244004 0.244005C0.569393 -0.0813835 1.09629 -0.0812864 1.42174 0.244005L5.97545 4.79772L10.5301 0.244005Z" fill="#4A5565"/>
|
|
59
|
+
</svg>
|
|
60
|
+
`;
|