Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions models/drive/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@hcengineering/model": "^0.6.11",
"@hcengineering/model-core": "^0.6.0",
"@hcengineering/model-preference": "^0.6.0",
"@hcengineering/model-presentation": "^0.6.0",
"@hcengineering/model-print": "^0.6.0",
"@hcengineering/model-tracker": "^0.6.0",
"@hcengineering/model-view": "^0.6.0",
Expand Down
33 changes: 33 additions & 0 deletions models/drive/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
UX
} from '@hcengineering/model'
import { TAttachedDoc, TDoc, TType, TTypedSpace } from '@hcengineering/model-core'
import presentation from '@hcengineering/model-presentation'
import print from '@hcengineering/model-print'
import tracker from '@hcengineering/model-tracker'
import view, { type Viewlet, actionTemplates, classPresenter, createAction } from '@hcengineering/model-view'
Expand Down Expand Up @@ -432,6 +433,22 @@ function defineFolder (builder: Builder): void {
encode: drive.function.FolderLinkProvider
})

// Search

builder.createDoc(
presentation.class.ObjectSearchCategory,
core.space.Model,
{
title: drive.string.Folders,
icon: drive.icon.Drive,
label: presentation.string.Search,
query: drive.completion.FolderQuery,
context: ['search', 'mention', 'spotlight'],
classToSearch: drive.class.Folder
},
drive.completion.FolderCategory
)

// Actions

