mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-11 04:07:43 +02:00
feat: add drive permissions (#10489)
Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
@@ -234,6 +234,12 @@ function defineDrive (builder: Builder): void {
|
||||
icon: drive.icon.Drive,
|
||||
baseClass: drive.class.Drive,
|
||||
availablePermissions: [
|
||||
drive.permission.CreateFolder,
|
||||
drive.permission.UpdateFolder,
|
||||
drive.permission.RemoveFolder,
|
||||
drive.permission.CreateFile,
|
||||
drive.permission.UpdateFile,
|
||||
drive.permission.RemoveFile,
|
||||
core.permission.UpdateSpace,
|
||||
core.permission.ArchiveSpace,
|
||||
core.permission.ForbidDeleteObject
|
||||
@@ -326,7 +332,8 @@ function defineDrive (builder: Builder): void {
|
||||
mode: ['context', 'browser'],
|
||||
application: drive.app.Drive,
|
||||
group: 'create'
|
||||
}
|
||||
},
|
||||
visibilityTester: drive.function.CanCreateFolder
|
||||
},
|
||||
drive.action.CreateRootFolder
|
||||
)
|
||||
@@ -475,6 +482,7 @@ function defineFolder (builder: Builder): void {
|
||||
actions: [
|
||||
view.action.Open,
|
||||
view.action.OpenInNewTab,
|
||||
view.action.Delete,
|
||||
print.action.Print,
|
||||
tracker.action.EditRelatedTargets,
|
||||
tracker.action.NewRelatedIssue
|
||||
@@ -494,7 +502,8 @@ function defineFolder (builder: Builder): void {
|
||||
mode: ['context', 'browser'],
|
||||
application: drive.app.Drive,
|
||||
group: 'create'
|
||||
}
|
||||
},
|
||||
visibilityTester: drive.function.CanCreateFolder
|
||||
},
|
||||
drive.action.CreateChildFolder
|
||||
)
|
||||
@@ -518,6 +527,25 @@ function defineFolder (builder: Builder): void {
|
||||
drive.action.RenameFolder
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.Delete,
|
||||
label: view.string.Delete,
|
||||
icon: view.icon.Delete,
|
||||
category: drive.category.Drive,
|
||||
input: 'none',
|
||||
target: drive.class.Folder,
|
||||
context: {
|
||||
mode: ['context', 'browser'],
|
||||
application: drive.app.Drive,
|
||||
group: 'edit'
|
||||
},
|
||||
visibilityTester: drive.function.CanDeleteFolder
|
||||
},
|
||||
drive.action.DeleteFolder
|
||||
)
|
||||
|
||||
createAction(builder, {
|
||||
...actionTemplates.move,
|
||||
action: view.actionImpl.ShowPopup,
|
||||
@@ -529,6 +557,7 @@ function defineFolder (builder: Builder): void {
|
||||
}
|
||||
},
|
||||
target: drive.class.Folder,
|
||||
visibilityTester: drive.function.CanUpdateFolder,
|
||||
context: {
|
||||
mode: ['browser', 'context'],
|
||||
group: 'tools'
|
||||
@@ -569,7 +598,8 @@ function defineFileVersion (builder: Builder): void {
|
||||
mode: ['context', 'browser'],
|
||||
application: drive.app.Drive,
|
||||
group: 'edit'
|
||||
}
|
||||
},
|
||||
visibilityTester: drive.function.CanUpdateFileVersion
|
||||
},
|
||||
drive.action.RestoreFileVersion
|
||||
)
|
||||
@@ -649,6 +679,7 @@ function defineFile (builder: Builder): void {
|
||||
actions: [
|
||||
view.action.Open,
|
||||
view.action.OpenInNewTab,
|
||||
view.action.Delete,
|
||||
print.action.Print,
|
||||
tracker.action.EditRelatedTargets,
|
||||
tracker.action.NewRelatedIssue
|
||||
@@ -692,6 +723,25 @@ function defineFile (builder: Builder): void {
|
||||
drive.action.RenameFile
|
||||
)
|
||||
|
||||
createAction(
|
||||
builder,
|
||||
{
|
||||
action: view.actionImpl.Delete,
|
||||
label: view.string.Delete,
|
||||
icon: view.icon.Delete,
|
||||
category: drive.category.Drive,
|
||||
input: 'none',
|
||||
target: drive.class.File,
|
||||
context: {
|
||||
mode: ['context', 'browser'],
|
||||
application: drive.app.Drive,
|
||||
group: 'edit'
|
||||
},
|
||||
visibilityTester: drive.function.CanDeleteFile
|
||||
},
|
||||
drive.action.DeleteFile
|
||||
)
|
||||
|
||||
// createAction(
|
||||
// builder,
|
||||
// {
|
||||
@@ -721,6 +771,7 @@ function defineFile (builder: Builder): void {
|
||||
}
|
||||
},
|
||||
target: drive.class.File,
|
||||
visibilityTester: drive.function.CanUpdateFile,
|
||||
context: {
|
||||
mode: ['browser', 'context'],
|
||||
group: 'tools'
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//
|
||||
|
||||
import core, { type Blob, type Ref, DOMAIN_BLOB, generateId, toIdMap } from '@hcengineering/core'
|
||||
import type { Drive, File, FileVersion, Resource } from '@hcengineering/drive'
|
||||
import type { File, FileVersion, Resource } from '@hcengineering/drive'
|
||||
import {
|
||||
type MigrateOperation,
|
||||
type MigrationClient,
|
||||
@@ -56,7 +56,7 @@ async function migrateFileVersions (client: MigrationClient): Promise<void> {
|
||||
collection: 'versions',
|
||||
modifiedOn: file.modifiedOn,
|
||||
modifiedBy: file.modifiedBy,
|
||||
space: file.space as Ref<Drive>,
|
||||
space: file.space,
|
||||
title: exfile.title,
|
||||
file: blob._id,
|
||||
size: blob.size,
|
||||
|
||||
@@ -3,6 +3,84 @@ import core from '@hcengineering/core'
|
||||
import drive from '@hcengineering/drive'
|
||||
|
||||
export function definePermissions (builder: Builder): void {
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
{
|
||||
scope: 'space',
|
||||
label: drive.string.CreateFilePermission,
|
||||
description: drive.string.CreateFilePermissionDescription,
|
||||
txClass: core.class.TxCreateDoc,
|
||||
objectClass: drive.class.File
|
||||
},
|
||||
drive.permission.CreateFile
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
{
|
||||
scope: 'space',
|
||||
label: drive.string.UpdateFilePermission,
|
||||
description: drive.string.UpdateFilePermissionDescription,
|
||||
txClass: core.class.TxUpdateDoc,
|
||||
objectClass: drive.class.File
|
||||
},
|
||||
drive.permission.UpdateFile
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
{
|
||||
scope: 'space',
|
||||
label: drive.string.RemoveFilePermission,
|
||||
description: drive.string.RemoveFilePermissionDescription,
|
||||
txClass: core.class.TxRemoveDoc,
|
||||
objectClass: drive.class.File
|
||||
},
|
||||
drive.permission.RemoveFile
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
{
|
||||
scope: 'space',
|
||||
label: drive.string.CreateFolderPermission,
|
||||
description: drive.string.CreateFolderPermissionDescription,
|
||||
txClass: core.class.TxCreateDoc,
|
||||
objectClass: drive.class.Folder
|
||||
},
|
||||
drive.permission.CreateFolder
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
{
|
||||
scope: 'space',
|
||||
label: drive.string.UpdateFolderPermission,
|
||||
description: drive.string.UpdateFolderPermissionDescription,
|
||||
txClass: core.class.TxUpdateDoc,
|
||||
objectClass: drive.class.Folder
|
||||
},
|
||||
drive.permission.UpdateFolder
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
{
|
||||
scope: 'space',
|
||||
label: drive.string.RemoveFolderPermission,
|
||||
description: drive.string.RemoveFolderPermissionDescription,
|
||||
txClass: core.class.TxRemoveDoc,
|
||||
objectClass: drive.class.Folder
|
||||
},
|
||||
drive.permission.RemoveFolder
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
core.class.Permission,
|
||||
core.space.Model,
|
||||
|
||||
@@ -53,8 +53,14 @@ export default mergeIds(driveId, drive, {
|
||||
DriveLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
|
||||
FolderLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
|
||||
FileLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
|
||||
CanCreateFolder: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanUpdateFile: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanUpdateFolder: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanDeleteFile: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanDeleteFolder: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanRenameFile: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanRenameFolder: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanUpdateFileVersion: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
CanDeleteFileVersion: '' as Resource<ViewActionAvailabilityFunction>,
|
||||
FileTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>,
|
||||
FolderTitleProvider: '' as Resource<(client: Client, ref: Ref<Doc>, doc?: Doc) => Promise<string>>
|
||||
@@ -79,6 +85,8 @@ export default mergeIds(driveId, drive, {
|
||||
CreateRootFolder: '' as Ref<Action>,
|
||||
EditDrive: '' as Ref<Action>,
|
||||
DownloadFile: '' as Ref<Action>,
|
||||
DeleteFile: '' as Ref<Action>,
|
||||
DeleteFolder: '' as Ref<Action>,
|
||||
RenameFile: '' as Ref<Action>,
|
||||
RenameFolder: '' as Ref<Action>,
|
||||
DeleteFileVersion: '' as Ref<Action>,
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Obnovit",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Zakázat vytvoření disku",
|
||||
"ForbidCreateDrivePermissionDescription": "Zakazuje uživatelům vytvářet nové disky"
|
||||
"ForbidCreateDrivePermissionDescription": "Zakazuje uživatelům vytvářet nové disky",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Wiederherstellen",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Laufwerkserstellung verbieten",
|
||||
"ForbidCreateDrivePermissionDescription": "Verbietet Benutzern die Erstellung neuer Laufwerke"
|
||||
"ForbidCreateDrivePermissionDescription": "Verbietet Benutzern die Erstellung neuer Laufwerke",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Restore",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Forbid create drive",
|
||||
"ForbidCreateDrivePermissionDescription": "Forbid users creating new drives"
|
||||
"ForbidCreateDrivePermissionDescription": "Forbid users creating new drives",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Restaurar",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Prohibir crear unidad",
|
||||
"ForbidCreateDrivePermissionDescription": "Prohíbe a los usuarios crear nuevas unidades"
|
||||
"ForbidCreateDrivePermissionDescription": "Prohíbe a los usuarios crear nuevas unidades",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Restaurer",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Interdire la création de disque",
|
||||
"ForbidCreateDrivePermissionDescription": "Interdit aux utilisateurs de créer de nouveaux disques"
|
||||
"ForbidCreateDrivePermissionDescription": "Interdit aux utilisateurs de créer de nouveaux disques",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Ripristina",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Vieta creazione drive",
|
||||
"ForbidCreateDrivePermissionDescription": "Vieta agli utenti di creare nuovi drive"
|
||||
"ForbidCreateDrivePermissionDescription": "Vieta agli utenti di creare nuovi drive",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "復元",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "ドライブの作成禁止",
|
||||
"ForbidCreateDrivePermissionDescription": "ユーザーが新しいドライブを作成することを禁止します"
|
||||
"ForbidCreateDrivePermissionDescription": "ユーザーが新しいドライブを作成することを禁止します",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Restaurar",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Proibir criação de unidade",
|
||||
"ForbidCreateDrivePermissionDescription": "Proíbe os utilizadores de criar novas unidades"
|
||||
"ForbidCreateDrivePermissionDescription": "Proíbe os utilizadores de criar novas unidades",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "Восстановить",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "Запретить создание диска",
|
||||
"ForbidCreateDrivePermissionDescription": "Запрещает пользователям создавать новые диски"
|
||||
"ForbidCreateDrivePermissionDescription": "Запрещает пользователям создавать новые диски",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,18 @@
|
||||
"EditDrive": "Sürücüyü Düzenle",
|
||||
"Rename": "Yeniden adlandır",
|
||||
"Restore": "Geri yükle",
|
||||
"Root": "/"
|
||||
"Root": "/",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,18 @@
|
||||
"Restore": "恢复",
|
||||
"Root": "/",
|
||||
"ForbidCreateDrivePermission": "禁止创建磁盘",
|
||||
"ForbidCreateDrivePermissionDescription": "禁止用户创建新磁盘"
|
||||
"ForbidCreateDrivePermissionDescription": "禁止用户创建新磁盘",
|
||||
"CreateFilePermission": "Create File",
|
||||
"CreateFilePermissionDescription": "Grants users ability to create files",
|
||||
"UpdateFilePermission": "Update File",
|
||||
"UpdateFilePermissionDescription": "Grants users ability to update files",
|
||||
"RemoveFilePermission": "Remove File",
|
||||
"RemoveFilePermissionDescription": "Grants users ability to remove files",
|
||||
"CreateFolderPermission": "Create Folder",
|
||||
"CreateFolderPermissionDescription": "Grants users ability to create folders",
|
||||
"UpdateFolderPermission": "Update Folder",
|
||||
"UpdateFolderPermissionDescription": "Grants users ability to update folders",
|
||||
"RemoveFolderPermission": "Remove Folder",
|
||||
"RemoveFolderPermissionDescription": "Grants users ability to remove folders"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
import { AccountArrayEditor, employeeRefByAccountUuidStore } from '@hcengineering/contact-resources'
|
||||
import core, {
|
||||
Data,
|
||||
DocumentUpdate,
|
||||
RolesAssignment,
|
||||
Ref,
|
||||
Role,
|
||||
@@ -48,6 +47,8 @@
|
||||
let description: string = drive?.description ?? ''
|
||||
let isPrivate: boolean = drive?.private ?? false
|
||||
|
||||
let autoJoin = drive?.autoJoin ?? false
|
||||
let restricted: boolean = drive?.restricted ?? false
|
||||
let members: AccountUuid[] =
|
||||
drive?.members !== undefined ? hierarchy.clone(drive.members) : [getCurrentAccount().uuid]
|
||||
let owners: AccountUuid[] = drive?.owners !== undefined ? hierarchy.clone(drive.owners) : [getCurrentAccount().uuid]
|
||||
@@ -102,7 +103,9 @@
|
||||
private: isPrivate,
|
||||
members,
|
||||
owners,
|
||||
archived: false
|
||||
autoJoin,
|
||||
archived: false,
|
||||
restricted
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,41 +114,8 @@
|
||||
return
|
||||
}
|
||||
|
||||
const data = getDriveData()
|
||||
const update: DocumentUpdate<Drive> = {}
|
||||
if (data.name !== drive?.name) {
|
||||
update.name = data.name
|
||||
}
|
||||
if (data.description !== drive?.description) {
|
||||
update.description = data.description
|
||||
}
|
||||
if (data.private !== drive?.private) {
|
||||
update.private = data.private
|
||||
}
|
||||
if (data.members.length !== drive?.members.length) {
|
||||
update.members = data.members
|
||||
} else {
|
||||
for (const member of data.members) {
|
||||
if (drive.members.findIndex((p) => p === member) === -1) {
|
||||
update.members = data.members
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.owners?.length !== drive?.owners?.length) {
|
||||
update.owners = data.owners
|
||||
} else {
|
||||
for (const owner of data.owners ?? []) {
|
||||
if (drive.owners?.findIndex((p) => p === owner) === -1) {
|
||||
update.owners = data.owners
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(update).length > 0) {
|
||||
await client.update(drive, update)
|
||||
}
|
||||
const update = getDriveData()
|
||||
await client.diffUpdate(drive, update)
|
||||
|
||||
if (!deepEqual(rolesAssignment, getRolesAssignment())) {
|
||||
await client.updateMixin(
|
||||
@@ -307,6 +277,22 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header withDesciption">
|
||||
<Label label={core.string.AutoJoin} />
|
||||
<span><Label label={core.string.AutoJoinDescr} /></span>
|
||||
</div>
|
||||
<Toggle id={'space-autoJoin'} bind:on={autoJoin} />
|
||||
</div>
|
||||
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header withDesciption">
|
||||
<Label label={core.string.RBAC} />
|
||||
<span><Label label={core.string.RBACDescr} /></span>
|
||||
</div>
|
||||
<Toggle id={'space-restricted'} bind:on={restricted} />
|
||||
</div>
|
||||
|
||||
{#each roles as role}
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header">
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { AccountRole, Ref, getCurrentAccount } from '@hcengineering/core'
|
||||
import { checkMyPermission, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { type Drive } from '@hcengineering/drive'
|
||||
import { getResource } from '@hcengineering/platform'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
@@ -23,6 +24,7 @@
|
||||
import { getFolderIdFromFragment } from '../navigation'
|
||||
import { showCreateDrivePopup, showCreateFolderPopup, getUploadOptionsByFragment } from '../utils'
|
||||
import { onMount } from 'svelte'
|
||||
import { canCreateObject } from '@hcengineering/view-resources'
|
||||
|
||||
export let currentSpace: Ref<Drive> | undefined
|
||||
export let currentFragment: string | undefined
|
||||
@@ -44,6 +46,8 @@
|
||||
]
|
||||
|
||||
let uploadActions: HeaderButtonAction[] = []
|
||||
let filteredUploadActions: HeaderButtonAction[] = []
|
||||
let filteredBasicActions: HeaderButtonAction[] = []
|
||||
let allActions: HeaderButtonAction[] = []
|
||||
|
||||
const myAcc = getCurrentAccount()
|
||||
@@ -84,6 +88,12 @@
|
||||
)
|
||||
|
||||
$: parent = getFolderIdFromFragment(currentFragment ?? '') ?? drive.ids.Root
|
||||
$: canCreateFolder =
|
||||
currentSpace !== undefined && canCreateObject(drive.class.Folder, currentSpace, $permissionsStore)
|
||||
$: canUpload = currentSpace !== undefined && canCreateObject(drive.class.File, currentSpace, $permissionsStore)
|
||||
|
||||
$: filteredBasicActions = [basicActions[0], ...(canCreateFolder ? [basicActions[1]] : [])]
|
||||
$: filteredUploadActions = canUpload ? uploadActions : []
|
||||
|
||||
function handleCreateDrive (): void {
|
||||
void showCreateDrivePopup()
|
||||
@@ -94,7 +104,11 @@
|
||||
}
|
||||
|
||||
let visibleActions: (string | number | null)[] = []
|
||||
function updateActions (hasSpace: boolean, uploadActions: HeaderButtonAction[]): void {
|
||||
function updateActions (
|
||||
hasSpace: boolean,
|
||||
uploadActions: HeaderButtonAction[],
|
||||
basicActions: HeaderButtonAction[]
|
||||
): void {
|
||||
allActions = [...basicActions, ...uploadActions]
|
||||
if (hasSpace) {
|
||||
visibleActions = allActions.map((a) => a.id)
|
||||
@@ -103,7 +117,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
$: updateActions(hasDrive, uploadActions)
|
||||
$: updateActions(hasDrive, filteredUploadActions, filteredBasicActions)
|
||||
</script>
|
||||
|
||||
<HeaderButton loading={false} {client} mainActionId={uploadActions[0]?.id} {visibleActions} actions={allActions} />
|
||||
<HeaderButton
|
||||
loading={false}
|
||||
{client}
|
||||
mainActionId={filteredUploadActions[0]?.id}
|
||||
{visibleActions}
|
||||
actions={allActions}
|
||||
/>
|
||||
|
||||
@@ -13,19 +13,14 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { type Drive, type Folder } from '@hcengineering/drive'
|
||||
import { type Folder } from '@hcengineering/drive'
|
||||
|
||||
import { type Ref } from '@hcengineering/core'
|
||||
import FolderBrowser from './FolderBrowser.svelte'
|
||||
|
||||
export let object: Folder
|
||||
export let readonly: boolean = false
|
||||
|
||||
function getSpace (object: Folder): Ref<Drive> {
|
||||
return object.space as Ref<Drive>
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if object}
|
||||
<FolderBrowser space={getSpace(object)} parent={object._id} {readonly} type={'folder'} />
|
||||
<FolderBrowser space={object.space} parent={object._id} {readonly} type={'folder'} />
|
||||
{/if}
|
||||
|
||||
@@ -14,13 +14,14 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { type Ref, type WithLookup } from '@hcengineering/core'
|
||||
import { checkMyPermission, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { createFileVersion, type File as DriveFile, type FileVersion } from '@hcengineering/drive'
|
||||
import { Panel } from '@hcengineering/panel'
|
||||
import { createQuery, getClient, getFileUrl } from '@hcengineering/presentation'
|
||||
import { Button, IconMoreH } from '@hcengineering/ui'
|
||||
import { FileUploadCallbackParams, showFilesUploadPopup } from '@hcengineering/uploader'
|
||||
import view from '@hcengineering/view'
|
||||
import { showMenu } from '@hcengineering/view-resources'
|
||||
import { canChangeDoc, showMenu } from '@hcengineering/view-resources'
|
||||
|
||||
import EditFile from './EditFile.svelte'
|
||||
import FileAside from './FileAside.svelte'
|
||||
@@ -58,6 +59,7 @@
|
||||
}
|
||||
}
|
||||
)
|
||||
$: canUploadVersion = object !== undefined && canChangeDoc(drive.class.File, object.space, $permissionsStore)
|
||||
|
||||
function handleDownloadFile (): void {
|
||||
if (object != null && download != null) {
|
||||
@@ -66,7 +68,7 @@
|
||||
}
|
||||
|
||||
function handleUploadFile (): void {
|
||||
if (object != null) {
|
||||
if (object != null && canUploadVersion) {
|
||||
const target = { objectId: object._id, objectClass: object._class }
|
||||
void showFilesUploadPopup(
|
||||
{
|
||||
@@ -123,13 +125,15 @@
|
||||
on:click={handleDownloadFile}
|
||||
/>
|
||||
</a>
|
||||
<Button
|
||||
icon={IconUpload}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
showTooltip={{ label: drive.string.Upload }}
|
||||
on:click={handleUploadFile}
|
||||
/>
|
||||
{#if canUploadVersion}
|
||||
<Button
|
||||
icon={IconUpload}
|
||||
iconProps={{ size: 'medium' }}
|
||||
kind={'icon'}
|
||||
showTooltip={{ label: drive.string.Upload }}
|
||||
on:click={handleUploadFile}
|
||||
/>
|
||||
{/if}
|
||||
<Button
|
||||
icon={IconMoreH}
|
||||
iconProps={{ size: 'medium' }}
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { type Doc, type DocumentQuery, type Space, type Ref, type WithLookup } from '@hcengineering/core'
|
||||
import { type Doc, type DocumentQuery, type Ref, type WithLookup } from '@hcengineering/core'
|
||||
import { permissionsStore } from '@hcengineering/contact-resources'
|
||||
import drive, { type Drive, type Folder } from '@hcengineering/drive'
|
||||
import { Scroller, SearchInput, Panel, Button, IconMoreH } from '@hcengineering/ui'
|
||||
import view, { Viewlet, ViewOptions } from '@hcengineering/view'
|
||||
@@ -24,7 +25,8 @@
|
||||
ViewletSelector,
|
||||
ViewletSettingButton,
|
||||
DocAttributeBar,
|
||||
showMenu
|
||||
showMenu,
|
||||
canCreateObject
|
||||
} from '@hcengineering/view-resources'
|
||||
|
||||
import DrivePresenter from './DrivePresenter.svelte'
|
||||
@@ -42,6 +44,7 @@
|
||||
|
||||
$: object = type === 'drive' ? (object as Drive) : (object as Folder)
|
||||
$: query = { space, parent }
|
||||
$: canUpload = canCreateObject(drive.class.File, space, $permissionsStore)
|
||||
|
||||
let viewlet: WithLookup<Viewlet> | undefined = undefined
|
||||
let viewOptions: ViewOptions | undefined
|
||||
@@ -101,7 +104,7 @@
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class="popupPanel-body" on:contextmenu>
|
||||
{#if viewlet}
|
||||
<FileDropArea {space} {parent} canDrop={() => !readonly}>
|
||||
<FileDropArea {space} {parent} canDrop={() => !readonly && canUpload}>
|
||||
<Scroller horizontal={true}>
|
||||
<ViewletContentView {_class} {viewlet} query={resultQuery} {space} {viewOptions} />
|
||||
</Scroller>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
let space: Ref<Drive> = value.space as Ref<Drive>
|
||||
let space: Ref<Drive> = value.space
|
||||
let parent: Ref<Folder> = value.parent as Ref<Folder>
|
||||
|
||||
async function save (): Promise<void> {
|
||||
|
||||
@@ -13,11 +13,14 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { permissionsStore } from '@hcengineering/contact-resources'
|
||||
import type { Class, Client, Doc, DocumentQuery, Ref, RelatedDocument, WithLookup } from '@hcengineering/core'
|
||||
import drive, { type Drive, type File, type FileVersion, type Folder } from '@hcengineering/drive'
|
||||
import { type Resources } from '@hcengineering/platform'
|
||||
import { type ObjectSearchResult, getFileUrl } from '@hcengineering/presentation'
|
||||
import { showPopup, type Location } from '@hcengineering/ui'
|
||||
import { canChangeDoc, canCreateObject, canDeleteObject, canRemoveDoc } from '@hcengineering/view-resources'
|
||||
import { get } from 'svelte/store'
|
||||
|
||||
import CreateDrive from './components/CreateDrive.svelte'
|
||||
import DrivePanel from './components/DrivePanel.svelte'
|
||||
@@ -153,22 +156,96 @@ async function RestoreFileVersion (doc: FileVersion | FileVersion[]): Promise<vo
|
||||
}
|
||||
|
||||
export async function CanRenameFile (doc: File | File[] | undefined): Promise<boolean> {
|
||||
return doc !== undefined && !Array.isArray(doc)
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
return canChangeDoc(drive.class.File, doc.space, get(permissionsStore))
|
||||
}
|
||||
|
||||
export async function CanRenameFolder (doc: Folder | Folder[] | undefined): Promise<boolean> {
|
||||
return doc !== undefined && !Array.isArray(doc)
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
return canChangeDoc(drive.class.Folder, doc.space, get(permissionsStore))
|
||||
}
|
||||
|
||||
export async function CanUpdateFileVersion (doc: FileVersion | FileVersion[] | undefined): Promise<boolean> {
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return canChangeDoc(drive.class.File, doc.space, get(permissionsStore))
|
||||
}
|
||||
|
||||
export async function CanDeleteFileVersion (
|
||||
doc: WithLookup<FileVersion> | Array<WithLookup<FileVersion>> | undefined
|
||||
): Promise<boolean> {
|
||||
if (doc === undefined) {
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const docs = Array.isArray(doc) ? doc : [doc]
|
||||
return docs.every((p) => p.$lookup?.attachedTo !== undefined && p.$lookup?.attachedTo.file !== p._id)
|
||||
const canDeleteByVersion = docs.every(
|
||||
(p) => p.$lookup?.attachedTo !== undefined && p.$lookup?.attachedTo.file !== p._id
|
||||
)
|
||||
if (!canDeleteByVersion) {
|
||||
return false
|
||||
}
|
||||
|
||||
const permissions = get(permissionsStore)
|
||||
return docs.every((p) => canChangeDoc(drive.class.File, doc.space, permissions))
|
||||
}
|
||||
|
||||
export async function CanCreateFolder (doc: Drive | Folder | Array<Drive | Folder> | undefined): Promise<boolean> {
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
const space = ((doc as Drive).space ?? doc._id) as Ref<Drive>
|
||||
return canCreateObject(drive.class.Folder, space, get(permissionsStore))
|
||||
}
|
||||
|
||||
export async function CanUpdateFile (doc: File | File[] | undefined): Promise<boolean> {
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
return canChangeDoc(drive.class.File, doc.space, get(permissionsStore))
|
||||
}
|
||||
|
||||
export async function CanUpdateFolder (doc: Folder | Folder[] | undefined): Promise<boolean> {
|
||||
if (doc === undefined || Array.isArray(doc)) {
|
||||
return false
|
||||
}
|
||||
return canChangeDoc(drive.class.Folder, doc.space, get(permissionsStore))
|
||||
}
|
||||
|
||||
export async function CanDeleteFile (doc: File | File[] | undefined): Promise<boolean> {
|
||||
if (doc === undefined) return false
|
||||
doc = Array.isArray(doc) ? doc : [doc]
|
||||
|
||||
const permissions = get(permissionsStore)
|
||||
const results = await Promise.all(
|
||||
doc.map(async (p) => {
|
||||
return permissions.restrictedSpaces.has(p.space)
|
||||
? canRemoveDoc(drive.class.File, p.space, permissions)
|
||||
: await canDeleteObject(doc)
|
||||
})
|
||||
)
|
||||
return results.every(Boolean)
|
||||
}
|
||||
|
||||
export async function CanDeleteFolder (doc: Folder | Folder[] | undefined): Promise<boolean> {
|
||||
if (doc === undefined) return false
|
||||
doc = Array.isArray(doc) ? doc : [doc]
|
||||
|
||||
const permissions = get(permissionsStore)
|
||||
const results = await Promise.all(
|
||||
doc.map(async (p) => {
|
||||
return permissions.restrictedSpaces.has(p.space)
|
||||
? canRemoveDoc(drive.class.Folder, p.space, permissions)
|
||||
: await canDeleteObject(doc)
|
||||
})
|
||||
)
|
||||
return results.every(Boolean)
|
||||
}
|
||||
|
||||
export async function FileTitleProvider (client: Client, ref: Ref<File>, doc?: File): Promise<string> {
|
||||
@@ -222,8 +299,14 @@ export default async (): Promise<Resources> => ({
|
||||
DriveLinkProvider,
|
||||
FileLinkProvider,
|
||||
FolderLinkProvider,
|
||||
CanCreateFolder,
|
||||
CanUpdateFile,
|
||||
CanUpdateFolder,
|
||||
CanDeleteFile,
|
||||
CanDeleteFolder,
|
||||
CanRenameFile,
|
||||
CanRenameFolder,
|
||||
CanUpdateFileVersion,
|
||||
CanDeleteFileVersion,
|
||||
FileTitleProvider,
|
||||
FolderTitleProvider
|
||||
|
||||
@@ -161,7 +161,7 @@ export async function resolveParents (object: Resource): Promise<Doc[]> {
|
||||
}
|
||||
}
|
||||
|
||||
const root = await client.findOne(drive.class.Drive, { _id: object.space as Ref<Drive> })
|
||||
const root = await client.findOne(drive.class.Drive, { _id: object.space })
|
||||
if (root !== undefined) {
|
||||
parents.push(root)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,19 @@ export const drivePlugin = plugin(driveId, {
|
||||
Folder: '' as IntlString,
|
||||
Resource: '' as IntlString,
|
||||
ForbidCreateDrivePermission: '' as IntlString,
|
||||
ForbidCreateDrivePermissionDescription: '' as IntlString
|
||||
ForbidCreateDrivePermissionDescription: '' as IntlString,
|
||||
CreateFilePermission: '' as IntlString,
|
||||
CreateFilePermissionDescription: '' as IntlString,
|
||||
UpdateFilePermission: '' as IntlString,
|
||||
UpdateFilePermissionDescription: '' as IntlString,
|
||||
RemoveFilePermission: '' as IntlString,
|
||||
RemoveFilePermissionDescription: '' as IntlString,
|
||||
CreateFolderPermission: '' as IntlString,
|
||||
CreateFolderPermissionDescription: '' as IntlString,
|
||||
UpdateFolderPermission: '' as IntlString,
|
||||
UpdateFolderPermissionDescription: '' as IntlString,
|
||||
RemoveFolderPermission: '' as IntlString,
|
||||
RemoveFolderPermissionDescription: '' as IntlString
|
||||
},
|
||||
descriptor: {
|
||||
DriveType: '' as Ref<SpaceTypeDescriptor>
|
||||
@@ -75,7 +87,13 @@ export const drivePlugin = plugin(driveId, {
|
||||
DefaultDrive: '' as Ref<SpaceType>
|
||||
},
|
||||
permission: {
|
||||
ForbidCreateDrive: '' as Ref<Permission>
|
||||
ForbidCreateDrive: '' as Ref<Permission>,
|
||||
CreateFile: '' as Ref<Permission>,
|
||||
UpdateFile: '' as Ref<Permission>,
|
||||
RemoveFile: '' as Ref<Permission>,
|
||||
CreateFolder: '' as Ref<Permission>,
|
||||
UpdateFolder: '' as Ref<Permission>,
|
||||
RemoveFolder: '' as Ref<Permission>
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ export function TypeFileVersion (): Type<number> {
|
||||
export interface Drive extends TypedSpace {}
|
||||
|
||||
/** @public */
|
||||
export interface Resource extends Doc {
|
||||
export interface Resource extends Doc<Drive> {
|
||||
title: string
|
||||
parent: Ref<Resource>
|
||||
path: Ref<Resource>[]
|
||||
|
||||
@@ -85,6 +85,28 @@ export function canChangeDoc (_class: Ref<Class<Doc>>, space: Ref<Space>, store:
|
||||
return !store.restrictedSpaces.has(space)
|
||||
}
|
||||
|
||||
export function canRemoveDoc (_class: Ref<Class<Doc>>, space: Ref<Space>, store: PermissionsStore): boolean {
|
||||
const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false
|
||||
if (arePermissionsDisabled) return true
|
||||
if (store.whitelist.has(space)) return true
|
||||
if (store.ps[space] !== undefined) {
|
||||
const client = getClient()
|
||||
const h = client.getHierarchy()
|
||||
const ancestors = h.getAncestors(_class)
|
||||
const permissions = client.getModel().findAllSync(core.class.Permission, { txClass: core.class.TxRemoveDoc })
|
||||
for (const ancestor of ancestors) {
|
||||
const curr = permissions.filter((p) => p.objectClass === ancestor && p.txMatch === undefined)
|
||||
for (const permission of curr) {
|
||||
if (store.ps[space]?.has(permission._id)) {
|
||||
return permission.forbid !== true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !store.restrictedSpaces.has(space)
|
||||
}
|
||||
|
||||
export function canCreateObject (_class: Ref<Class<Doc>>, space: Ref<Space>, store: PermissionsStore): boolean {
|
||||
const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false
|
||||
if (arePermissionsDisabled) return true
|
||||
|
||||
Reference in New Issue
Block a user