Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions foundations/core/packages/core/src/hierarchy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,23 @@ export class Hierarchy {
return Array.from(resultSet)
}

getAllPossibleMixins (_class: Ref<Class<Doc>>, to: Ref<Class<Doc>> = core.class.Doc): Ref<Mixin<Doc>>[] {
const result = new Set<Ref<Mixin<Doc>>>()
let c = this.getClass(_class)

while (c._id !== to && c.extends !== undefined) {
const _descendants = this.descendants.get(c._id)
for (const d of _descendants ?? []) {
if (this.isMixin(d) && this.getBaseClass(d) === c._id) {
result.add(d)
}
}
c = this.getClass(c.extends)
}

return [...result]
}

isMixin (_class: Ref<Class<Doc>>): boolean {
const data = this.classifiers.get(_class)
return data !== undefined && this._isMixin(data)
Expand Down
5 changes: 4 additions & 1 deletion foundations/core/packages/core/src/versioning.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Class, Doc, PersonId, Ref } from './classes'
import { Class, Doc, Mixin, PersonId, Ref } from './classes'

export interface VersionableDoc extends Doc {
baseId?: Ref<Doc>
Expand All @@ -10,4 +10,7 @@ export interface VersionableDoc extends Doc {

export interface VersionableClass extends Class<Doc> {
enabled: boolean
excludedProperties?: string[]
excludedRelations?: string[] // ${associationId}_${a|b}
excludeMixins?: Ref<Mixin<Doc>>[]
}
3 changes: 3 additions & 0 deletions models/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,4 +447,7 @@ export class TCollaborator extends TAttachedDoc implements Collaborator {
@MMixin(core.mixin.VersionableClass, core.class.Class)
export class TVersionableClass extends TClass implements VersionableClass {
enabled!: boolean
excludedProperties?: string[]
excludedRelations?: string[] // ${associationId}_${a|b}
excludeMixins?: Ref<Mixin<Doc>>[]
}
13 changes: 13 additions & 0 deletions models/process/src/functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,19 @@ export function defineFunctions (builder: Builder): void {
process.function.StringFromNumber
)

builder.createDoc(
process.class.ProcessFunction,
core.space.Model,
{
of: core.class.TypeIdentifier,
to: core.class.TypeString,
category: 'attribute',
label: process.string.TextFromIdentifier,
type: 'convert'
},
process.function.StringFromIdentifier
)

builder.createDoc(
process.class.ProcessFunction,
core.space.Model,
Expand Down
4 changes: 4 additions & 0 deletions models/server-process/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ export function createModel (builder: Builder): void {
func: serverProcess.transform.DateFromNumber
})

builder.mixin(process.function.StringFromIdentifier, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, {
func: serverProcess.transform.StringFromIdentifier
})

builder.mixin(process.function.NumberFromString, process.class.ProcessFunction, serverProcess.mixin.FuncImpl, {
func: serverProcess.transform.NumberFromString
})
Expand Down
72 changes: 58 additions & 14 deletions packages/ui/src/components/DropdownLabelsIntl.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
export let label: IntlString = ui.string.DropdownDefaultLabel
export let params: Record<string, any> = {}
export let items: DropdownIntlItem[]
export let selected: DropdownIntlItem['id'] | undefined = undefined
export let multiselect: boolean = false
export let selected: DropdownIntlItem['id'] | Array<DropdownIntlItem['id']> | undefined = multiselect ? [] : undefined
export let disabled: boolean = false
export let kind: ButtonKind = 'regular'
export let size: ButtonSize = 'small'
Expand All @@ -48,9 +49,11 @@
let container: HTMLElement
let opened: boolean = false

$: selectedItem = items.find((x) => x.id === selected)
$: if (shouldUpdateUndefined && selected === undefined && items[0] !== undefined) {
selected = items[0].id
$: selectedItem = multiselect
? (items ?? []).filter((p) => (selected as Array<DropdownIntlItem['id']>)?.includes(p.id))
: (items ?? []).find((x) => x.id === selected)
$: if (shouldUpdateUndefined && selected === undefined && items?.[0] !== undefined) {
selected = multiselect ? [items[0].id] : items[0].id
dispatch('selected', selected)
}

Expand All @@ -59,13 +62,24 @@
function openPopup () {
if (!opened) {
opened = true
showPopup(DropdownLabelsPopupIntl, { items, selected, params, withSearch }, container, (result) => {
if (result) {
selected = result
dispatch('selected', result)
showPopup(
DropdownLabelsPopupIntl,
{ items, selected, params, withSearch, multiselect },
container,
(result) => {
if (result) {
selected = result
dispatch('selected', result)
}
opened = false
},
(result) => {
if (result != null) {
selected = result
dispatch('selected', result)
}
}
opened = false
})
)
}
}

Expand Down Expand Up @@ -98,10 +112,21 @@
on:click={openPopup}
>
<span slot="content" class="overflow-label disabled flex-grow text-left mr-2">
<Label
label={selectedItem ? selectedItem.label : label}
params={selectedItem ? (selectedItem.params ?? params) : params}
/>
{#if Array.isArray(selectedItem)}
{#if selectedItem.length > 0}
{#each selectedItem as item}
<span class="step-row">
<Label label={item.label} params={item.params ?? params} />
</span>
{/each}
{:else}
<Label {label} {params} />
{/if}
{:else if selectedItem}
<Label label={selectedItem.label} params={selectedItem.params ?? params} />
{:else}
<Label {label} {params} />
{/if}
</span>
<svelte:fragment slot="iconRight">
<DropdownIcon
Expand All @@ -111,3 +136,22 @@
</svelte:fragment>
</Button>
</div>

<style lang="scss">
.step-row + .step-row {
position: relative;
margin-left: 0.75rem;

&::before {
position: absolute;
content: '';
top: 50%;
left: -0.5rem;
width: 0.25rem;
height: 0.25rem;
background-color: var(--dark-color);
border-radius: 50%;
transform: translateY(-50%);
}
}
</style>
29 changes: 26 additions & 3 deletions packages/ui/src/components/DropdownLabelsPopupIntl.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,24 @@
import ui from '../plugin'

export let items: DropdownIntlItem[]
export let selected: DropdownIntlItem['id'] | undefined = undefined
export let selected: DropdownIntlItem['id'] | Array<DropdownIntlItem['id']> | undefined = undefined
export let multiselect: boolean = false
export let params: Record<string, any> = {}
export let withSearch: boolean = false
export let searchPlaceholder: IntlString = ui.string.Search

const dispatch = createEventDispatcher()

function isSelected (
selected: DropdownIntlItem['id'] | Array<DropdownIntlItem['id']> | undefined,
item: DropdownIntlItem
): boolean {
if (Array.isArray(selected)) {
return selected.includes(item.id)
} else {
return item.id === selected
}
}
let btns: HTMLButtonElement[] = []

const keyDown = (ev: KeyboardEvent, n?: number): void => {
Expand Down Expand Up @@ -100,7 +112,18 @@
keyDown(ev, i)
}}
on:click={() => {
dispatch('close', item.id)
if (multiselect && Array.isArray(selected)) {
const index = selected.indexOf(item.id)
if (index !== -1) {
selected.splice(index, 1)
selected = selected
} else {
selected = selected === undefined ? [item.id] : [...selected, item.id]
}
dispatch('update', selected)
} else {
dispatch('close', item.id)
}
}}
>
<div class="flex-grow caption-color nowrap flex-presenter flex-gap-2">
Expand All @@ -110,7 +133,7 @@
<Label label={item.label} params={item.params ?? params} />
</div>
<div class="check">
{#if item.id === selected}<IconCheck size={'small'} />{/if}
{#if isSelected(selected, item)}<IconCheck size={'small'} />{/if}
</div>
</button>
{/each}
Expand Down
12 changes: 7 additions & 5 deletions plugins/card-resources/src/components/CardVersionSelector.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import { createQuery, getClient } from '@hcengineering/presentation'
import { Button, DropdownLabels, DropdownTextItem, getCurrentLocation, navigate, showPopup } from '@hcengineering/ui'
import card from '../plugin'
import NewVersionPopup from './NewVersionPopup.svelte'
import { createNewVersion } from '../utils'

export let value: Card

Expand Down Expand Up @@ -70,10 +70,12 @@
}
}

function newVersion (): void {
showPopup(NewVersionPopup, {
value
})
async function newVersion (): Promise<void> {
const _id = await createNewVersion(value)
const loc = getCurrentLocation()
loc.path[2] = cardId
loc.path[3] = _id
navigate(loc)
}
</script>

Expand Down
106 changes: 0 additions & 106 deletions plugins/card-resources/src/components/NewVersionPopup.svelte

This file was deleted.

Loading
Loading