UBERF-8573 Hide archived teamspaces and drives (#7112)

This commit is contained in:
Alexander Onnikov 2024-11-06 21:01:29 +07:00 committed by GitHub
parent d435a0db5a
commit 5b3f69a85f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 130 additions and 18 deletions

View File

@ -207,7 +207,21 @@ function defineTeamspace (builder: Builder): void {
configOptions: {
hiddenKeys: ['name', 'description']
},
config: ['', 'members', 'private', 'archived']
config: ['', 'members', 'private', 'archived'],
viewOptions: {
groupBy: [],
orderBy: [],
other: [
{
key: 'hideArchived',
type: 'toggle',
defaultValue: true,
actionTarget: 'query',
action: document.function.HideArchivedTeamspaces,
label: view.string.HideArchived
}
]
}
},
document.viewlet.TeamspaceTable
)

View File

@ -21,7 +21,7 @@ import { type ObjectSearchCategory, type ObjectSearchFactory } from '@hcengineer
import { type IntlString, mergeIds, type Resource } from '@hcengineering/platform'
import { type TagCategory } from '@hcengineering/tags'
import { type AnyComponent } from '@hcengineering/ui'
import { type Viewlet, type Action, type ActionCategory, type ViewAction } from '@hcengineering/view'
import type { Viewlet, Action, ActionCategory, ViewAction, ViewQueryAction } from '@hcengineering/view'
export default mergeIds(documentId, document, {
component: {
@ -51,7 +51,8 @@ export default mergeIds(documentId, document, {
},
function: {
CanLockDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
CanUnlockDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>
CanUnlockDocument: '' as Resource<(doc?: Doc | Doc[]) => Promise<boolean>>,
HideArchivedTeamspaces: '' as ViewQueryAction
},
viewlet: {
TeamspaceTable: '' as Ref<Viewlet>

View File

@ -268,7 +268,21 @@ function defineDrive (builder: Builder): void {
configOptions: {
hiddenKeys: ['name', 'description']
},
config: ['', 'members', 'owners', 'private', 'archived']
config: ['', 'members', 'owners', 'private', 'archived'],
viewOptions: {
groupBy: [],
orderBy: [],
other: [
{
key: 'hideArchived',
type: 'toggle',
defaultValue: true,
actionTarget: 'query',
action: drive.function.HideArchivedDrives,
label: view.string.HideArchived
}
]
}
},
drive.viewlet.DriveTable
)

View File

@ -25,6 +25,7 @@ import {
type ActionCategory,
type ViewAction,
type ViewActionAvailabilityFunction,
type ViewQueryAction,
type Viewlet,
type ViewletDescriptor
} from '@hcengineering/view'
@ -54,7 +55,8 @@ export default mergeIds(driveId, drive, {
FolderLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
FileLinkProvider: '' as Resource<(doc: Doc, props: Record<string, any>) => Promise<Location>>,
CanRenameFile: '' as Resource<ViewActionAvailabilityFunction>,
CanRenameFolder: '' as Resource<ViewActionAvailabilityFunction>
CanRenameFolder: '' as Resource<ViewActionAvailabilityFunction>,
HideArchivedDrives: '' as ViewQueryAction
},
completion: {
FileQuery: '' as Resource<ObjectSearchFactory>,

View File

@ -110,7 +110,8 @@ export default mergeIds(viewId, view, {
General: '' as IntlString,
Navigation: '' as IntlString,
Editor: '' as IntlString,
MarkdownFormatting: '' as IntlString
MarkdownFormatting: '' as IntlString,
HideArchived: '' as IntlString
},
function: {
FilterArrayAllResult: '' as FilterFunction,

View File

@ -159,6 +159,10 @@ export async function canUnlockDocument (doc: Document | Document[]): Promise<bo
return arr.some((p) => p.lockedBy != null)
}
export function hideArchivedTeamspaces (value: boolean, query: DocumentQuery<Teamspace>): DocumentQuery<Teamspace> {
return value ? { ...query, archived: false } : query
}
export default async (): Promise<Resources> => ({
component: {
CreateDocument,
@ -196,7 +200,8 @@ export default async (): Promise<Resources> => ({
CanLockDocument: canLockDocument,
CanUnlockDocument: canUnlockDocument,
GetDocumentLinkId: getDocumentLinkId,
ParseDocumentId: parseDocumentId
ParseDocumentId: parseDocumentId,
HideArchivedTeamspaces: hideArchivedTeamspaces
},
resolver: {
Location: resolveLocation

View File

@ -160,6 +160,10 @@ export async function CanRenameFolder (doc: Folder | Folder[] | undefined): Prom
return doc !== undefined && !Array.isArray(doc)
}
export function HideArchivedDrives (value: boolean, query: DocumentQuery<Drive>): DocumentQuery<Drive> {
return value ? { ...query, archived: false } : query
}
export default async (): Promise<Resources> => ({
component: {
CreateDrive,
@ -200,7 +204,8 @@ export default async (): Promise<Resources> => ({
FileLinkProvider,
FolderLinkProvider,
CanRenameFile,
CanRenameFolder
CanRenameFolder,
HideArchivedDrives
},
resolver: {
Location: resolveLocation

View File

@ -125,6 +125,7 @@
"MoreActions": "More actions",
"Leave": "Leave",
"Join": "Join",
"Copied": "Copied"
"Copied": "Copied",
"HideArchived": "Hide archived"
}
}

View File

@ -120,6 +120,7 @@
"MoreActions": "Más Acciones",
"Leave": "Salir",
"Join": "Unirse",
"Copied": "Copiado"
"Copied": "Copiado",
"HideArchived": "Ocultar archivadas"
}
}

View File

@ -120,6 +120,7 @@
"MoreActions": "Plus d'actions",
"Leave": "Quitter",
"Join": "Rejoindre",
"Copied": "Copié"
"Copied": "Copié",
"HideArchived": "Masquer les archives"
}
}

View File

@ -120,6 +120,7 @@
"MoreActions": "Altre azioni",
"Leave": "Esci",
"Join": "Unisciti",
"Copied": "Copiato"
"Copied": "Copiato",
"HideArchived": "Nascondi archiviato"
}
}

View File

@ -120,6 +120,7 @@
"MoreActions": "Mais Ações",
"Leave": "Sair",
"Join": "Ingressar",
"Copied": "Copiado"
"Copied": "Copiado",
"HideArchived": "Ocultar arquivado"
}
}

View File

@ -122,6 +122,7 @@
"MoreActions": "Больше действий",
"Leave": "Покинуть",
"Join": "Присоединиться",
"Copied": "Скопировано"
"Copied": "Скопировано",
"HideArchived": "Скрыть архивные"
}
}

View File

@ -125,6 +125,7 @@
"MoreActions": "更多操作",
"Leave": "离开",
"Join": "加入",
"Copied": "已复制"
"Copied": "已复制",
"HideArchived": "隱藏已存檔"
}
}

View File

@ -14,7 +14,8 @@
-->
<script lang="ts">
import { Class, Doc, DocumentQuery, Ref, Space, WithLookup } from '@hcengineering/core'
import { IntlString, Asset } from '@hcengineering/platform'
import { IntlString, Asset, getResource } from '@hcengineering/platform'
import { getClient } from '@hcengineering/presentation'
import {
AnyComponent,
Button,
@ -28,7 +29,14 @@
Header,
Breadcrumb
} from '@hcengineering/ui'
import { ViewOptions, Viewlet, ViewletDescriptor, ViewletPreference } from '@hcengineering/view'
import {
ViewOptionModel,
ViewOptions,
ViewQueryOption,
Viewlet,
ViewletDescriptor,
ViewletPreference
} from '@hcengineering/view'
import { FilterBar, FilterButton, ViewletSelector, ViewletSettingButton } from '@hcengineering/view-resources'
export let _class: Ref<Class<Doc>>
@ -44,6 +52,9 @@
export let baseQuery: DocumentQuery<Doc> | undefined = undefined
export let modes: IModeSelector<any> | undefined = undefined
const client = getClient()
const hierarchy = client.getHierarchy()
let search = ''
let viewlet: WithLookup<Viewlet> | undefined
let filterVisible: boolean = false
@ -52,10 +63,45 @@
let viewlets: Array<WithLookup<Viewlet>> = []
let viewOptions: ViewOptions | undefined
$: query = { ...(baseQuery ?? {}), ...(viewlet?.baseQuery ?? {}) }
$: _baseQuery = { ...(baseQuery ?? {}), ...(viewlet?.baseQuery ?? {}) }
$: query = { ..._baseQuery }
$: searchQuery = search === '' ? query : { ...query, $search: search }
$: resultQuery = searchQuery
$: void updateQuery(_baseQuery, viewOptions, viewlet)
async function updateQuery (
initialQuery: DocumentQuery<Doc>,
viewOptions: ViewOptions | undefined,
viewlet: Viewlet | undefined
): Promise<void> {
query =
viewOptions !== undefined && viewlet !== undefined
? await getViewQuery(initialQuery, viewOptions, viewlet.viewOptions?.other)
: initialQuery
}
async function getViewQuery (
query: DocumentQuery<Doc>,
viewOptions: ViewOptions,
viewOptionsModel: ViewOptionModel[] | undefined
): Promise<DocumentQuery<Doc>> {
if (viewOptionsModel === undefined) return query
let result: DocumentQuery<Doc> = hierarchy.clone(query)
for (const viewOption of viewOptionsModel) {
if (viewOption.actionTarget !== 'query') continue
const queryOption = viewOption as ViewQueryOption
const f = await getResource(queryOption.action)
const resultP = f(viewOptions[queryOption.key] ?? queryOption.defaultValue, result)
if (resultP instanceof Promise) {
result = await resultP
} else {
result = resultP
}
}
return result
}
function showCreateDialog (): void {
if (createComponent === undefined) return
showPopup(createComponent, createComponentProps, 'top')

View File

@ -53,6 +53,7 @@ test.describe('Drive tests', () => {
})
test('Archive/unarchive drive, check drive archive status', async () => {
await drivesPage.disableHideArchived()
await drivesPage.archiveDrive(drive)
await drivesPage.checkIsArchived(drive)
await drivesPage.unarchiveDrive(drive)

View File

@ -10,6 +10,12 @@ export class DrivesPage extends CommonPage {
this.page = page
}
readonly buttonView = (): Locator =>
this.page.locator('div.hulyHeader-container > .hulyHeader-buttonsGroup.before button[data-id="btn-viewOptions"]')
readonly buttonHideArchived = (): Locator => this.page.locator('div.popup .toggle span.toggle-switch')
readonly inputHideArchived = (): Locator => this.page.locator('div.popup .toggle input[type="checkbox"]')
readonly cellDriveName = (driveName: string): Locator => this.page.getByRole('cell', { name: driveName }).first()
readonly buttonContextMenu = (buttonText: ButtonDrivesContextMenu): Locator =>
@ -65,6 +71,16 @@ export class DrivesPage extends CommonPage {
await this.popupArchive().waitFor({ state: 'detached' })
}
async disableHideArchived (): Promise<void> {
await this.buttonView().click()
await expect(this.buttonHideArchived()).toBeVisible()
if (await this.inputHideArchived().isChecked()) {
await this.buttonHideArchived().click()
await expect(this.inputHideArchived()).not.toBeChecked()
}
await this.page.keyboard.press('Escape')
}
async checkIsArchived (drive: Drive): Promise<void> {
await expect(this.cellArchiveStatusYes(drive.name)).toBeVisible()
}