mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 19:11:33 +03:00
EZQMS-602: Moved Rank
type to core (utilities stay in its own package) (#5019)
This commit is contained in:
parent
23a3c8e94f
commit
b2d3256df0
@ -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 {}
|
||||
|
@ -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,
|
||||
|
@ -34,6 +34,7 @@
|
||||
"CreatedDate": "Created date",
|
||||
"Status": "Status",
|
||||
"StatusCategory": "Status category",
|
||||
"Account": "Account"
|
||||
"Account": "Account",
|
||||
"Rank": "Rank"
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
"CreatedDate": "Fecha de creación",
|
||||
"Status": "Estado",
|
||||
"StatusCategory": "Categoría de estado",
|
||||
"Account": "Cuenta"
|
||||
"Account": "Cuenta",
|
||||
"Rank": "Rango"
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
"CreatedDate": "Data de criação",
|
||||
"Status": "Estado",
|
||||
"StatusCategory": "Categoria de estado",
|
||||
"Account": "Conta"
|
||||
"Account": "Conta",
|
||||
"Rank": "Ranking"
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
"CreatedDate": "Дата создания",
|
||||
"Status": "Статус",
|
||||
"StatusCategory": "Категория статуса",
|
||||
"Account": "Аккаунт"
|
||||
"Account": "Аккаунт",
|
||||
"Rank": "Ранг"
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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>
|
@ -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'
|
||||
|
@ -32,6 +32,7 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/core": "^0.6.28",
|
||||
"lexorank": "~1.0.4"
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
|
@ -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) => {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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}
|
||||
*/
|
||||
|
@ -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>(
|
||||
|
Loading…
Reference in New Issue
Block a user