mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-27 20:14:57 +02:00
Merge branch 'develop' of https://github.com/hcengineering/platform into staging-new
Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
@@ -41,7 +41,7 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
- uses: pnpm/action-setup@v5
|
||||
with:
|
||||
version: latest
|
||||
version: 10
|
||||
- name: Docker build
|
||||
run: |
|
||||
cd ./dev/base-image
|
||||
|
||||
@@ -672,7 +672,7 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
- uses: pnpm/action-setup@v5
|
||||
with:
|
||||
version: latest
|
||||
version: 10
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v5
|
||||
env:
|
||||
|
||||
@@ -668,6 +668,7 @@ export interface Version extends Doc {
|
||||
export interface MigrationState extends Doc {
|
||||
plugin: string
|
||||
state: string
|
||||
durationMs?: number
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -176,22 +176,28 @@ export async function tryMigrate (
|
||||
const states = client.migrateState.get(plugin) ?? new Set()
|
||||
for (const migration of migrations) {
|
||||
if (states.has(migration.state)) continue
|
||||
if (migration.mode == null || migration.mode === mode) {
|
||||
try {
|
||||
client.logger.log('running migration', { plugin, state: migration.state })
|
||||
await migration.func(client, mode)
|
||||
} catch (err: any) {
|
||||
client.logger.error('Failed to run migration', { plugin, state: migration.state, err })
|
||||
Analytics.handleError(err)
|
||||
continue
|
||||
}
|
||||
// Do not persist MigrationState when this migration is not applicable to the
|
||||
// current mode — otherwise it would be skipped forever on the correct mode.
|
||||
if (migration.mode != null && migration.mode !== mode) {
|
||||
continue
|
||||
}
|
||||
const startedAt = Date.now()
|
||||
try {
|
||||
client.logger.log('running migration', { plugin, state: migration.state })
|
||||
await migration.func(client, mode)
|
||||
} catch (err: any) {
|
||||
client.logger.error('Failed to run migration', { plugin, state: migration.state, err })
|
||||
Analytics.handleError(err)
|
||||
continue
|
||||
}
|
||||
const finishedAt = Date.now()
|
||||
const st: MigrationState = {
|
||||
plugin,
|
||||
state: migration.state,
|
||||
durationMs: finishedAt - startedAt,
|
||||
space: core.space.Configuration,
|
||||
modifiedBy: core.account.System,
|
||||
modifiedOn: Date.now(),
|
||||
modifiedOn: finishedAt,
|
||||
_class: core.class.MigrationState,
|
||||
_id: generateId()
|
||||
}
|
||||
@@ -212,19 +218,23 @@ export async function tryUpgrade (
|
||||
const states = state.get(plugin) ?? new Set()
|
||||
for (const upgrades of migrations) {
|
||||
if (states.has(upgrades.state)) continue
|
||||
const _client = await client()
|
||||
if (upgrades.mode == null || upgrades.mode === mode) {
|
||||
try {
|
||||
await upgrades.func(_client, mode)
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
Analytics.handleError(err)
|
||||
continue
|
||||
}
|
||||
if (upgrades.mode != null && upgrades.mode !== mode) {
|
||||
continue
|
||||
}
|
||||
const _client = await client()
|
||||
const startedAt = Date.now()
|
||||
try {
|
||||
await upgrades.func(_client, mode)
|
||||
} catch (err: any) {
|
||||
console.error(err)
|
||||
Analytics.handleError(err)
|
||||
continue
|
||||
}
|
||||
const finishedAt = Date.now()
|
||||
const st: Data<MigrationState> = {
|
||||
plugin,
|
||||
state: upgrades.state
|
||||
state: upgrades.state,
|
||||
durationMs: finishedAt - startedAt
|
||||
}
|
||||
const tx = new TxOperations(_client, core.account.System)
|
||||
await tx.createDoc(core.class.MigrationState, core.space.Configuration, st)
|
||||
|
||||
@@ -1153,18 +1153,6 @@ function defineTabs (builder: Builder): void {
|
||||
card.section.Properties
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
card.class.CardSection,
|
||||
core.space.Model,
|
||||
{
|
||||
label: card.string.RichtextProperties,
|
||||
component: card.sectionComponent.MarkupPropertiesSection,
|
||||
order: 150,
|
||||
navigation: []
|
||||
},
|
||||
card.section.MarkupProperties
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
card.class.CardSection,
|
||||
core.space.Model,
|
||||
|
||||
@@ -358,6 +358,7 @@ export class TVersion extends TDoc implements Version {
|
||||
export class TMigrationState extends TDoc implements MigrationState {
|
||||
plugin!: string
|
||||
state!: string
|
||||
durationMs?: number
|
||||
}
|
||||
|
||||
@Model(core.class.PluginConfiguration, core.class.Doc, DOMAIN_MODEL)
|
||||
|
||||
@@ -550,7 +550,7 @@ export function createModel (builder: Builder): void {
|
||||
{
|
||||
key: 'showDone',
|
||||
type: 'toggle',
|
||||
defaultValue: true,
|
||||
defaultValue: false,
|
||||
actionTarget: 'query',
|
||||
action: process.function.ShowDoneQuery,
|
||||
label: process.string.ShowDone
|
||||
|
||||
@@ -63,14 +63,9 @@
|
||||
</script>
|
||||
|
||||
{#each keys as key}
|
||||
<div class="px-4 w-full">
|
||||
<div class="w-full mt-2">
|
||||
<span>
|
||||
<Label label={key.attr.label} />
|
||||
{#if tag}
|
||||
<span class="text-xs">
|
||||
(<Label label={tag.label} />)
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
<MarkupEditor
|
||||
value={getValue(doc, key.key)}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
import Lock from './icons/Lock.svelte'
|
||||
import Unlock from './icons/Unlock.svelte'
|
||||
import card from '../plugin'
|
||||
import MarkupProperties from './MarkupProperties.svelte'
|
||||
|
||||
export let value: Card
|
||||
export let readonly: boolean = false
|
||||
@@ -115,6 +116,7 @@
|
||||
</div>
|
||||
<ExpandCollapse isExpanded={!isCollapsed}>
|
||||
<CardAttributes object={value} _class={value._class} {readonly} {ignoreKeys} {fourRows} showCollaborators />
|
||||
<MarkupProperties doc={value} {readonly} tag={undefined} />
|
||||
</ExpandCollapse>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
import Lock from './icons/Lock.svelte'
|
||||
import Unlock from './icons/Unlock.svelte'
|
||||
import card from '../plugin'
|
||||
import MarkupProperties from './MarkupProperties.svelte'
|
||||
|
||||
export let value: Card
|
||||
export let tag: Tag
|
||||
@@ -126,6 +127,7 @@
|
||||
</div>
|
||||
<ExpandCollapse isExpanded={!isCollapsed}>
|
||||
<CardAttributes object={value} _class={tag._id} to={tag.extends} {readonly} {ignoreKeys} />
|
||||
<MarkupProperties doc={value} {readonly} {tag} />
|
||||
</ExpandCollapse>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
function filterClasses (): [DropdownIntlItem, DropdownIntlItem[]][] {
|
||||
const descendants = hierarchy.getDescendants(parent).filter((p) => p !== card.class.Card)
|
||||
const descendants = hierarchy.getDescendants(parent).filter((p) => p !== parent)
|
||||
const added = new Set<Ref<Class<Doc>>>()
|
||||
const base = new Map<Ref<Class<Doc>>, Class<Doc>[]>()
|
||||
for (const _id of descendants) {
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<!--
|
||||
// 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 { Doc, Mixin } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { getDocMixins } from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import MarkupProperties from '../MarkupProperties.svelte'
|
||||
|
||||
export let readonly: boolean = false
|
||||
export let doc: Card
|
||||
export let hidden: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
const client = getClient()
|
||||
const h = client.getHierarchy()
|
||||
|
||||
let mixins: Array<Mixin<Doc>> = []
|
||||
$: mixins = getDocMixins(doc)
|
||||
onMount(() => {
|
||||
dispatch('loaded')
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if !hidden}
|
||||
<div class="w-full flex flex-col flex-gap-4">
|
||||
<MarkupProperties
|
||||
{doc}
|
||||
readonly={readonly || h.getAncestors(doc._class).some((p) => doc.readonlySections?.includes(p))}
|
||||
tag={undefined}
|
||||
on:update
|
||||
/>
|
||||
{#each mixins as mixin}
|
||||
<MarkupProperties {doc} readonly={readonly || doc.readonlySections?.includes(mixin._id)} tag={mixin} on:update />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -78,7 +78,6 @@ import PropertiesCardSection from './components/sections/PropertiesSection.svelt
|
||||
import RelationsCardSection from './components/sections/RelationsSection.svelte'
|
||||
import CardCommunicatiomMessages from './components/sections/CardCommunicatiomMessages.svelte'
|
||||
import OldMessagesCardSection from './components/sections/OldMessagesCardSection.svelte'
|
||||
import MarkupPropertiesCardSection from './components/sections/MarkupPropertiesSection.svelte'
|
||||
|
||||
import FavoriteCardPresenter from './components/FavoriteCardPresenter.svelte'
|
||||
import CardTagsColored from './components/CardTagsColored.svelte'
|
||||
@@ -151,8 +150,7 @@ export default async (): Promise<Resources> => ({
|
||||
PropertiesSection: PropertiesCardSection,
|
||||
RelationsSection: RelationsCardSection,
|
||||
OldMessagesSection: OldMessagesCardSection,
|
||||
CommunicationMessagesSection: CardCommunicatiomMessages,
|
||||
MarkupPropertiesSection: MarkupPropertiesCardSection
|
||||
CommunicationMessagesSection: CardCommunicatiomMessages
|
||||
},
|
||||
completion: {
|
||||
CardQuery: queryCard
|
||||
|
||||
@@ -83,7 +83,6 @@ export default mergeIds(cardId, card, {
|
||||
ChildrenSection: '' as AnyComponent,
|
||||
ContentSection: '' as AnyComponent,
|
||||
PropertiesSection: '' as AnyComponent,
|
||||
MarkupPropertiesSection: '' as AnyComponent,
|
||||
RelationsSection: '' as AnyComponent,
|
||||
CommunicationMessagesSection: '' as AnyComponent,
|
||||
OldMessagesSection: '' as AnyComponent
|
||||
|
||||
@@ -222,7 +222,6 @@ const cardPlugin = plugin(cardId, {
|
||||
Children: '' as Ref<CardSection>,
|
||||
Content: '' as Ref<CardSection>,
|
||||
Properties: '' as Ref<CardSection>,
|
||||
MarkupProperties: '' as Ref<CardSection>,
|
||||
Relations: '' as Ref<CardSection>,
|
||||
OldMessages: '' as Ref<CardSection>,
|
||||
CommunicationMessages: '' as Ref<CardSection>
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Card } from '@hcengineering/card'
|
||||
import { PermissionsStore } from '@hcengineering/contact'
|
||||
import { checkMyPermission, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import core, { Doc, FindOptions, Ref, SortingOrder, TypedSpace } from '@hcengineering/core'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import { Execution } from '@hcengineering/process'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Execution, Process } from '@hcengineering/process'
|
||||
import {
|
||||
Button,
|
||||
eventToHTMLElement,
|
||||
@@ -35,11 +37,9 @@
|
||||
SelectDirection,
|
||||
ViewletsSettingButton
|
||||
} from '@hcengineering/view-resources'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import process from '../plugin'
|
||||
import RunProcessPopup from './RunProcessPopup.svelte'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { checkMyPermission, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { PermissionsStore } from '@hcengineering/contact'
|
||||
|
||||
export let card: Card
|
||||
export let readonly: boolean = false
|
||||
@@ -47,8 +47,18 @@
|
||||
const viewletId = process.viewlet.CardExecutions
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const client = getClient()
|
||||
|
||||
const autoProcesses = client
|
||||
.getModel()
|
||||
.findAllSync(process.class.Process, {
|
||||
automationOnly: true
|
||||
})
|
||||
.map((p: Process) => p._id)
|
||||
|
||||
$: query = {
|
||||
card: card._id
|
||||
card: card._id,
|
||||
process: { $nin: autoProcesses }
|
||||
}
|
||||
|
||||
const options: FindOptions<Execution> = {
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
{process}
|
||||
{attribute}
|
||||
{context}
|
||||
allowArray
|
||||
masterTag={process.masterTag}
|
||||
editor={undefined}
|
||||
presenterClass={{
|
||||
|
||||
@@ -959,6 +959,9 @@ export function getMockAttribute (_class: Ref<Class<Doc>>, label: IntlString, ty
|
||||
export async function checkProcessSectionVisibility (doc: Card): Promise<boolean> {
|
||||
const client = getClient()
|
||||
const anc = client.getHierarchy().getAncestors(doc._class)
|
||||
const processes = client.getModel().findAllSync(process.class.Process, { masterTag: { $in: anc } })
|
||||
const processes = client.getModel().findAllSync(process.class.Process, {
|
||||
masterTag: { $in: anc },
|
||||
automationOnly: { $ne: true }
|
||||
})
|
||||
return processes.length > 0
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
{:else if value}
|
||||
<span class="label caption-color overflow-label pointer-events-none">{value}</span>
|
||||
{:else}
|
||||
<span class="label content-dark-color pointer-events-none">
|
||||
<span class="label content-dark-color overflow-label pointer-events-none">
|
||||
<Label label={placeholder} />
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
{#if value != null}
|
||||
<span class="caption-color overflow-label pointer-events-none">{value}</span>
|
||||
{:else}
|
||||
<span class="content-dark-color pointer-events-none"><Label {label} /></span>
|
||||
<span class="content-dark-color overflow-labelpointer-events-none"><Label {label} /></span>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Button>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
{#if value}
|
||||
<span class="caption-color overflow-label pointer-events-none">{value}</span>
|
||||
{:else}
|
||||
<span class="content-dark-color pointer-events-none"><Label label={placeholder} /></span>
|
||||
<span class="content-dark-color overflow-label pointer-events-none"><Label label={placeholder} /></span>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</Button>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
FROM hardcoreeng/base-slim:v20250916
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
RUN npm install -g pnpm
|
||||
RUN npm install -g pnpm@10
|
||||
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
@@ -39,5 +39,8 @@
|
||||
"@livekit/rtc-node": "^0.13.11",
|
||||
"dotenv": "^16.4.5",
|
||||
"ws": "^8.18.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": ["esbuild"]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user