EZQMS-602: Moved Rank type to core (utilities stay in its own package) (#5019)

This commit is contained in:
Pete Anøther 2024-03-19 23:39:30 -03:00 committed by GitHub
parent 23a3c8e94f
commit b2d3256df0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 49 additions and 170 deletions

View File

@ -363,3 +363,7 @@ export class TTypeCollaborativeDoc extends TType {}
@UX(core.string.CollaborativeDocVersion)
@Model(core.class.TypeCollaborativeDocVersion, core.class.Type)
export class TTypeCollaborativeDocVersion extends TType {}
@UX(core.string.Rank)
@Model(core.class.TypeRank, core.class.Type)
export class TTypeRank extends TType {}

View File

@ -60,6 +60,7 @@ import {
TTypeIntlString,
TTypeMarkup,
TTypeNumber,
TTypeRank,
TTypeRecord,
TTypeRelatedDocument,
TTypeString,
@ -122,6 +123,7 @@ export function createModel (builder: Builder): void {
TTypeNumber,
TTypeBoolean,
TTypeString,
TTypeRank,
TTypeRecord,
TTypeAttachment,
TTypeHyperlink,

View File

@ -34,6 +34,7 @@
"CreatedDate": "Created date",
"Status": "Status",
"StatusCategory": "Status category",
"Account": "Account"
"Account": "Account",
"Rank": "Rank"
}
}

View File

@ -34,6 +34,7 @@
"CreatedDate": "Fecha de creación",
"Status": "Estado",
"StatusCategory": "Categoría de estado",
"Account": "Cuenta"
"Account": "Cuenta",
"Rank": "Rango"
}
}

View File

@ -34,6 +34,7 @@
"CreatedDate": "Data de criação",
"Status": "Estado",
"StatusCategory": "Categoria de estado",
"Account": "Conta"
"Account": "Conta",
"Rank": "Ranking"
}
}

View File

@ -34,6 +34,7 @@
"CreatedDate": "Дата создания",
"Status": "Статус",
"StatusCategory": "Категория статуса",
"Account": "Аккаунт"
"Account": "Аккаунт",
"Rank": "Ранг"
}
}

View File

@ -46,6 +46,13 @@ export type Hyperlink = string
*/
export type CollectionSize<T> = T[]['length']
/**
* @public
*
* String representation of {@link https://www.npmjs.com/package/lexorank LexoRank} type
*/
export type Rank = string
/**
* @public
*/

View File

