solid-panes 4.4.0 → 4.4.1-test.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 +4 -2
- package/dist/RDFXMLPane.css +70 -0
- package/dist/RDFXMLPane.d.ts +13 -0
- package/dist/RDFXMLPane.d.ts.map +1 -0
- package/dist/RDFXMLPane.js +46 -5
- package/dist/dataContentPane.css +271 -0
- package/dist/dataContentPane.d.ts +14 -0
- package/dist/dataContentPane.d.ts.map +1 -0
- package/dist/dataContentPane.js +68 -101
- package/dist/defaultPane.css +97 -0
- package/dist/defaultPane.d.ts +14 -0
- package/dist/defaultPane.d.ts.map +1 -0
- package/dist/defaultPane.js +9 -2
- package/dist/form/formPane.css +120 -0
- package/dist/form/pane.d.ts +4 -0
- package/dist/form/pane.d.ts.map +1 -0
- package/dist/form/pane.js +120 -54
- package/dist/humanReadablePane.css +129 -0
- package/dist/humanReadablePane.d.ts +13 -0
- package/dist/humanReadablePane.d.ts.map +1 -0
- package/dist/humanReadablePane.js +29 -18
- package/dist/icons/signUp.svg +9 -0
- package/dist/imagePane.css +4 -0
- package/dist/imagePane.d.ts +12 -0
- package/dist/imagePane.d.ts.map +1 -0
- package/dist/imagePane.js +19 -21
- package/dist/internal/internalPane.css +14 -0
- package/dist/internal/internalPane.d.ts +1 -0
- package/dist/internal/internalPane.d.ts.map +1 -1
- package/dist/internal/internalPane.js +5 -6
- package/dist/mainPage/header.js +2 -2
- package/dist/mainPage/index.d.ts +2 -1
- package/dist/mainPage/index.d.ts.map +1 -1
- package/dist/mainPage/index.js +23 -0
- package/dist/mainPage/menu.d.ts.map +1 -1
- package/dist/mainPage/menu.js +29 -2
- package/dist/n3Pane.css +49 -0
- package/dist/n3Pane.d.ts +13 -0
- package/dist/n3Pane.d.ts.map +1 -0
- package/dist/n3Pane.js +36 -5
- package/dist/outline/manager.js +20 -1
- package/dist/pad/padPane.css +6 -2
- package/dist/pad/padPane.js +1 -1
- package/dist/registerPanes.js +8 -8
- package/dist/schedule/schedulePane.css +294 -0
- package/dist/schedule/schedulePane.d.ts +23 -0
- package/dist/schedule/schedulePane.d.ts.map +1 -0
- package/dist/schedule/schedulePane.js +161 -61
- package/dist/social/editProfileDetails.d.ts +3 -3
- package/dist/social/editProfileDetails.d.ts.map +1 -1
- package/dist/social/editProfileDetails.js +222 -127
- package/dist/social/icons.d.ts +2 -0
- package/dist/social/icons.d.ts.map +1 -1
- package/dist/social/icons.js +39 -4
- package/dist/social/socialPane.css +838 -178
- package/dist/social/socialPane.d.ts.map +1 -1
- package/dist/social/socialPane.js +136 -43
- package/dist/social/socialSections.d.ts +11 -0
- package/dist/social/socialSections.d.ts.map +1 -1
- package/dist/social/socialSections.js +138 -62
- package/dist/social/spinner.d.ts +3 -0
- package/dist/social/spinner.d.ts.map +1 -0
- package/dist/social/spinner.js +13 -0
- package/dist/social/triage.d.ts +17 -0
- package/dist/social/triage.d.ts.map +1 -0
- package/dist/social/triage.js +79 -0
- package/dist/solid-panes.js +25772 -9576
- package/dist/solid-panes.js.map +1 -1
- package/dist/solid-panes.min.js +2583 -927
- package/dist/solid-panes.min.js.map +1 -1
- package/dist/{style → styles}/tabbedtab.css +0 -157
- package/dist/styles/utilities.css +5 -0
- package/dist/versionInfo.js +13 -13
- package/package.json +27 -26
- package/dist/icons/signup.png +0 -0
|
@@ -7,8 +7,11 @@ exports.appendProfileLinks = appendProfileLinks;
|
|
|
7
7
|
exports.createEditProfileDetailsButton = createEditProfileDetailsButton;
|
|
8
8
|
exports.profileLinkFields = void 0;
|
|
9
9
|
var _rdflib = require("rdflib");
|
|
10
|
+
var _litHtml = require("lit-html");
|
|
10
11
|
var _solidUi = require("solid-ui");
|
|
12
|
+
require("solid-ui/components/button");
|
|
11
13
|
var _icons = require("./icons");
|
|
14
|
+
var _spinner = require("./spinner");
|
|
12
15
|
/* The following code was generated by AI Model: GPT-5.4
|
|
13
16
|
Prompt: can you create me a form to enter this data [
|
|
14
17
|
ns.foaf('homepage'),
|
|
@@ -42,22 +45,25 @@ const profileLinkFields = exports.profileLinkFields = [{
|
|
|
42
45
|
placeholder: 'https://school.example.edu',
|
|
43
46
|
predicate: _solidUi.ns.foaf('schoolHomepage')
|
|
44
47
|
}];
|
|
48
|
+
function createEmptyProfileLinkValues() {
|
|
49
|
+
return {
|
|
50
|
+
homepage: [''],
|
|
51
|
+
weblog: [''],
|
|
52
|
+
workplaceHomepage: [''],
|
|
53
|
+
schoolHomepage: ['']
|
|
54
|
+
};
|
|
55
|
+
}
|
|
45
56
|
function readProfileLinkValues(store, subject) {
|
|
46
57
|
const doc = subject.doc();
|
|
47
58
|
return profileLinkFields.reduce((result, field) => {
|
|
48
59
|
const values = store.statementsMatching(subject, field.predicate, undefined, doc).map(statement => statement.object?.value || '').filter(Boolean);
|
|
49
|
-
result[field.key] = values.
|
|
60
|
+
result[field.key] = values.length ? values : [''];
|
|
50
61
|
return result;
|
|
51
|
-
},
|
|
52
|
-
homepage: '',
|
|
53
|
-
weblog: '',
|
|
54
|
-
workplaceHomepage: '',
|
|
55
|
-
schoolHomepage: ''
|
|
56
|
-
});
|
|
62
|
+
}, createEmptyProfileLinkValues());
|
|
57
63
|
}
|
|
58
|
-
function normalizeUrlList(
|
|
64
|
+
function normalizeUrlList(values, fieldLabel) {
|
|
59
65
|
const unique = new Set();
|
|
60
|
-
const lines =
|
|
66
|
+
const lines = values.map(entry => entry.trim()).filter(Boolean);
|
|
61
67
|
for (const line of lines) {
|
|
62
68
|
let parsed;
|
|
63
69
|
try {
|
|
@@ -74,96 +80,76 @@ function normalizeUrlList(value, fieldLabel) {
|
|
|
74
80
|
}
|
|
75
81
|
async function saveProfileLinkValues(store, subject, values) {
|
|
76
82
|
const updater = store.updater;
|
|
77
|
-
|
|
83
|
+
const fetcher = store.fetcher;
|
|
84
|
+
if (!updater || typeof updater.serialize !== 'function' || !fetcher || typeof fetcher.webOperation !== 'function') {
|
|
78
85
|
throw new Error('This profile cannot be edited with the current store.');
|
|
79
86
|
}
|
|
80
87
|
const doc = subject.doc();
|
|
81
|
-
const deletions = [];
|
|
82
88
|
const insertions = [];
|
|
89
|
+
const existingStatements = [];
|
|
83
90
|
for (const field of profileLinkFields) {
|
|
84
|
-
|
|
85
|
-
deletions.push(...existingStatements);
|
|
91
|
+
existingStatements.push(...store.statementsMatching(subject, field.predicate, undefined, doc));
|
|
86
92
|
const nextValues = normalizeUrlList(values[field.key], field.label);
|
|
87
93
|
for (const nextValue of nextValues) {
|
|
88
94
|
insertions.push((0, _rdflib.st)(subject, field.predicate, (0, _rdflib.sym)(nextValue), doc));
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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();
|
|
97
|
+
const retainedStatements = store.statementsMatching(undefined, undefined, undefined, doc).filter(statement => {
|
|
98
|
+
return !profileLinkFields.some(field => {
|
|
99
|
+
return statement.subject.equals(subject) && statement.predicate.equals(field.predicate);
|
|
105
100
|
});
|
|
106
101
|
});
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
}
|
|
102
|
+
const nextStatements = retainedStatements.concat(insertions);
|
|
103
|
+
const contentType = 'text/turtle';
|
|
104
|
+
const body = updater.serialize(doc.value, nextStatements, contentType);
|
|
105
|
+
const response = await fetcher.webOperation('PUT', doc.value, {
|
|
106
|
+
noMeta: true,
|
|
107
|
+
contentType,
|
|
108
|
+
body
|
|
109
|
+
});
|
|
110
|
+
if (!response || response.ok !== true) {
|
|
111
|
+
const status = response?.status || 'unknown';
|
|
112
|
+
throw new Error(`Unable to save profile links. Web error: ${status}`);
|
|
142
113
|
}
|
|
114
|
+
existingStatements.forEach(statement => {
|
|
115
|
+
store.removeStatement(statement);
|
|
116
|
+
});
|
|
117
|
+
for (const statement of insertions) {
|
|
118
|
+
store.add(statement.subject, statement.predicate, statement.object, statement.why);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function appendProfileLinks(_container, _dom, _store, _subject) {
|
|
122
|
+
// Hidden for now because social-pane website links are not part of the new design.
|
|
123
|
+
// Revisit later if we decide to show profile links in this header again.
|
|
143
124
|
}
|
|
144
125
|
function createEditProfileDetailsButton(options) {
|
|
145
126
|
const {
|
|
146
127
|
dom,
|
|
147
128
|
store,
|
|
148
129
|
subject,
|
|
149
|
-
header,
|
|
150
130
|
onSaved
|
|
151
131
|
} = options;
|
|
152
|
-
const button = dom.createElement('button');
|
|
132
|
+
const button = dom.createElement('solid-ui-button');
|
|
153
133
|
button.type = 'button';
|
|
154
|
-
button.className = 'social-pane__edit-button';
|
|
134
|
+
button.className = 'social-pane__edit-button profile__action-button profile__heading-action-button profile-action-text flex-center profile-section-collapsible__edit-button';
|
|
135
|
+
button.variant = 'secondary';
|
|
136
|
+
button.size = 'sm';
|
|
137
|
+
const label = dom.createElement('span');
|
|
138
|
+
label.className = 'profile-section-collapsible__edit-label social-pane__edit-button-label';
|
|
139
|
+
label.innerHTML = `${_icons.editIcon} Edit`;
|
|
140
|
+
button.appendChild(label);
|
|
155
141
|
const icon = dom.createElement('span');
|
|
156
|
-
icon.className = 'social-pane__edit-button-icon';
|
|
142
|
+
icon.className = 'profile-section-collapsible__edit-icon social-pane__edit-button-icon';
|
|
143
|
+
icon.setAttribute('aria-hidden', 'true');
|
|
157
144
|
icon.innerHTML = _icons.editIcon;
|
|
158
145
|
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
146
|
button.setAttribute('aria-label', 'Edit profile links');
|
|
164
|
-
header.style.position = 'relative';
|
|
165
147
|
const openDialog = () => {
|
|
166
148
|
const initialValues = readProfileLinkValues(store, subject);
|
|
149
|
+
const formState = profileLinkFields.reduce((result, field) => {
|
|
150
|
+
result[field.key] = [...initialValues[field.key]];
|
|
151
|
+
return result;
|
|
152
|
+
}, createEmptyProfileLinkValues());
|
|
167
153
|
const overlay = dom.createElement('div');
|
|
168
154
|
overlay.classList.add('social-pane__dialog-backdrop', 'flex-center');
|
|
169
155
|
const dialog = dom.createElement('div');
|
|
@@ -179,88 +165,197 @@ function createEditProfileDetailsButton(options) {
|
|
|
179
165
|
title.className = 'social-pane__dialog-title';
|
|
180
166
|
title.textContent = 'Edit profile links';
|
|
181
167
|
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
168
|
const form = dom.createElement('form');
|
|
189
169
|
form.classList.add('social-pane__dialog-form', 'flex-column');
|
|
190
170
|
dialog.appendChild(form);
|
|
171
|
+
const savingOverlay = dom.createElement('div');
|
|
172
|
+
savingOverlay.className = 'social-pane__dialog-saving-overlay';
|
|
173
|
+
savingOverlay.hidden = true;
|
|
174
|
+
dialog.appendChild(savingOverlay);
|
|
175
|
+
const fieldsContainer = dom.createElement('div');
|
|
176
|
+
fieldsContainer.className = 'social-pane__dialog-fields';
|
|
177
|
+
form.appendChild(fieldsContainer);
|
|
191
178
|
const errorMessage = dom.createElement('p');
|
|
192
179
|
errorMessage.className = 'social-pane__dialog-error';
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
180
|
+
const focusRow = (fieldKey, rowIndex) => {
|
|
181
|
+
const nextField = fieldsContainer.querySelector(`input[data-profile-link-key="${fieldKey}"][data-profile-link-index="${String(rowIndex)}"]`);
|
|
182
|
+
nextField?.focus();
|
|
183
|
+
};
|
|
184
|
+
const renderFields = focusTarget => {
|
|
185
|
+
fieldsContainer.replaceChildren();
|
|
186
|
+
for (const field of profileLinkFields) {
|
|
187
|
+
const fieldWrapper = dom.createElement('section');
|
|
188
|
+
fieldWrapper.classList.add('social-pane__dialog-field', 'flex-column');
|
|
189
|
+
const fieldHeader = dom.createElement('div');
|
|
190
|
+
fieldHeader.className = 'social-pane__dialog-field-header';
|
|
191
|
+
fieldWrapper.appendChild(fieldHeader);
|
|
192
|
+
const fieldLabel = dom.createElement('h3');
|
|
193
|
+
fieldLabel.className = 'social-pane__dialog-label';
|
|
194
|
+
fieldLabel.textContent = field.label;
|
|
195
|
+
fieldHeader.appendChild(fieldLabel);
|
|
196
|
+
const addButton = dom.createElement('solid-ui-button');
|
|
197
|
+
addButton.type = 'button';
|
|
198
|
+
addButton.className = 'social-pane__dialog-row-button--add';
|
|
199
|
+
addButton.setAttribute('aria-label', `Add another ${field.label.toLowerCase()}`);
|
|
200
|
+
addButton.variant = 'secondary';
|
|
201
|
+
addButton.size = 'sm';
|
|
202
|
+
const addButtonContent = dom.createElement('span');
|
|
203
|
+
addButtonContent.className = 'social-pane__add-more-content';
|
|
204
|
+
const addButtonInline = dom.createElement('span');
|
|
205
|
+
addButtonInline.className = 'social-pane__add-more-inline';
|
|
206
|
+
const addButtonIcon = dom.createElement('span');
|
|
207
|
+
addButtonIcon.className = 'social-pane__add-more-icon';
|
|
208
|
+
addButtonIcon.setAttribute('aria-hidden', 'true');
|
|
209
|
+
addButtonIcon.innerHTML = _icons.plusIcon;
|
|
210
|
+
const addButtonText = dom.createElement('span');
|
|
211
|
+
addButtonText.textContent = 'Add More';
|
|
212
|
+
addButtonInline.appendChild(addButtonIcon);
|
|
213
|
+
addButtonInline.appendChild(addButtonText);
|
|
214
|
+
addButtonContent.appendChild(addButtonInline);
|
|
215
|
+
addButton.appendChild(addButtonContent);
|
|
216
|
+
addButton.addEventListener('click', () => {
|
|
217
|
+
formState[field.key].push('');
|
|
218
|
+
renderFields({
|
|
219
|
+
fieldKey: field.key,
|
|
220
|
+
rowIndex: formState[field.key].length - 1
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
fieldHeader.appendChild(addButton);
|
|
224
|
+
const rows = dom.createElement('div');
|
|
225
|
+
rows.className = 'social-pane__dialog-row-list';
|
|
226
|
+
fieldWrapper.appendChild(rows);
|
|
227
|
+
const values = formState[field.key].length ? formState[field.key] : [''];
|
|
228
|
+
values.forEach((value, index) => {
|
|
229
|
+
const row = dom.createElement('div');
|
|
230
|
+
row.className = 'social-pane__dialog-row';
|
|
231
|
+
const input = dom.createElement('input');
|
|
232
|
+
input.classList.add('social-pane__dialog-input', 'input');
|
|
233
|
+
input.type = 'url';
|
|
234
|
+
input.placeholder = field.placeholder;
|
|
235
|
+
input.value = value;
|
|
236
|
+
input.setAttribute('data-profile-link-key', field.key);
|
|
237
|
+
input.setAttribute('data-profile-link-index', String(index));
|
|
238
|
+
input.addEventListener('input', () => {
|
|
239
|
+
formState[field.key][index] = input.value;
|
|
240
|
+
});
|
|
241
|
+
row.appendChild(input);
|
|
242
|
+
const removeButton = dom.createElement('solid-ui-button');
|
|
243
|
+
removeButton.type = 'button';
|
|
244
|
+
removeButton.className = 'social-pane__dialog-row-button--remove';
|
|
245
|
+
removeButton.setAttribute('aria-label', `Remove ${field.label.toLowerCase()} ${index + 1}`);
|
|
246
|
+
removeButton.setAttribute('title', 'Remove');
|
|
247
|
+
removeButton.variant = 'icon';
|
|
248
|
+
removeButton.size = 'md';
|
|
249
|
+
const removeButtonIcon = dom.createElement('span');
|
|
250
|
+
removeButtonIcon.className = 'social-pane__dialog-row-button-icon social-pane__dialog-row-button-icon--remove';
|
|
251
|
+
removeButtonIcon.setAttribute('slot', 'icon');
|
|
252
|
+
removeButtonIcon.setAttribute('aria-hidden', 'true');
|
|
253
|
+
removeButtonIcon.innerHTML = _icons.trashIcon;
|
|
254
|
+
removeButton.appendChild(removeButtonIcon);
|
|
255
|
+
removeButton.addEventListener('click', () => {
|
|
256
|
+
if (formState[field.key].length === 1) {
|
|
257
|
+
formState[field.key][0] = '';
|
|
258
|
+
} else {
|
|
259
|
+
formState[field.key].splice(index, 1);
|
|
260
|
+
}
|
|
261
|
+
renderFields();
|
|
262
|
+
});
|
|
263
|
+
row.appendChild(removeButton);
|
|
264
|
+
rows.appendChild(row);
|
|
265
|
+
});
|
|
266
|
+
fieldsContainer.appendChild(fieldWrapper);
|
|
267
|
+
}
|
|
268
|
+
if (focusTarget) {
|
|
269
|
+
focusRow(focusTarget.fieldKey, focusTarget.rowIndex);
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
renderFields();
|
|
210
273
|
form.appendChild(errorMessage);
|
|
211
274
|
const actions = dom.createElement('div');
|
|
212
275
|
actions.className = 'social-pane__dialog-actions';
|
|
213
276
|
form.appendChild(actions);
|
|
214
|
-
const closeButton = dom.createElement('button');
|
|
277
|
+
const closeButton = dom.createElement('solid-ui-button');
|
|
215
278
|
closeButton.type = 'button';
|
|
216
|
-
closeButton.className = 'social-pane__dialog-button
|
|
217
|
-
closeButton.
|
|
279
|
+
closeButton.className = 'social-pane__dialog-button--cancel';
|
|
280
|
+
closeButton.setAttribute('aria-label', 'Close dialog');
|
|
281
|
+
closeButton.label = 'Close';
|
|
282
|
+
closeButton.variant = 'secondary';
|
|
283
|
+
closeButton.size = 'md';
|
|
218
284
|
actions.appendChild(closeButton);
|
|
219
|
-
const saveButton = dom.createElement('button');
|
|
220
|
-
saveButton.type = '
|
|
221
|
-
saveButton.className = 'social-pane__dialog-button
|
|
222
|
-
saveButton.
|
|
285
|
+
const saveButton = dom.createElement('solid-ui-button');
|
|
286
|
+
saveButton.type = 'button';
|
|
287
|
+
saveButton.className = 'social-pane__dialog-button--save';
|
|
288
|
+
saveButton.label = 'Save Changes';
|
|
289
|
+
saveButton.variant = 'primary';
|
|
290
|
+
saveButton.size = 'md';
|
|
223
291
|
actions.appendChild(saveButton);
|
|
224
|
-
|
|
292
|
+
let isSaving = false;
|
|
293
|
+
const setSavingState = nextSaving => {
|
|
294
|
+
isSaving = nextSaving;
|
|
295
|
+
dialog.classList.toggle('modal--saving', nextSaving);
|
|
296
|
+
dialog.setAttribute('aria-busy', String(nextSaving));
|
|
297
|
+
form.toggleAttribute('inert', nextSaving);
|
|
298
|
+
saveButton.disabled = nextSaving;
|
|
299
|
+
saveButton.setAttribute('aria-busy', String(nextSaving));
|
|
300
|
+
closeButton.disabled = nextSaving;
|
|
301
|
+
savingOverlay.hidden = !nextSaving;
|
|
302
|
+
if (nextSaving) {
|
|
303
|
+
const activeElement = dialog.ownerDocument.activeElement;
|
|
304
|
+
if (activeElement && dialog.contains(activeElement)) {
|
|
305
|
+
activeElement.blur();
|
|
306
|
+
}
|
|
307
|
+
(0, _litHtml.render)((0, _litHtml.html)`
|
|
308
|
+
<div class="modal__saving-indicator inline-flex-row justify-center" aria-live="polite" aria-label="Saving changes">
|
|
309
|
+
${(0, _spinner.createSpinner)()}
|
|
310
|
+
</div>
|
|
311
|
+
`, savingOverlay);
|
|
312
|
+
} else {
|
|
313
|
+
(0, _litHtml.render)((0, _litHtml.html)``, savingOverlay);
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
const closeDialog = (force = false) => {
|
|
317
|
+
if (isSaving && !force) return;
|
|
225
318
|
overlay.remove();
|
|
226
319
|
};
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
|
|
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();
|
|
320
|
+
const requestCloseDialog = () => {
|
|
321
|
+
closeDialog();
|
|
322
|
+
};
|
|
323
|
+
const handleSave = async () => {
|
|
237
324
|
errorMessage.textContent = '';
|
|
238
|
-
|
|
239
|
-
closeButton.disabled = true;
|
|
240
|
-
closeIconButton.disabled = true;
|
|
325
|
+
setSavingState(true);
|
|
241
326
|
const nextValues = profileLinkFields.reduce((result, field) => {
|
|
242
|
-
result[field.key] =
|
|
327
|
+
result[field.key] = [...formState[field.key]];
|
|
243
328
|
return result;
|
|
244
|
-
},
|
|
245
|
-
homepage: '',
|
|
246
|
-
weblog: '',
|
|
247
|
-
workplaceHomepage: '',
|
|
248
|
-
schoolHomepage: ''
|
|
249
|
-
});
|
|
329
|
+
}, createEmptyProfileLinkValues());
|
|
250
330
|
try {
|
|
251
331
|
await saveProfileLinkValues(store, subject, nextValues);
|
|
252
|
-
|
|
332
|
+
setSavingState(false);
|
|
333
|
+
closeDialog(true);
|
|
253
334
|
onSaved();
|
|
254
335
|
} catch (error) {
|
|
255
336
|
errorMessage.textContent = error instanceof Error ? error.message : 'Unable to save profile links.';
|
|
256
337
|
} finally {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
338
|
+
if (isSaving) {
|
|
339
|
+
setSavingState(false);
|
|
340
|
+
}
|
|
260
341
|
}
|
|
342
|
+
};
|
|
343
|
+
overlay.addEventListener('click', event => {
|
|
344
|
+
if (event.target === overlay) closeDialog();
|
|
345
|
+
});
|
|
346
|
+
closeButton.addEventListener('click', requestCloseDialog);
|
|
347
|
+
saveButton.addEventListener('click', async event => {
|
|
348
|
+
event.preventDefault();
|
|
349
|
+
await handleSave();
|
|
350
|
+
});
|
|
351
|
+
overlay.addEventListener('keydown', event => {
|
|
352
|
+
if (event.key === 'Escape') closeDialog();
|
|
353
|
+
});
|
|
354
|
+
form.addEventListener('submit', event => {
|
|
355
|
+
event.preventDefault();
|
|
261
356
|
});
|
|
262
357
|
dom.body.appendChild(overlay);
|
|
263
|
-
|
|
358
|
+
focusRow('homepage', 0);
|
|
264
359
|
};
|
|
265
360
|
button.addEventListener('click', openDialog);
|
|
266
361
|
return button;
|
package/dist/social/icons.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export declare const personInCircleIcon: string;
|
|
|
2
2
|
export declare const editIcon: string;
|
|
3
3
|
export declare const locationIcon: string;
|
|
4
4
|
export declare const closeIcon: string;
|
|
5
|
+
export declare const trashIcon: string;
|
|
6
|
+
export declare const plusIcon: string;
|
|
5
7
|
//# sourceMappingURL=icons.d.ts.map
|
|
@@ -1 +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"}
|
|
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;AACD,eAAO,MAAM,SAAS,QAerB,CAAA;AACD,eAAO,MAAM,QAAQ,QAkBpB,CAAA"}
|
package/dist/social/icons.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.personInCircleIcon = exports.locationIcon = exports.editIcon = exports.closeIcon = void 0;
|
|
6
|
+
exports.trashIcon = exports.plusIcon = exports.personInCircleIcon = exports.locationIcon = exports.editIcon = exports.closeIcon = void 0;
|
|
7
7
|
/* Simpliest solution for now since we are only using it for the symposium
|
|
8
8
|
and then we will use icons from solid-assets */
|
|
9
9
|
const html = String.raw;
|
|
@@ -23,9 +23,9 @@ const personInCircleIcon = exports.personInCircleIcon = html`
|
|
|
23
23
|
`;
|
|
24
24
|
const editIcon = exports.editIcon = html`
|
|
25
25
|
<svg xmlns="http://www.w3.org/2000/svg"
|
|
26
|
-
width="
|
|
27
|
-
height="
|
|
28
|
-
viewBox="
|
|
26
|
+
width="14"
|
|
27
|
+
height="14"
|
|
28
|
+
viewBox="3 3 14 14"
|
|
29
29
|
fill="none"
|
|
30
30
|
aria-hidden="true"
|
|
31
31
|
focusable="false"
|
|
@@ -57,4 +57,39 @@ const closeIcon = exports.closeIcon = html`
|
|
|
57
57
|
>
|
|
58
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
59
|
</svg>
|
|
60
|
+
`;
|
|
61
|
+
const trashIcon = exports.trashIcon = html`
|
|
62
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
63
|
+
width="20"
|
|
64
|
+
height="20"
|
|
65
|
+
viewBox="0 0 20 20"
|
|
66
|
+
fill="none"
|
|
67
|
+
aria-hidden="true"
|
|
68
|
+
focusable="false"
|
|
69
|
+
>
|
|
70
|
+
<path d="M8.33301 9.16675V14.1667" stroke="#D1D5DC" stroke-width="1.45833" stroke-linecap="round" stroke-linejoin="round"/>
|
|
71
|
+
<path d="M11.667 9.16675V14.1667" stroke="#D1D5DC" stroke-width="1.45833" stroke-linecap="round" stroke-linejoin="round"/>
|
|
72
|
+
<path d="M15.8337 5V16.6667C15.8337 17.1087 15.6581 17.5326 15.3455 17.8452C15.0329 18.1577 14.609 18.3333 14.167 18.3333H5.83366C5.39163 18.3333 4.96771 18.1577 4.65515 17.8452C4.34259 17.5326 4.16699 17.1087 4.16699 16.6667V5" stroke="#D1D5DC" stroke-width="1.45833" stroke-linecap="round" stroke-linejoin="round"/>
|
|
73
|
+
<path d="M2.5 5H17.5" stroke="#D1D5DC" stroke-width="1.45833" stroke-linecap="round" stroke-linejoin="round"/>
|
|
74
|
+
<path d="M6.66699 5.00008V3.33341C6.66699 2.89139 6.84259 2.46746 7.15515 2.1549C7.46771 1.84234 7.89163 1.66675 8.33366 1.66675H11.667C12.109 1.66675 12.5329 1.84234 12.8455 2.1549C13.1581 2.46746 13.3337 2.89139 13.3337 3.33341V5.00008" stroke="#D1D5DC" stroke-width="1.45833" stroke-linecap="round" stroke-linejoin="round"/>
|
|
75
|
+
</svg>
|
|
76
|
+
`;
|
|
77
|
+
const plusIcon = exports.plusIcon = html`
|
|
78
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
79
|
+
width="12"
|
|
80
|
+
height="12"
|
|
81
|
+
viewBox="0 0 12 12"
|
|
82
|
+
fill="none"
|
|
83
|
+
aria-hidden="true"
|
|
84
|
+
focusable="false"
|
|
85
|
+
>
|
|
86
|
+
<g clip-path="url(#clip0_3001_2564)">
|
|
87
|
+
<path d="M6.06055 0.10083C6.53372 0.101056 6.91793 0.485037 6.91797 0.958252V5.20532H11.165C11.6384 5.20532 12.0225 5.58936 12.0225 6.06274C12.0223 6.536 11.6383 6.92017 11.165 6.92017H6.91797V11.1663C6.91797 11.6395 6.53374 12.0235 6.06055 12.0237C5.58716 12.0237 5.20312 11.6396 5.20312 11.1663V6.92017H0.957031C0.483929 6.91994 0.0997601 6.53586 0.0996094 6.06274C0.0996094 5.5895 0.483837 5.20555 0.957031 5.20532H5.20312V0.958252C5.20316 0.484897 5.58718 0.10083 6.06055 0.10083Z" fill="#7C4DFF"/>
|
|
88
|
+
</g>
|
|
89
|
+
<defs>
|
|
90
|
+
<clipPath id="clip0_3001_2564">
|
|
91
|
+
<rect width="12" height="12" fill="white"/>
|
|
92
|
+
</clipPath>
|
|
93
|
+
</defs>
|
|
94
|
+
</svg>
|
|
60
95
|
`;
|