UBERF-7036 Drive file and folder renaming (#5648)

Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
Alexander Onnikov 2024-05-23 11:46:39 +07:00 committed by GitHub
parent 171a2d1083
commit 858e8f866b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 134 additions and 8 deletions

View File

@ -350,6 +350,25 @@ function defineFolder (builder: Builder): void {
},
drive.action.CreateChildFolder
)
createAction(
builder,
{
action: drive.actionImpl.RenameFolder,
label: drive.string.Rename,
icon: view.icon.Edit,
category: drive.category.Drive,
input: 'none',
target: drive.class.Folder,
context: {
mode: ['context', 'browser'],
application: drive.app.Drive,
group: 'edit'
},
visibilityTester: drive.function.CanRenameFolder
},
drive.action.RenameFolder
)
}
function defineFile (builder: Builder): void {
@ -362,7 +381,12 @@ function defineFile (builder: Builder): void {
// Actions
builder.mixin(drive.class.File, core.class.Class, view.mixin.IgnoreActions, {
actions: [view.action.OpenInNewTab, tracker.action.EditRelatedTargets, tracker.action.NewRelatedIssue]
actions: [
view.action.Open,
view.action.OpenInNewTab,
tracker.action.EditRelatedTargets,
tracker.action.NewRelatedIssue
]
})
createAction(
@ -382,6 +406,25 @@ function defineFile (builder: Builder): void {
},
drive.action.DownloadFile
)
createAction(
builder,
{
action: drive.actionImpl.RenameFile,
label: drive.string.Rename,
icon: view.icon.Edit,
category: drive.category.Drive,
input: 'none',
target: drive.class.File,
context: {
mode: ['context', 'browser'],
application: drive.app.Drive,
group: 'edit'
},
visibilityTester: drive.function.CanRenameFile
},
drive.action.RenameFile
)
}
function defineApplication (builder: Builder): void {

View File

@ -23,6 +23,7 @@ import {
type Action,
type ActionCategory,
type ViewAction,
type ViewActionAvailabilityFunction,
type Viewlet,
type ViewletDescriptor
} from '@hcengineering/view'
@ -44,7 +45,9 @@ export default mergeIds(driveId, drive, {
},
function: {
DriveLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
FolderLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>
FolderLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
CanRenameFile: '' as Resource<ViewActionAvailabilityFunction>,
CanRenameFolder: '' as Resource<ViewActionAvailabilityFunction>
},
viewlet: {
Grid: '' as Ref<ViewletDescriptor>,
@ -59,13 +62,17 @@ export default mergeIds(driveId, drive, {
CreateChildFolder: '' as Ref<Action>,
CreateRootFolder: '' as Ref<Action>,
EditDrive: '' as Ref<Action>,
DownloadFile: '' as Ref<Action>
DownloadFile: '' as Ref<Action>,
RenameFile: '' as Ref<Action>,
RenameFolder: '' as Ref<Action>
},
actionImpl: {
CreateChildFolder: '' as ViewAction,
CreateRootFolder: '' as ViewAction,
EditDrive: '' as ViewAction,
DownloadFile: '' as ViewAction
DownloadFile: '' as ViewAction,
RenameFile: '' as ViewAction,
RenameFolder: '' as ViewAction
},
string: {
Name: '' as IntlString,

View File

@ -18,6 +18,7 @@
"UploadFile": "Upload File",
"UploadFolder": "Upload Folder",
"EditDrive": "Edit Drive",
"Rename": "Rename",
"RoleLabel": "Role",
"Root": "/"
}

View File

@ -18,6 +18,7 @@
"UploadFile": "Загрузить файл",
"UploadFolder": "Загрузить папку",
"EditDrive": "Редактировать",
"Rename": "Переименовать",
"RoleLabel": "Роль",
"Root": "/"
}

View File

@ -0,0 +1,39 @@
<!--
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
-->
<script lang="ts">
import { createEventDispatcher } from 'svelte'
import core from '@hcengineering/core'
import { Card } from '@hcengineering/presentation'
import { EditBox } from '@hcengineering/ui'
import view from '@hcengineering/view'
import drive from '../plugin'
export let value: string | undefined
const dispatch = createEventDispatcher()
$: canSave = value !== undefined && value.trim().length > 0
function handleOkAction (): void {
dispatch('close', value?.trim())
}
</script>
<Card label={drive.string.Rename} okLabel={view.string.Save} okAction={handleOkAction} {canSave} on:close>
<EditBox bind:value placeholder={core.string.Name} autoFocus select />
</Card>

View File

@ -33,7 +33,7 @@ import GridView from './components/GridView.svelte'
import ResourcePresenter from './components/ResourcePresenter.svelte'
import { getDriveLink, getFolderLink, resolveLocation } from './navigation'
import { createFolder } from './utils'
import { createFolder, renameResource } from './utils'
async function CreateRootFolder (doc: Drive): Promise<void> {
await createFolder(doc._id, drive.ids.Root)
@ -68,6 +68,26 @@ async function FolderLinkProvider (doc: Doc): Promise<Location> {
return getFolderLink(doc._id as Ref<Folder>)
}
async function RenameFile (doc: File | File[]): Promise<void> {
if (!Array.isArray(doc)) {
await renameResource(doc)
}
}
async function RenameFolder (doc: Folder | Folder[]): Promise<void> {
if (!Array.isArray(doc)) {
await renameResource(doc)
}
}
export async function CanRenameFile (doc: File | File[] | undefined): Promise<boolean> {
return doc !== undefined && !Array.isArray(doc)
}
export async function CanRenameFolder (doc: Folder | Folder[] | undefined): Promise<boolean> {
return doc !== undefined && !Array.isArray(doc)
}
export default async (): Promise<Resources> => ({
component: {
CreateDrive,
@ -87,11 +107,15 @@ export default async (): Promise<Resources> => ({
CreateChildFolder,
CreateRootFolder,
EditDrive,
DownloadFile
DownloadFile,
RenameFile,
RenameFolder
},
function: {
DriveLinkProvider,
FolderLinkProvider
FolderLinkProvider,
CanRenameFile,
CanRenameFolder
},
resolver: {
Location: resolveLocation

View File

@ -24,6 +24,7 @@ export default mergeIds(driveId, drive, {
UploadFile: '' as IntlString,
UploadFolder: '' as IntlString,
EditDrive: '' as IntlString,
Rename: '' as IntlString,
RoleLabel: '' as IntlString,
Root: '' as IntlString
}

View File

@ -14,7 +14,7 @@
//
import { type Class, type Doc, type Ref } from '@hcengineering/core'
import drive, { type Drive, type Folder } from '@hcengineering/drive'
import drive, { type Drive, type Folder, type Resource } from '@hcengineering/drive'
import { setPlatformStatus, unknownError } from '@hcengineering/platform'
import { getClient, getFileMetadata, uploadFile } from '@hcengineering/presentation'
import { showPopup } from '@hcengineering/ui'
@ -22,6 +22,7 @@ import { openDoc } from '@hcengineering/view-resources'
import CreateDrive from './components/CreateDrive.svelte'
import CreateFolder from './components/CreateFolder.svelte'
import RenamePopup from './components/RenamePopup.svelte'
async function navigateToDoc (_id: Ref<Doc>, _class: Ref<Class<Doc>>): Promise<void> {
const client = getClient()
@ -81,3 +82,12 @@ export async function createFile (file: File, space: Ref<Drive>, parent: Folder
void setPlatformStatus(unknownError(e))
}
}
export async function renameResource (resource: Resource): Promise<void> {
showPopup(RenamePopup, { value: resource.name, format: 'text' }, undefined, async (res) => {
if (res != null && res !== resource.name) {
const client = getClient()
await client.update(resource, { name: res })
}
})
}