@ -14,7 +14,7 @@
//
import type { IntlString, Plugin, StatusCode } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import { Mixin, Version } from '.'
import { Mixin, type Rank, Version } from '.'
import type {
Account,
AnyAttribute,
@ -101,6 +101,7 @@ export default plugin(coreId, {
TypeHyperlink: '' as Ref<Class<Type<Hyperlink>>>,
TypeNumber: '' as Ref<Class<Type<number>>>,
TypeMarkup: '' as Ref<Class<Type<string>>>,
TypeRank: '' as Ref<Class<Type<Rank>>>,
TypeRecord: '' as Ref<Class<Type<Record<any, any>>>>,
TypeBoolean: '' as Ref<Class<Type<boolean>>>,
TypeTimestamp: '' as Ref<Class<Type<Timestamp>>>,
@ -187,6 +188,7 @@ export default plugin(coreId, {
CreatedDate: '' as IntlString,
Status: '' as IntlString,
Account: '' as IntlString,
StatusCategory: '' as IntlString
StatusCategory: '' as IntlString,
Rank: '' as IntlString
}
})

View File

@ -20,6 +20,7 @@
DocumentQuery,
DocumentUpdate,
FindOptions,
type Rank,
RateLimiter,
Ref,
Space
@ -99,7 +100,7 @@
const client = getClient()
let dragCard: Item | undefined
let dragCardInitialRank: string | undefined
let dragCardInitialRank: Rank | undefined
let dragCardInitialState: CategoryType
let dragCardInitialPosition: number | undefined
let dragCardState: CategoryType | undefined

View File

@ -1,6 +1,5 @@
import { type Doc } from '@hcengineering/core'
import { type Doc, type Rank } from '@hcengineering/core'
import { type Asset } from '@hcengineering/platform'
import type { Rank } from '@hcengineering/rank'
/**
* @public

View File

@ -35,6 +35,7 @@ import core, {
MixinUpdate,
Obj,
PropertyType,
Rank,
Ref,
RefTo,
Space,
@ -501,3 +502,10 @@ export function TypeCollaborativeDoc (): Type<CollaborativeDoc> {
export function TypeCollaborativeDocVersion (): Type<CollaborativeDoc> {
return { _class: core.class.TypeCollaborativeDocVersion, label: core.string.CollaborativeDocVersion }
}
/**
* @public
*/
export function TypeRank (): Type<Rank> {
return { _class: core.class.TypeRank, label: core.string.Rank }
}

View File

@ -1,145 +0,0 @@
<!--
// Copyright © 2022 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 { flip } from 'svelte/animate'
import { Doc, DocData, Ref } from '@hcengineering/core'
import { IconMoreV } from '@hcengineering/ui'
import { getClient } from '../utils'
type DocWithRank = Doc & { rank: string }
type DraftDoc = DocData<Doc> & { _id: Ref<Doc> }
type DraftDocWithRank = DocData<DocWithRank> & { _id: Ref<Doc> }
type ListType = Doc[] | DocWithRank[] | DraftDoc[] | DraftDocWithRank[]
export let objects: ListType
export let handleMove: ((fromIndex: number, toIndex: number) => void) | undefined = undefined
export let calcRank: (doc: DocWithRank, next: DocWithRank) => string
export let showContextMenu: ((evt: MouseEvent, doc: Doc) => void) | undefined = undefined
export let isDraft = false
export let editable = true
const client = getClient()
let draggingIndex: number | null = null
let hoveringIndex: number | null = null
let dragOverIndex: number = -1
function resetDrag () {
draggingIndex = null
hoveringIndex = null
dragOverIndex = -1
}
function handleDragStart (ev: DragEvent, index: number) {
if (ev.dataTransfer) {
ev.dataTransfer.effectAllowed = 'move'
ev.dataTransfer.dropEffect = 'move'
draggingIndex = index
}
}
function checkHasRank (objects: ListType): objects is DocWithRank[] {
return 'rank' in objects[0]
}
function checkIsNotDraft (object: Doc | DocWithRank | DraftDoc | DraftDocWithRank): object is Doc | DocWithRank {
return !('_class' in object) && !isDraft
}
async function handleDrop (ev: DragEvent, toIndex: number) {
if (ev.dataTransfer && draggingIndex !== null && toIndex !== draggingIndex) {
ev.dataTransfer.dropEffect = 'move'
if (handleMove) {
handleMove(draggingIndex, toIndex)
return
}
if (!checkHasRank(objects)) {
return
}
const [prev, next] = [
objects[draggingIndex < toIndex ? toIndex : toIndex - 1],
objects[draggingIndex < toIndex ? toIndex + 1 : toIndex]
]
const object = objects[draggingIndex]
const newRank = calcRank(prev, next)
if (isDraft) {
object.rank = newRank
} else {
await client.update(object, { rank: newRank })
}
}
resetDrag()
}
</script>
<div class="antiAccordion">
{#each objects as object, index (object._id)}
<div class="description pb-1" animate:flip={{ duration: 400 }}>
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class:is-dragging={index === draggingIndex}
class:is-dragged-over-up={draggingIndex !== null && index < draggingIndex && index === hoveringIndex}
class:is-dragged-over-down={draggingIndex !== null && index > draggingIndex && index === hoveringIndex}
class:drag-over-highlight={index === dragOverIndex}
draggable={editable}
on:contextmenu={(ev) => checkIsNotDraft(object) && showContextMenu?.(ev, object)}
on:dragstart={(ev) => {
handleDragStart(ev, index)
}}
on:dragover|preventDefault={() => {
dragOverIndex = index
return false
}}
on:dragenter={() => (hoveringIndex = index)}
on:drop|preventDefault={(ev) => handleDrop(ev, index)}
on:dragend={resetDrag}
>
<div class="draggable-container">
<div class="caption mb-0 flex flex-grow flex-row-center">
<div class="draggable-mark fs-title content-dark-color whitespace-nowrap mr-2">
<IconMoreV size={'small'} />
</div>
<div class="fs-title content-dark-color whitespace-nowrap mr-2">
{`${index + 1}.`}
</div>
<slot name="object" {index} />
</div>
<slot name="object-footer" {index} />
</div>
</div>
</div>
{/each}
</div>
<style lang="scss">
.drag-over-highlight {
opacity: 0.2;
}
.description {
.draggable-container {
cursor: grabbing;
}
&:hover {
.draggable-mark {
opacity: 0.4;
}
}
}
</style>

View File

@ -36,7 +36,6 @@ export { default as SpacesMultiPopup } from './components/SpacesMultiPopup.svelt
export { default as ObjectSearchPopup } from './components/ObjectSearchPopup.svelte'
export { default as IndexedDocumentPreview } from './components/IndexedDocumentPreview.svelte'
export { default as IndexedDocumentCompare } from './components/IndexedDocumentCompare.svelte'
export { default as DraggableList } from './components/DraggableList.svelte'
export { default as NavLink } from './components/NavLink.svelte'
export { default as IconForward } from './components/icons/Forward.svelte'
export { default as Breadcrumbs } from './components/breadcrumbs/Breadcrumbs.svelte'

View File

@ -32,6 +32,7 @@
"typescript": "^5.3.3"
},
"dependencies": {
"@hcengineering/core": "^0.6.28",
"lexorank": "~1.0.4"
}
}

View File

@ -13,9 +13,4 @@
// limitations under the License.
//
/**
* @public
*
* String representation of {@link https://www.npmjs.com/package/lexorank LexoRank} type
*/
export type Rank = string
export { type Rank } from '@hcengineering/core'

View File

@ -76,14 +76,14 @@
const selection = listProvider.selection
let resultQuery: DocumentQuery<DocWithRank>
let resultQuery: DocumentQuery<Card>
$: resultQuery = { ...query, isArchived: { $nin: [true] }, space }
const cardQuery = createQuery()
let cards: DocWithRank[] = []
let cards: Card[] = []
$: cardQuery.query<DocWithRank>(
$: cardQuery.query<Card>(
_class,
getCategoryQueryNoLookup(resultQuery),
(result) => {

View File

@ -20,6 +20,7 @@ import {
Class,
Doc,
Mixin,
type Rank,
Ref,
Space,
Status,
@ -29,7 +30,6 @@ import {
import { NotificationType } from '@hcengineering/notification'
import type { Asset, IntlString, Plugin, Resource } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform'
import type { Rank } from '@hcengineering/rank'
import type { AnyComponent, ComponentExtensionId } from '@hcengineering/ui'
import { Action, IconProps, ViewletDescriptor } from '@hcengineering/view'
@ -48,7 +48,7 @@ export interface Project extends Space {
/**
* @public
*/
export interface Task extends AttachedDoc, DocWithRank {
export interface Task extends AttachedDoc {
kind: Ref<TaskType>
status: Ref<Status>
isDone?: boolean
@ -59,6 +59,7 @@ export interface Task extends AttachedDoc, DocWithRank {
attachments?: number
labels?: number
identifier: string
rank: Rank
}
/**

View File

@ -26,16 +26,17 @@ import core, {
TxOperations,
generateId,
type AnyAttribute,
type Rank,
type RefTo
} from '@hcengineering/core'
import { PlatformError, getEmbeddedLabel, unknownStatus } from '@hcengineering/platform'
import task, { Project, ProjectStatus, ProjectType, Task, TaskType } from '.'
import { makeRank, type Rank } from '@hcengineering/rank'
import { makeRank } from '@hcengineering/rank'
export { genRanks, makeRank } from '@hcengineering/rank'
/**
* @public
* @deprecated Prefer {@link makeRank}
*
* TODO: Drop after everything migrates to {@link makeRank}
*/

View File

@ -13,7 +13,7 @@
// limitations under the License.
-->
<script lang="ts">
import core, { AttachedData, FindOptions, Ref, SortingOrder } from '@hcengineering/core'
import core, { AttachedData, FindOptions, type Rank, Ref, SortingOrder } from '@hcengineering/core'
import { ObjectPopup, getClient } from '@hcengineering/presentation'
import { makeRank } from '@hcengineering/task'
import { Issue, IssueDraft } from '@hcengineering/tracker'
@ -42,7 +42,7 @@
parentIssue?._id !== docValue.attachedTo &&
parentIssue?._id !== docValue._id
) {
let rank: string | null = null
let rank: Rank | null = null
if (parentIssue) {
const lastAttachedIssue = await client.findOne<Issue>(