Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2026-03-10 10:24:21 +07:00
committed by GitHub
parent 24bdc18b92
commit eb3317b1fd
18 changed files with 166 additions and 16 deletions
+4 -1
View File
@@ -17522,6 +17522,9 @@ importers:
'@hcengineering/text-markdown':
specifier: workspace:^0.7.20
version: link:../../foundations/core/packages/text-markdown
'@hcengineering/time':
specifier: workspace:^0.7.0
version: link:../time
'@hcengineering/ui':
specifier: workspace:^0.7.0
version: link:../../packages/ui
@@ -61380,7 +61383,7 @@ snapshots:
node-loader@2.0.0(webpack@5.102.1):
dependencies:
loader-utils: 2.0.4
webpack: 5.102.1(esbuild@0.25.12)(webpack-cli@5.1.4)
webpack: 5.102.1
node-localstorage@2.2.1:
dependencies:
+15
View File
@@ -568,6 +568,21 @@ export function createModel (builder: Builder): void {
locationDataResolver: card.resolver.LocationData,
navigatorModel: {
specials: [
{
id: 'my-cards',
label: card.string.MyCards,
icon: card.icon.Card,
component: card.component.MyCards,
componentProps: {
icon: card.icon.Card,
config: [
['assigned', view.string.Assigned, {}],
['created', view.string.Created, {}],
['subscribed', view.string.Subscribed, {}]
]
},
position: 'top'
},
{
id: 'all',
label: card.string.AllCards,
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importovat",
"Export": "Exportovat",
"CardUpdated": "Karta aktualizována",
"CardCreated": "Karta vytvořena"
"CardCreated": "Karta vytvořena",
"MyCards": "Moje karty",
"GotoMyCards": "Přejít na moje karty"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importieren",
"Export": "Exportieren",
"CardUpdated": "Karte aktualisiert",
"CardCreated": "Karte erstellt"
"CardCreated": "Karte erstellt",
"MyCards": "Meine Karten",
"GotoMyCards": "Zu meinen Karten"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Import",
"Export": "Export",
"CardUpdated": "Card updated",
"CardCreated": "Card created"
"CardCreated": "Card created",
"MyCards": "My cards",
"GotoMyCards": "Go to my cards"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importar",
"Export": "Exportar",
"CardUpdated": "Tarjeta actualizada",
"CardCreated": "Tarjeta creada"
"CardCreated": "Tarjeta creada",
"MyCards": "Mis tarjetas",
"GotoMyCards": "Ir a mis tarjetas"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importer",
"Export": "Exporter",
"CardUpdated": "Carte mise à jour",
"CardCreated": "Carte créée"
"CardCreated": "Carte créée",
"MyCards": "Mes cartes",
"GotoMyCards": "Aller à mes cartes"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importa",
"Export": "Esporta",
"CardUpdated": "Scheda aggiornata",
"CardCreated": "Scheda creata"
"CardCreated": "Scheda creata",
"MyCards": "Le mie carte",
"GotoMyCards": "Vai alle mie carte"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "インポート",
"Export": "エクスポート",
"CardUpdated": "カードが更新されました",
"CardCreated": "カードが作成されました"
"CardCreated": "カードが作成されました",
"MyCards": "マイカード",
"GotoMyCards": "マイカードへ移動"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importar",
"Export": "Exportar",
"CardUpdated": "Cartão atualizado",
"CardCreated": "Cartão criado"
"CardCreated": "Cartão criado",
"MyCards": "Meus cartões",
"GotoMyCards": "Ir para meus cartões"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Importar",
"Export": "Exportar",
"CardUpdated": "Cartão atualizado",
"CardCreated": "Cartão criado"
"CardCreated": "Cartão criado",
"MyCards": "Meus cartões",
"GotoMyCards": "Ir para meus cartões"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "Импортировать",
"Export": "Экспортировать",
"CardUpdated": "Карточка обновлена",
"CardCreated": "Карточка создана"
"CardCreated": "Карточка создана",
"MyCards": "Мои карты",
"GotoMyCards": "Перейти к моим картам"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "İçe aktar",
"Export": "Dışa aktar",
"CardUpdated": "Kart güncellendi",
"CardCreated": "Kart oluşturuldu"
"CardCreated": "Kart oluşturuldu",
"MyCards": "Benim kartlarım",
"GotoMyCards": "Benim kartlarıma git"
}
}
+3 -1
View File
@@ -72,6 +72,8 @@
"Import": "导入",
"Export": "导出",
"CardUpdated": "卡片已更新",
"CardCreated": "卡片已创建"
"CardCreated": "卡片已创建",
"MyCards": "我的卡片",
"GotoMyCards": "转到我的卡片"
}
}
+1
View File
@@ -70,6 +70,7 @@
"@hcengineering/converter": "workspace:^0.7.0",
"@hcengineering/converter-resources": "workspace:^0.7.0",
"@hcengineering/notification": "workspace:^0.7.0",
"@hcengineering/time": "workspace:^0.7.0",
"@hcengineering/contact": "workspace:^0.7.0",
"@hcengineering/workbench": "workspace:^0.7.0",
"@tiptap/core": "^2.11.7",
@@ -0,0 +1,102 @@
<!--
// Copyright © 2025 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 { Card } from '@hcengineering/card'
import core, { DocumentQuery, getCurrentAccount, QuerySelector, Ref } from '@hcengineering/core'
import { type Asset, type IntlString } from '@hcengineering/platform'
import { createQuery, getClient } from '@hcengineering/presentation'
import { IModeSelector, resolvedLocationStore } from '@hcengineering/ui'
import { SpecialView } from '@hcengineering/workbench-resources'
import { createEventDispatcher } from 'svelte'
import { getCurrentEmployee } from '@hcengineering/contact'
import time, { ToDo } from '@hcengineering/time'
import card from '../../plugin'
export let config: [string, IntlString, object][] = []
export let icon: Asset | undefined = undefined
const client = getClient()
const hierarchy = client.getHierarchy()
const socialIds = getCurrentAccount().socialIds
const acc = getCurrentAccount().uuid
const dispatch = createEventDispatcher()
const user = getCurrentEmployee()
let assigned: DocumentQuery<Card> = { _id: { $in: [] as Ref<Card>[] } }
const created = { createdBy: { $in: socialIds } }
let subscribed: DocumentQuery<Card> = { _id: { $in: [] as Ref<Card>[] } }
let query: DocumentQuery<Card> = {}
let modeSelectorProps: IModeSelector | undefined = undefined
let mode: string | undefined = undefined
const todoQuery = createQuery()
$: todoQuery.query(time.class.ToDo, { user, doneOn: null }, (todos: ToDo[]) => {
console.log('todos', todos)
const cardIds = todos
.filter((todo) => hierarchy.isDerived(todo.attachedToClass, card.class.Card))
.map((todo) => todo.attachedTo as Ref<Card>)
console.log('cardIds', cardIds)
const uniqueIds = [...new Set(cardIds)]
const curIds: Ref<Card>[] = (assigned._id as QuerySelector<Ref<Card>>)?.$in ?? []
if (curIds.length !== uniqueIds.length || curIds.some((id, i) => uniqueIds[i] !== id)) {
assigned = { _id: { $in: uniqueIds } }
}
})
const subscribedQuery = createQuery()
$: subscribedQuery.query(
core.class.Collaborator,
{ collaborator: acc, attachedToClass: { $in: hierarchy.getDescendants(card.class.Card) } },
(collaborators) => {
const newSub = collaborators.map((it) => it.attachedTo as Ref<Card>)
const curSub: Ref<Card>[] = (subscribed._id as QuerySelector<Ref<Card>>)?.$in ?? []
if (curSub.length !== newSub.length || curSub.some((id, i) => newSub[i] !== id)) {
subscribed = { _id: { $in: newSub } }
}
}
)
$: queries = { assigned, created, subscribed }
$: mode = $resolvedLocationStore.query?.mode ?? undefined
$: if (mode === undefined || (queries as any)[mode] === undefined) {
if (config.length > 0) {
;[[mode]] = config
}
}
$: if (mode !== undefined) {
query = { ...(queries as any)[mode] }
modeSelectorProps = {
config,
mode,
onChange: (newMode: string) => dispatch('action', { mode: newMode })
}
}
</script>
{#if query !== undefined && modeSelectorProps !== undefined}
<SpecialView
_class={card.class.Card}
baseQuery={query}
space={undefined}
label={card.string.MyCards}
{icon}
modes={modeSelectorProps}
/>
{/if}
+3 -1
View File
@@ -64,6 +64,7 @@ import CreateRolePopup from './components/settings/CreateRolePopup.svelte'
import CardWidget from './components/CardWidget.svelte'
import CreateSpace from './components/navigator/CreateSpace.svelte'
import CardHeaderButton from './components/navigator/CardHeaderButton.svelte'
import MyCards from './components/navigator/MyCards.svelte'
// Card Sections
import AttachmentsCardSection from './components/sections/AttachmentsSection.svelte'
@@ -134,7 +135,8 @@ export default async (): Promise<Resources> => ({
CardFeedView,
CreateSpace,
CardHeaderButton,
CreateRolePopup
CreateRolePopup,
MyCards
},
sectionComponent: {
AttachmentsSection: AttachmentsCardSection,
+5 -2
View File
@@ -55,7 +55,8 @@ export default mergeIds(cardId, card, {
CardWidgetTab: '' as AnyComponent,
CreateCard: '' as AnyComponent,
CardHeaderButton: '' as AnyComponent,
CreateRolePopup: '' as AnyComponent
CreateRolePopup: '' as AnyComponent,
MyCards: '' as AnyComponent
},
function: {
CardFactory: '' as Resource<(props?: Record<string, any>) => Promise<Ref<Doc> | undefined>>,
@@ -161,6 +162,8 @@ export default mergeIds(cardId, card, {
ForbidAddTagPermission: '' as IntlString,
ForbidRemoveTag: '' as IntlString,
CardUpdated: '' as IntlString,
CardCreated: '' as IntlString
CardCreated: '' as IntlString,
MyCards: '' as IntlString,
GotoMyCards: '' as IntlString
}
})