snappymail/dev/View/Popup/Folder.js
2024-08-20 13:12:14 +02:00

220 lines
7.1 KiB
JavaScript

import { AbstractViewPopup } from 'Knoin/AbstractViews';
import { addObservablesTo, koComputable } from 'External/ko';
import Remote from 'Remote/User/Fetch';
import { FolderUserStore } from 'Stores/User/Folder';
import { getFolderFromCacheList, setFolder, removeFolderFromCacheList } from 'Common/Cache';
import { Notifications } from 'Common/Enums';
import { FolderMetadataKeys } from 'Common/EnumsUser';
import { folderListOptionsBuilder, sortFolders } from 'Common/Folders';
import { initOnStartOrLangChange, i18n, getNotification } from 'Common/Translator';
import { defaultOptionsAfterRender } from 'Common/Utils';
import { FolderACLPopupView } from 'View/Popup/FolderAcl';
import { showScreenPopup } from 'Knoin/Knoin';
import { AbstractCollectionModel } from 'Model/AbstractCollection';
export class FolderACLModel extends AbstractCollectionModel
{
static reviveFromJson(json) {
return super.reviveFromJson(json, rights => FolderACLRightsModel.reviveFromJson(rights));
}
}
import { AbstractModel } from 'Knoin/AbstractModel';
export class FolderACLRightsModel extends AbstractModel {
constructor() {
super();
addObservablesTo(this, {
identifier: '',
mine: false
});
// The "RIGHTS=" capability MUST NOT include any of the rights defined in RFC 2086.
// That way we know it supports RFC 4314
// this.rights = ko.observableArray(/*'alrswipcd'.split('')*/);
this.rights = ko.observableArray(/*'alrswipkxte'.split('')*/);
}
static reviveFromJson(json) {
json.rights = json.rights.split('');
return super.reviveFromJson(json);
}
/*
get mayReadItems() { return this.rights.includes('l') && this.rights.includes('r'); }
get mayAddItems() { return this.rights.includes('i'); }
get mayRemoveItems() { return this.rights.includes('t') && this.rights.includes('e'); }
get maySetSeen() { return this.rights.includes('s'); }
get maySetKeywords() { return this.rights.includes('w'); }
get mayCreateChild() { return this.rights.includes('k'); }
get mayRename() { return this.rights.includes('x'); }
get mayDelete() { return this.rights.includes('x'); }
get maySubmit() { return this.rights.includes('p'); }
*/
}
export class FolderPopupView extends AbstractViewPopup {
constructor() {
super('Folder');
addObservablesTo(this, {
folder: null, // FolderModel
parentFolder: '',
name: '',
editing: false,
adminACL: false
});
this.ACLAllowed = FolderUserStore.hasCapability('ACL');
this.parentFolderSelectList = koComputable(() =>
folderListOptionsBuilder(
[],
[['', '']],
oItem => oItem ? oItem.detailedName() : '',
item => !item.subFolders.allow
|| (FolderUserStore.namespace && !item.fullName.startsWith(FolderUserStore.namespace))
)
);
this.displaySpecSetting = FolderUserStore.displaySpecSetting;
this.showKolab = FolderUserStore.allowKolab();
this.kolabTypeOptions = ko.observableArray();
let i18nFilter = key => i18n('SETTINGS_FOLDERS/TYPE_' + key);
initOnStartOrLangChange(()=>{
this.kolabTypeOptions([
{ id: '', name: '' },
{ id: 'event', name: i18nFilter('CALENDAR') },
{ id: 'contact', name: i18nFilter('CONTACTS') },
{ id: 'task', name: i18nFilter('TASKS') },
{ id: 'note', name: i18nFilter('NOTES') },
{ id: 'file', name: i18nFilter('FILES') },
{ id: 'journal', name: i18nFilter('JOURNAL') },
{ id: 'configuration', name: i18nFilter('CONFIGURATION') }
]);
});
this.defaultOptionsAfterRender = defaultOptionsAfterRender;
this.editACL = this.editACL.bind(this);
this.deleteACL = this.deleteACL.bind(this);
}
afterHide() {
this.editing(false);
}
submitForm(/*form*/) {
const
folder = this.folder(),
nameToEdit = this.name().trim(),
newParentName = this.parentFolder(),
oldParent = getFolderFromCacheList(folder.parentName),
newParent = getFolderFromCacheList(newParentName),
folderList = FolderUserStore.folderList,
newFolderList = newParent ? newParent.subFolders : folderList,
delimiter = (newParent || folder).delimiter,
oldFullname = folder.fullName,
newFullname = (newParent ? newParentName + delimiter : '') + nameToEdit;
if (nameToEdit && newFullname != oldFullname) {
Remote.abort('Folders').post('FolderRename', FolderUserStore.foldersRenaming, {
oldName: oldFullname,
newName: newFullname,
// toggleFolderSubscription / FolderSubscribe
subscribe: folder.isSubscribed() ? 1 : 0,
// toggleFolderCheckable / FolderCheckable
checkable: folder.checkable() ? 1 : 0,
// toggleFolderKolabType / FolderSetMetadata
kolab: {
// TODO: append '.default' ?
type: FolderMetadataKeys.KolabFolderType,
value: folder.kolabType()
}
})
.then(() => {
const
renameFolder = (folder, parent) => {
removeFolderFromCacheList(folder.fullName);
folder.parentName = (parent ? parent.fullName : '');
folder.fullName = (parent ? parent.fullName + delimiter : '') + folder.name();
folder.delimiter = delimiter;
folder.deep = (parent ? parent.deep : -1) + 1;
setFolder(folder);
},
renameChildren = folder => {
folder.subFolders.forEach(child => {
renameFolder(child, folder);
renameChildren(child);
})
};
folder.name(nameToEdit);
renameFolder(folder, newParent);
if (folder.subFolders.length || newParent != oldParent) {
// Rename all subfolders to prevent reload
renameChildren(folder);
}
(oldParent ? oldParent.subFolders : folderList).remove(folder);
newFolderList.push(folder);
sortFolders(newFolderList);
})
.catch(error => {
console.error(error);
FolderUserStore.error(
getNotification(error.code, '', Notifications.CantRenameFolder) + '.\n' + error.message
);
});
} else {
Remote.request('FolderSettings', null, {
folder: folder.fullName,
// toggleFolderSubscription / FolderSubscribe
subscribe: folder.isSubscribed() ? 1 : 0,
// toggleFolderCheckable / FolderCheckable
checkable: folder.checkable() ? 1 : 0,
// toggleFolderKolabType / FolderSetMetadata
kolab: {
// TODO: append '.default' ?
type: FolderMetadataKeys.KolabFolderType,
value: folder.kolabType()
}
});
}
this.close();
}
createACL()
{
showScreenPopup(FolderACLPopupView, [this.folder(), new FolderACLRightsModel]);
}
editACL(acl)
{
showScreenPopup(FolderACLPopupView, [this.folder(), acl]);
}
deleteACL(acl)
{
Remote.request('FolderDeleteACL',
(iError, data) => !iError && data.Result && this.folder().ACL.remove(acl),
{
folder: this.folder().fullName,
identifier: acl.identifier
}
);
}
beforeShow(folder) {
folder.ACL || (folder.ACL = ko.observableArray());
this.adminACL(false);
this.ACLAllowed && Remote.request('FolderACL', (iError, data) => {
if (!iError && data.Result) {
folder.ACL(FolderACLModel.reviveFromJson(data.Result));
// data.Result.map(aItem => FolderACLRightsModel.reviveFromJson(aItem)).filter(v => v)
this.adminACL(folder.ACL()[0].rights.includes('a'));
}
}, {
folder: folder.fullName
});
this.editing(!folder.type() && folder.exists && folder.selectable());
this.name(folder.name()),
this.parentFolder(folder.parentName);
this.folder(folder);
}
}