builder.mixin(drive.class.Folder, core.class.Class, view.mixin.IgnoreActions, {
Expand Down Expand Up @@ -566,6 +583,22 @@ function defineFile (builder: Builder): void {
components: { input: chunter.component.ChatMessageInput }
})

// Search

builder.createDoc(
presentation.class.ObjectSearchCategory,
core.space.Model,
{
title: drive.string.Files,
icon: drive.icon.Drive,
label: presentation.string.Search,
query: drive.completion.FileQuery,
context: ['search', 'mention', 'spotlight'],
classToSearch: drive.class.File
},
drive.completion.FileCategory
)

// Actions

builder.mixin(drive.class.File, core.class.Class, view.mixin.IgnoreActions, {
Expand Down
9 changes: 9 additions & 0 deletions models/drive/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type { Doc, Ref } from '@hcengineering/core'
import {} from '@hcengineering/core'
import { driveId } from '@hcengineering/drive'
import drive from '@hcengineering/drive-resources/src/plugin'
import { type ObjectSearchCategory, type ObjectSearchFactory } from '@hcengineering/model-presentation'
import { type IntlString, type Resource, mergeIds } from '@hcengineering/platform'
import { type AnyComponent, type Location } from '@hcengineering/ui'
import {
Expand Down Expand Up @@ -55,6 +56,12 @@ export default mergeIds(driveId, drive, {
CanRenameFile: '' as Resource<ViewActionAvailabilityFunction>,
CanRenameFolder: '' as Resource<ViewActionAvailabilityFunction>
},
completion: {
FileQuery: '' as Resource<ObjectSearchFactory>,
FileCategory: '' as Ref<ObjectSearchCategory>,
FolderQuery: '' as Resource<ObjectSearchFactory>,
FolderCategory: '' as Ref<ObjectSearchCategory>
},
viewlet: {
Grid: '' as Ref<ViewletDescriptor>,
DriveTable: '' as Ref<Viewlet>,
Expand Down Expand Up @@ -93,6 +100,8 @@ export default mergeIds(driveId, drive, {
Parent: '' as IntlString,
Path: '' as IntlString,
Drives: '' as IntlString,
Files: '' as IntlString,
Folders: '' as IntlString,
Version: '' as IntlString,
Restore: '' as IntlString
}
Expand Down
14 changes: 14 additions & 0 deletions models/server-drive/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,18 @@ export function createModel (builder: Builder): void {
collectDocs: serverDrive.function.FindFolderResources
}
)

builder.mixin(drive.class.File, core.class.Class, serverCore.mixin.SearchPresenter, {
searchConfig: {
icon: drive.icon.File,
title: 'name'
}
})

builder.mixin(drive.class.Folder, core.class.Class, serverCore.mixin.SearchPresenter, {
searchConfig: {
icon: drive.icon.Folder,
title: 'name'
}
})
}
2 changes: 2 additions & 0 deletions plugins/drive-assets/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Drives": "Drives",
"Grid": "Grid",
"File": "File",
"Files": "Files",
"FileVersion": "File version",
"FileVersions": "File versions",
"Folder": "Folder",
"Folders": "Folders",
"Resource": "Resource",
"Name": "Name",
"Description": "Description",
Expand Down
2 changes: 2 additions & 0 deletions plugins/drive-assets/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Drives": "Unidades",
"Grid": "Red",
"File": "Archivo",
"Files": "Archivos",
"FileVersion": "Versión del archivo",
"FileVersions": "Versiones de archivos",
"Folder": "Carpeta",
"Folders": "Carpetas",
"Resource": "Recurso",
"Name": "Nombre",
"Description": "Descripción",
Expand Down
2 changes: 2 additions & 0 deletions plugins/drive-assets/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Drives": "Disques",
"Grid": "Grille",
"File": "Fichier",
"Files": "Fichiers",
"FileVersion": "Version du fichier",
"FileVersions": "Versions de fichiers",
"Folder": "Dossier",
"Folders": "Dossiers",
"Resource": "Ressource",
"Name": "Nom",
"Description": "Description",
Expand Down
2 changes: 2 additions & 0 deletions plugins/drive-assets/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Drives": "Unidades",
"Grid": "Grade",
"File": "Ficheiro",
"Files": "Ficheiros",
"FileVersion": "Versão do ficheiro",
"FileVersions": "Versões de ficheiro",
"Folder": "Pasta",
"Folders": "Pastas",
"Resource": "Recurso",
"Name": "Nome",
"Description": "Descrição",
Expand Down
2 changes: 2 additions & 0 deletions plugins/drive-assets/lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Drives": "Диски",
"Grid": "Сетка",
"File": "Файл",
"Files": "Файлы",
"FileVersion": "Версия файла",
"FileVersions": "Версии файла",
"Folder": "Папка",
"Folders": "Папки",
"Resource": "Ресурс",
"Name": "Название",
"Description": "Описание",
Expand Down
2 changes: 2 additions & 0 deletions plugins/drive-assets/lang/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
"Drives": "磁盘",
"Grid": "网格",
"File": "文件",
"Files": "文件",
"FileVersion": "檔案版本",
"FileVersions": "檔案版本",
"Folder": "文件夹",
"Folders": "文件夹",
"Resource": "资源",
"Name": "名称",
"Description": "描述",
Expand Down
35 changes: 35 additions & 0 deletions plugins/drive-resources/src/components/FileSearchItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!--
// 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 { WithLookup } from '@hcengineering/core'
import { File } from '@hcengineering/drive'
import { Icon } from '@hcengineering/ui'

import { getFileTypeIcon } from '../utils'

export let value: WithLookup<File>

$: icon = getFileTypeIcon(value.$lookup?.file?.type ?? '')
</script>

<div class="flex-row-center">
<div class="flex-center p-1 content-dark-color flex-no-shrink mr-2-5">
<Icon {icon} size={'medium'} />
</div>
<span class="overflow-label">
{value.name}
</span>
</div>
31 changes: 31 additions & 0 deletions plugins/drive-resources/src/components/FolderSearchItem.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!--
// 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 { WithLookup } from '@hcengineering/core'
import drive, { Folder } from '@hcengineering/drive'
import { Icon } from '@hcengineering/ui'

export let value: WithLookup<Folder>
</script>

<div class="flex-row-center">
<div class="flex-center p-1 content-dark-color flex-no-shrink mr-2-5">
<Icon icon={drive.icon.Folder} size={'medium'} />
</div>
<span class="overflow-label">
{value.name}
</span>
</div>
64 changes: 62 additions & 2 deletions plugins/drive-resources/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
// limitations under the License.
//

import { type Doc, type Ref, type WithLookup } from '@hcengineering/core'
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 CreateDrive from './components/CreateDrive.svelte'
Expand All @@ -27,19 +28,72 @@ import EditFile from './components/EditFile.svelte'
import EditFolder from './components/EditFolder.svelte'
import FilePanel from './components/FilePanel.svelte'
import FilePresenter from './components/FilePresenter.svelte'
import FileSearchItem from './components/FileSearchItem.svelte'
import FileSizePresenter from './components/FileSizePresenter.svelte'
import FileVersionPresenter from './components/FileVersionPresenter.svelte'
import FileVersionVersionPresenter from './components/FileVersionVersionPresenter.svelte'
import FolderPanel from './components/FolderPanel.svelte'
import FolderPresenter from './components/FolderPresenter.svelte'
import FolderSearchItem from './components/FolderSearchItem.svelte'
import GridView from './components/GridView.svelte'
import MoveResource from './components/MoveResource.svelte'
import ResourcePresenter from './components/ResourcePresenter.svelte'

import { getFileUrl } from '@hcengineering/presentation'
import { getDriveLink, getFileLink, getFolderLink, resolveLocation } from './navigation'
import { restoreFileVersion, showCreateFolderPopup, showRenameResourcePopup } from './utils'

const toFileObjectSearchResult = (e: WithLookup<File>): ObjectSearchResult => ({
doc: e,
title: e.name,
icon: drive.icon.File,
component: FileSearchItem
})

const toFolderObjectSearchResult = (e: WithLookup<Folder>): ObjectSearchResult => ({
doc: e,
title: e.name,
icon: drive.icon.Folder,
component: FolderSearchItem
})

async function queryFile (
_class: Ref<Class<File>>,
client: Client,
search: string,
filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }
): Promise<ObjectSearchResult[]> {
const q: DocumentQuery<File> = { name: { $like: `%${search}%` } }
if (filter?.in !== undefined || filter?.nin !== undefined) {
q._id = {}
if (filter.in !== undefined) {
q._id.$in = filter.in?.map((it) => it._id as Ref<File>)
}
if (filter.nin !== undefined) {
q._id.$nin = filter.nin?.map((it) => it._id as Ref<File>)
}
}
return (await client.findAll(_class, q, { limit: 200 })).map(toFileObjectSearchResult)
}

async function queryFolder (
_class: Ref<Class<Folder>>,
client: Client,
search: string,
filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }
): Promise<ObjectSearchResult[]> {
const q: DocumentQuery<Folder> = { name: { $like: `%${search}%` } }
if (filter?.in !== undefined || filter?.nin !== undefined) {
q._id = {}
if (filter.in !== undefined) {
q._id.$in = filter.in?.map((it) => it._id as Ref<Folder>)
}
if (filter.nin !== undefined) {
q._id.$nin = filter.nin?.map((it) => it._id as Ref<Folder>)
}
}
return (await client.findAll(_class, q, { limit: 200 })).map(toFolderObjectSearchResult)
}

async function CreateRootFolder (doc: Drive): Promise<void> {
await showCreateFolderPopup(doc._id, drive.ids.Root)
}
Expand Down Expand Up @@ -135,6 +189,12 @@ export default async (): Promise<Resources> => ({
RenameFolder,
RestoreFileVersion
},
completion: {
FileQuery: async (client: Client, query: string, filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }) =>
await queryFile(drive.class.File, client, query, filter),
FolderQuery: async (client: Client, query: string, filter?: { in?: RelatedDocument[], nin?: RelatedDocument[] }) =>
await queryFolder(drive.class.Folder, client, query, filter)
},
function: {
DriveLinkProvider,
FileLinkProvider,
Expand Down