mirror of
https://github.com/cryptpad/cryptpad.git
synced 2026-09-14 11:05:41 +05:00
Merge b364b4684a into 04df22a4f8
This commit is contained in:
commit
352e84f300
@ -157,6 +157,16 @@ define(req, function(AppConfig, Default, Language) {
|
||||
}
|
||||
};
|
||||
|
||||
// XXX
|
||||
Messages.form_guestAuthorTitle = "Save your author link before sharing";
|
||||
Messages.form_guestEditLinkDefinition = "This form's author link is the private link to modify questions and read responses.";
|
||||
Messages.form_guestAuthorBody = "This author link is currently not stored anywhere since you are not logged in. To avoid loosing access in future please save this link now:";
|
||||
Messages.form_guestAuthorBodyStored = "This author link is currently only stored on this device, please save it to avoid loosing access to your form.";
|
||||
Messages.form_guestAuthorCopied = "Author link copied";
|
||||
Messages.form_guestAuthorCopy = "Copy author link";
|
||||
Messages.form_guestAuthorContinuePublic = "Continue to public link";
|
||||
Messages.form_guestPublicTitle = "Copy your public link";
|
||||
Messages.form_guestPublicBody = "Share this link with participants so they can fill out your form.";
|
||||
return Messages;
|
||||
|
||||
});
|
||||
|
||||
@ -119,15 +119,16 @@
|
||||
.cp-creation-checkboxes {
|
||||
min-width: 300px;
|
||||
flex-flow: column;
|
||||
align-items: baseline !important;
|
||||
max-height: 150px;
|
||||
min-height: 120px !important;
|
||||
align-items: stretch !important;
|
||||
max-height: 180px;
|
||||
min-height: 140px !important;
|
||||
justify-content: space-evenly;
|
||||
flex: 1;
|
||||
& > div {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
margin: auto;
|
||||
text-align: left;
|
||||
}
|
||||
@ -258,40 +259,76 @@
|
||||
}
|
||||
|
||||
.cp-creation-teams {
|
||||
display: none !important;
|
||||
.cp-creation-teams-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 2px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
.cp-creation-store-label,
|
||||
.cp-creation-help {
|
||||
flex: none;
|
||||
}
|
||||
.cp-creation-team {
|
||||
.avatar_main(25px);
|
||||
width: 140px;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.cp-creation-team-avatar {
|
||||
.avatar_main(20px);
|
||||
flex: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
cursor: default;
|
||||
font: @colortheme_app-font;
|
||||
margin: 0 1px;
|
||||
|
||||
.tools_unselectable();
|
||||
|
||||
&.cp-selected {
|
||||
background-color: @cp_creation-button-bg;
|
||||
color: @cp_creation-button-fg;
|
||||
justify-content: center;
|
||||
svg, .lucide {
|
||||
margin: 0;
|
||||
}
|
||||
.cp-creation-team-name {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.cp-creation-team-name {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: left;
|
||||
}
|
||||
.cp-dropdown-container {
|
||||
flex: 1 1 0;
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
button.btn {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
line-height: 18px;
|
||||
justify-content: flex-start;
|
||||
overflow: hidden;
|
||||
color: @cp_creation-fg;
|
||||
background: @cp_forms-bg;
|
||||
border: 1px solid @cp_forms-border;
|
||||
text-transform: none;
|
||||
.cp-dropdown-button-title {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 0.5rem;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
.cp-dropdown-content {
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
li[role="menuitem"] {
|
||||
overflow: hidden;
|
||||
> a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
border: 1px solid @cp_creation-button-bg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2814,55 +2814,79 @@ define([
|
||||
}
|
||||
|
||||
// Team pad
|
||||
var team;
|
||||
// FIXME: broken wen cache is enabled
|
||||
var teamExists = privateData.teams && Object.keys(privateData.teams).length;
|
||||
var teamValue;
|
||||
// storeInTeam can be
|
||||
// * a team ID ==> store in the team drive, and the team will be the owner
|
||||
// * -1 ==> store in the user drive, and the user will be the owner
|
||||
// * undefined ==> ask
|
||||
if (teamExists) {
|
||||
var teams = Object.keys(privateData.teams).map(function (id) {
|
||||
var data = privateData.teams[id];
|
||||
var avatar = h('span.cp-creation-team-avatar.cp-avatar');
|
||||
// We assume that teams always have a non-empty name, so we don't need a UID
|
||||
common.displayAvatar($(avatar), data.avatar, data.name);
|
||||
return h('div.cp-creation-team', {
|
||||
'data-id': id,
|
||||
title: data.name,
|
||||
},[
|
||||
avatar,
|
||||
h('span.cp-creation-team-name', data.name)
|
||||
]);
|
||||
});
|
||||
teams.unshift(h('div.cp-creation-team', {
|
||||
'data-id': '-1',
|
||||
title: Messages.settings_cat_drive
|
||||
}, [
|
||||
h('span.cp-creation-team-avatar', Icons.get('drive')),
|
||||
h('span.cp-creation-team-name', Messages.settings_cat_drive)
|
||||
]));
|
||||
team = h('div.cp-creation-teams', [
|
||||
Messages.team_pcsSelectLabel,
|
||||
h('div.cp-creation-teams-grid', teams),
|
||||
createHelper('#', Messages.team_pcsSelectHelp)
|
||||
]);
|
||||
var $team = $(team);
|
||||
$team.find('.cp-creation-team').click(function () {
|
||||
if ($(this).hasClass('cp-selected')) {
|
||||
teamValue = undefined;
|
||||
return void $(this).removeClass('cp-selected');
|
||||
}
|
||||
$team.find('.cp-creation-team').removeClass('cp-selected');
|
||||
$(this).addClass('cp-selected');
|
||||
teamValue = $(this).attr('data-id');
|
||||
});
|
||||
if (privateData.storeInTeam) {
|
||||
$team.find('[data-id="'+privateData.storeInTeam+'"]').addClass('cp-selected');
|
||||
teamValue = privateData.storeInTeam;
|
||||
// * undefined ==> ask (CryptDrive / team / don't store); default CryptDrive
|
||||
var team;
|
||||
var teamValue = typeof(privateData.storeInTeam) === "undefined" ? '-1' : String(privateData.storeInTeam);
|
||||
var getTeamLabel = function (val) {
|
||||
if (val === '-1') { return Messages.settings_cat_drive; }
|
||||
if (!val || val === 'none') { return Messages.autostore_hide; }
|
||||
return privateData.teams?.[val]?.name || val;
|
||||
};
|
||||
var getTeamAvatar = function (val) {
|
||||
if (val === '-1') {
|
||||
return h('span.cp-creation-team-avatar', Icons.get('drive'));
|
||||
}
|
||||
}
|
||||
if (!val || val === 'none') {
|
||||
return h('span.cp-creation-team-avatar', Icons.get('close'));
|
||||
}
|
||||
var data = privateData.teams?.[val];
|
||||
var avatar = h('span.cp-creation-team-avatar.cp-avatar');
|
||||
if (data) {
|
||||
common.displayAvatar($(avatar), data.avatar, data.name);
|
||||
}
|
||||
return avatar;
|
||||
};
|
||||
var teamOptions = [{
|
||||
tag: 'a',
|
||||
attributes: { 'data-value': '-1' },
|
||||
content: [getTeamAvatar('-1'), h('span.cp-creation-team-name', getTeamLabel('-1'))]
|
||||
}];
|
||||
Object.keys(privateData.teams || {}).forEach(function (id) {
|
||||
var data = privateData.teams[id];
|
||||
if (!data) { return; }
|
||||
teamOptions.push({
|
||||
tag: 'a',
|
||||
attributes: { 'data-value': id },
|
||||
content: [getTeamAvatar(id), h('span.cp-creation-team-name', data.name)]
|
||||
});
|
||||
});
|
||||
teamOptions.push({
|
||||
tag: 'a',
|
||||
attributes: { 'data-value': 'none' },
|
||||
content: [getTeamAvatar('none'), h('span.cp-creation-team-name', getTeamLabel('none'))]
|
||||
});
|
||||
var $teamSelect = UIElements.createDropdown({
|
||||
text: getTeamLabel(teamValue),
|
||||
options: teamOptions,
|
||||
isSelect: true,
|
||||
caretDown: true,
|
||||
initialValue: teamValue,
|
||||
buttonTitle: getTeamLabel(teamValue),
|
||||
common: common
|
||||
});
|
||||
var $teamBtn = $teamSelect.find('button').addClass('btn');
|
||||
var setTeamButton = function (val) {
|
||||
var label = getTeamLabel(val);
|
||||
$teamBtn[0]?._tippy?.destroy();
|
||||
$teamBtn.attr('title', label);
|
||||
$teamBtn.find('.cp-dropdown-button-title').empty().append([
|
||||
getTeamAvatar(val),
|
||||
h('span.cp-creation-team-name', label)
|
||||
]);
|
||||
};
|
||||
setTeamButton(teamValue);
|
||||
$teamSelect.onChange.reg(function (text, value) {
|
||||
teamValue = typeof(value) === "undefined" ? 'none' : String(value);
|
||||
setTeamButton(teamValue);
|
||||
});
|
||||
team = h('div.cp-creation-teams', [
|
||||
h('span.cp-creation-store-label', Messages.team_pcsSelectLabel),
|
||||
$teamSelect[0],
|
||||
// createHelper('#', Messages.team_pcsSelectHelp) - commented until the documentation is updated
|
||||
]);
|
||||
|
||||
|
||||
// Owned pads
|
||||
@ -3145,9 +3169,16 @@ define([
|
||||
var templateContent = $template.data('content') || undefined;
|
||||
// Team
|
||||
var team;
|
||||
if (teamValue) {
|
||||
team = privateData.teams[teamValue] || {};
|
||||
team.id = Number(teamValue);
|
||||
if (teamValue === 'none') {
|
||||
team = false;
|
||||
} else if (teamValue === '-1') {
|
||||
team = { id: -1 };
|
||||
} else if (teamValue) {
|
||||
var selectedTeam = privateData.teams[teamValue] || {};
|
||||
team = {
|
||||
id: Number(teamValue),
|
||||
edPublic: selectedTeam.edPublic
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -1151,6 +1151,13 @@ define([
|
||||
data.href = parsed.getUrl({present: parsed.present});
|
||||
|
||||
if (typeof (data.title) !== "string") { return cb('Missing title'); }
|
||||
if (common.initialTeam === false) {
|
||||
if (!data.forceSave) {
|
||||
common.autoStore.onStoreRequest.fire({});
|
||||
return void cb(null, { notStored: true });
|
||||
}
|
||||
delete common.initialTeam;
|
||||
}
|
||||
|
||||
if (common.initialTeam) {
|
||||
// If the value is -1, it means the user drive was selected from the pad creation screen
|
||||
|
||||
@ -1179,6 +1179,11 @@ define([
|
||||
openURL(url);
|
||||
});
|
||||
sframeChan.on('EV_OPEN_URL', openURL);
|
||||
sframeChan.on('EV_OPEN_VIEW_URL', function () {
|
||||
if (!hashes || !hashes.viewHash) { return; }
|
||||
var a = window.open(Utils.Hash.hashToHref(hashes.viewHash, 'form'));
|
||||
if (!a) { _sframeChan.event('EV_POPUP_BLOCKED'); }
|
||||
});
|
||||
|
||||
sframeChan.on('Q_GET_PAD_METADATA', function (data, cb) {
|
||||
if (!data || !data.channel) {
|
||||
@ -1765,7 +1770,9 @@ define([
|
||||
});
|
||||
|
||||
sframeChan.on('Q_SAVE_AS_TEMPLATE', function (data, cb) {
|
||||
data.teamId = Cryptpad.initialTeam;
|
||||
if (Cryptpad.initialTeam) {
|
||||
data.teamId = Cryptpad.initialTeam;
|
||||
}
|
||||
Cryptpad.saveAsTemplate(Cryptget.put, data, cb);
|
||||
});
|
||||
|
||||
@ -2279,12 +2286,8 @@ define([
|
||||
});
|
||||
});
|
||||
});
|
||||
sframeChan.on('EV_OPEN_VIEW_URL', function () {
|
||||
var url = Utils.Hash.hashToHref(hashes.viewHash, 'form');
|
||||
var a = window.open(url);
|
||||
if (!a) {
|
||||
sframeChan.event('EV_POPUP_BLOCKED');
|
||||
}
|
||||
sframeChan.on('EV_FORM_GUEST_SHARE_OPEN', function (data) {
|
||||
initSecureModal('formGuestShare', data || {});
|
||||
});
|
||||
|
||||
Handler.formCommandHandlers(sframeChan, Utils, nThen, Cryptpad);
|
||||
@ -2537,8 +2540,12 @@ define([
|
||||
|
||||
if (cfg.integration) { rtConfig.metadata.selfdestruct = true; }
|
||||
|
||||
if (data.team) {
|
||||
if (data.team === false) {
|
||||
Cryptpad.initialTeam = false;
|
||||
} else if (data.team) {
|
||||
Cryptpad.initialTeam = data.team.id;
|
||||
} else {
|
||||
delete Cryptpad.initialTeam;
|
||||
}
|
||||
if (data.owned && data.team && data.team.edPublic) {
|
||||
rtConfig.metadata.owners = [data.team.edPublic];
|
||||
|
||||
@ -17,7 +17,6 @@ define([
|
||||
'/common/common-hash.js',
|
||||
'/common/common-interface.js',
|
||||
'/common/common-ui-elements.js',
|
||||
'/common/clipboard.js',
|
||||
'/common/inner/common-mediatag.js',
|
||||
'/common/hyperscript.js',
|
||||
'/customize/messages.js',
|
||||
@ -66,7 +65,6 @@ define([
|
||||
Hash,
|
||||
UI,
|
||||
UIElements,
|
||||
Clipboard,
|
||||
MT,
|
||||
h,
|
||||
Messages,
|
||||
@ -4908,14 +4906,35 @@ define([
|
||||
Messages.form_geturl
|
||||
]);
|
||||
var preview = h('div.cp-forms-results-participant', [previewBtn, participantBtn]);
|
||||
var shouldWarnGuestAuthor = function () {
|
||||
if (framework._.sfCommon.isLoggedIn()) { return false; }
|
||||
if (!APP.isEditor) { return false; }
|
||||
return true;
|
||||
};
|
||||
var warnGuestAuthorThen = function (next) {
|
||||
framework._.sfCommon.isPadStored(function (err, stored) {
|
||||
sframeChan.event('EV_FORM_GUEST_SHARE_OPEN', {
|
||||
next: next,
|
||||
stored: Boolean(stored)
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$(previewBtn).click(function () {
|
||||
sframeChan.event('EV_OPEN_VIEW_URL');
|
||||
if (!shouldWarnGuestAuthor()) {
|
||||
return void sframeChan.event('EV_OPEN_VIEW_URL');
|
||||
}
|
||||
warnGuestAuthorThen('preview');
|
||||
});
|
||||
$(participantBtn).click(function () {
|
||||
sframeChan.query('Q_COPY_VIEW_URL', null, function (err, success) {
|
||||
if (success) { return void UI.log(Messages.shareSuccess); }
|
||||
UI.warn(Messages.error);
|
||||
});
|
||||
if (!shouldWarnGuestAuthor()) {
|
||||
sframeChan.query('Q_COPY_VIEW_URL', null, function (err, success) {
|
||||
if (success) { return void UI.log(Messages.shareSuccess); }
|
||||
UI.warn(Messages.error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
warnGuestAuthorThen('public');
|
||||
});
|
||||
|
||||
// Private / public status
|
||||
|
||||
@ -106,4 +106,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.alertify .cp-form-guest-share-modal {
|
||||
h4, h5, h6, p, textarea {
|
||||
color: @cryptpad_text_col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,123 @@ define([
|
||||
};
|
||||
|
||||
var create = {};
|
||||
create['formGuestShare'] = function (data) {
|
||||
data = data || {};
|
||||
require(['/common/clipboard.js'], function (Clipboard) {
|
||||
var priv = metadataMgr.getPrivateData();
|
||||
var hashes = priv.hashes || {};
|
||||
var origin = priv.origin || '';
|
||||
var editUrl = hashes.editHash ?
|
||||
(origin + Hash.hashToHref(hashes.editHash, 'form')) : '';
|
||||
var viewUrl = hashes.viewHash ?
|
||||
(origin + Hash.hashToHref(hashes.viewHash, 'form')) : '';
|
||||
|
||||
var showPublic = function () {
|
||||
if (!viewUrl) { return void hideIframe(); }
|
||||
var frame;
|
||||
var modal = UI.dialog.customModal(h('div.cp-form-guest-share-modal', [
|
||||
h('h4', Messages.form_guestPublicTitle),
|
||||
h('p', Messages.form_guestPublicBody),
|
||||
UI.dialog.selectableArea(viewUrl, {
|
||||
id: 'cp-form-guest-public-link',
|
||||
rows: 2
|
||||
})
|
||||
]), {
|
||||
onClose: function () {
|
||||
if (displayed === frame) { hideIframe(); }
|
||||
},
|
||||
buttons: [{
|
||||
className: 'cancel',
|
||||
name: Messages.cancel,
|
||||
onClick: function () {},
|
||||
keys: [27]
|
||||
}, {
|
||||
className: 'primary',
|
||||
name: Messages.form_geturl,
|
||||
iconClass: 'copy',
|
||||
onClick: function () {
|
||||
Clipboard.copy(viewUrl, function (err) {
|
||||
if (err) { return void UI.warn(Messages.error); }
|
||||
UI.log(Messages.shareSuccess);
|
||||
hideIframe();
|
||||
});
|
||||
return true;
|
||||
},
|
||||
keys: [13]
|
||||
}]
|
||||
});
|
||||
frame = UI.openCustomModal(modal);
|
||||
displayed = frame;
|
||||
};
|
||||
|
||||
var showAuthor = function () {
|
||||
if (!editUrl) {
|
||||
if (data.next === 'public') { return void showPublic(); }
|
||||
if (data.next === 'preview') {
|
||||
sframeChan.event('EV_OPEN_VIEW_URL');
|
||||
}
|
||||
return void hideIframe();
|
||||
}
|
||||
var frame;
|
||||
var stay;
|
||||
var modal = UI.dialog.customModal(h('div.cp-form-guest-share-modal', [
|
||||
h('h4', Messages.form_guestAuthorTitle),
|
||||
h('p', Messages.form_guestEditLinkDefinition),
|
||||
h('p', data.stored ?
|
||||
Messages.form_guestAuthorBodyStored : Messages.form_guestAuthorBody),
|
||||
UI.dialog.selectableArea(editUrl, {
|
||||
id: 'cp-form-guest-author-link',
|
||||
rows: 2
|
||||
})
|
||||
]), {
|
||||
onClose: function () {
|
||||
if (stay || displayed !== frame) { return; }
|
||||
hideIframe();
|
||||
},
|
||||
buttons: [{
|
||||
className: 'cancel',
|
||||
name: Messages.cancel,
|
||||
onClick: function () {},
|
||||
keys: [27]
|
||||
}, {
|
||||
className: 'secondary',
|
||||
name: Messages.form_guestAuthorCopy,
|
||||
iconClass: 'copy',
|
||||
onClick: function () {
|
||||
Clipboard.copy(editUrl, function (err) {
|
||||
if (err) { return void UI.warn(Messages.error); }
|
||||
UI.log(Messages.form_guestAuthorCopied);
|
||||
});
|
||||
return true;
|
||||
},
|
||||
keys: []
|
||||
}, {
|
||||
className: 'primary',
|
||||
name: data.next === 'public' ?
|
||||
Messages.form_guestAuthorContinuePublic : Messages.continue,
|
||||
onClick: function () {
|
||||
if (data.next === 'public') {
|
||||
stay = true;
|
||||
if (frame && frame.closeModal) {
|
||||
frame.closeModal(showPublic);
|
||||
} else {
|
||||
showPublic();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (data.next === 'preview') {
|
||||
sframeChan.event('EV_OPEN_VIEW_URL');
|
||||
}
|
||||
},
|
||||
keys: [13]
|
||||
}]
|
||||
});
|
||||
frame = UI.openCustomModal(modal);
|
||||
displayed = frame;
|
||||
};
|
||||
showAuthor();
|
||||
});
|
||||
};
|
||||
|
||||
// Share modal
|
||||
create['share'] = function (data) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user