mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
Move Attribute setting to Settings. (#1887)
Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
parent
b1d751e60f
commit
9f9003ec68
@ -32,6 +32,7 @@
|
||||
"@anticrm/model-view": "~0.6.0",
|
||||
"@anticrm/model-presentation": "~0.6.0",
|
||||
"@anticrm/model": "~0.6.0",
|
||||
"@anticrm/setting": "~0.6.1",
|
||||
"@anticrm/core": "~0.6.16",
|
||||
"@anticrm/ui": "~0.6.0",
|
||||
"@anticrm/platform": "~0.6.6",
|
||||
|
@ -36,6 +36,7 @@ import view, { actionTemplates, createAction } from '@anticrm/model-view'
|
||||
import workbench from '@anticrm/model-workbench'
|
||||
import type { Asset, IntlString } from '@anticrm/platform'
|
||||
import contact from './plugin'
|
||||
import setting from '@anticrm/setting'
|
||||
|
||||
export const DOMAIN_CONTACT = 'contact' as Domain
|
||||
export const DOMAIN_CHANNEL = 'channel' as Domain
|
||||
@ -297,6 +298,8 @@ export function createModel (builder: Builder): void {
|
||||
filters: ['_class', 'city', 'modifiedOn']
|
||||
})
|
||||
|
||||
builder.mixin(contact.class.Contact, core.class.Class, setting.mixin.Editable, {})
|
||||
|
||||
builder.createDoc(
|
||||
presentation.class.ObjectSearchCategory,
|
||||
core.space.Model,
|
||||
|
@ -35,6 +35,7 @@
|
||||
"@anticrm/inventory": "~0.6.0",
|
||||
"@anticrm/inventory-resources": "~0.6.0",
|
||||
"@anticrm/view": "~0.6.0",
|
||||
"@anticrm/setting": "~0.6.1",
|
||||
"@anticrm/workbench": "~0.6.1",
|
||||
"@anticrm/model-view": "~0.6.0"
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import { createAction } from '@anticrm/model-view'
|
||||
import workbench from '@anticrm/model-workbench'
|
||||
import type {} from '@anticrm/view'
|
||||
import view from '@anticrm/view'
|
||||
import setting from '@anticrm/setting'
|
||||
import inventory from './plugin'
|
||||
|
||||
export const DOMAIN_INVENTORY = 'inventory' as Domain
|
||||
@ -93,6 +94,8 @@ export function createModel (builder: Builder): void {
|
||||
editor: inventory.component.EditProduct
|
||||
})
|
||||
|
||||
builder.mixin(inventory.class.Product, core.class.Class, setting.mixin.Editable, {})
|
||||
|
||||
builder.createDoc(view.class.Viewlet, core.space.Model, {
|
||||
attachTo: inventory.class.Product,
|
||||
descriptor: view.viewlet.Table,
|
||||
|
@ -38,6 +38,7 @@
|
||||
"@anticrm/model-attachment": "~0.6.0",
|
||||
"@anticrm/lead": "~0.6.0",
|
||||
"@anticrm/lead-resources": "~0.6.0",
|
||||
"@anticrm/setting": "~0.6.1",
|
||||
"@anticrm/view": "~0.6.0",
|
||||
"@anticrm/task": "~0.6.0",
|
||||
"@anticrm/model-task": "~0.6.0",
|
||||
|
@ -25,6 +25,7 @@ import core from '@anticrm/model-core'
|
||||
import task, { TSpaceWithStates, TTask } from '@anticrm/model-task'
|
||||
import view, { createAction } from '@anticrm/model-view'
|
||||
import workbench, { Application } from '@anticrm/model-workbench'
|
||||
import setting from '@anticrm/setting'
|
||||
import lead from './plugin'
|
||||
|
||||
@Model(lead.class.Funnel, task.class.SpaceWithStates)
|
||||
@ -76,6 +77,8 @@ export function createModel (builder: Builder): void {
|
||||
}
|
||||
})
|
||||
|
||||
builder.mixin(lead.class.Lead, core.class.Class, setting.mixin.Editable, {})
|
||||
|
||||
builder.createDoc(
|
||||
workbench.class.Application,
|
||||
core.space.Model,
|
||||
|
@ -41,6 +41,7 @@
|
||||
"@anticrm/model-chunter": "~0.6.0",
|
||||
"@anticrm/view": "~0.6.0",
|
||||
"@anticrm/task": "~0.6.0",
|
||||
"@anticrm/setting": "~0.6.1",
|
||||
"@anticrm/model-task": "~0.6.0",
|
||||
"@anticrm/workbench": "~0.6.1",
|
||||
"@anticrm/model-presentation": "~0.6.0",
|
||||
|
@ -42,6 +42,7 @@ import workbench, { Application, createNavigateAction } from '@anticrm/model-wor
|
||||
import { IntlString } from '@anticrm/platform'
|
||||
import { Applicant, Candidate, Candidates, Vacancy } from '@anticrm/recruit'
|
||||
import { KeyBinding } from '@anticrm/view'
|
||||
import setting from '@anticrm/setting'
|
||||
import recruit from './plugin'
|
||||
import { createReviewModel, reviewTableConfig, reviewTableOptions } from './review'
|
||||
import { TOpinion, TReview } from './review-model'
|
||||
@ -141,6 +142,10 @@ export function createModel (builder: Builder): void {
|
||||
component: recruit.component.CreateCandidate
|
||||
})
|
||||
|
||||
builder.mixin(recruit.class.Applicant, core.class.Class, setting.mixin.Editable, {})
|
||||
|
||||
builder.mixin(recruit.class.Vacancy, core.class.Class, setting.mixin.Editable, {})
|
||||
|
||||
const vacanciesId = 'vacancies'
|
||||
const candidatesId = 'candidates'
|
||||
const skillsId = 'skills'
|
||||
|
@ -13,14 +13,15 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { Builder, Model } from '@anticrm/model'
|
||||
import { Builder, Mixin, Model } from '@anticrm/model'
|
||||
import { Ref, Domain, DOMAIN_MODEL } from '@anticrm/core'
|
||||
import core, { TDoc } from '@anticrm/model-core'
|
||||
import core, { TClass, TDoc } from '@anticrm/model-core'
|
||||
import setting from './plugin'
|
||||
import type { Integration, IntegrationType, Handler, SettingsCategory } from '@anticrm/setting'
|
||||
import type { Editable, Integration, IntegrationType, Handler, SettingsCategory } from '@anticrm/setting'
|
||||
import type { Asset, IntlString } from '@anticrm/platform'
|
||||
import task from '@anticrm/task'
|
||||
import activity from '@anticrm/activity'
|
||||
import view from '@anticrm/view'
|
||||
|
||||
import workbench from '@anticrm/model-workbench'
|
||||
import { AnyComponent } from '@anticrm/ui'
|
||||
@ -51,8 +52,11 @@ export class TIntegrationType extends TDoc implements IntegrationType {
|
||||
onDisconnect!: Handler
|
||||
}
|
||||
|
||||
@Mixin(setting.mixin.Editable, core.class.Class)
|
||||
export class TEditable extends TClass implements Editable {}
|
||||
|
||||
export function createModel (builder: Builder): void {
|
||||
builder.createModel(TIntegration, TIntegrationType, TSettingsCategory)
|
||||
builder.createModel(TIntegration, TIntegrationType, TSettingsCategory, TEditable)
|
||||
|
||||
builder.createDoc(
|
||||
setting.class.SettingsCategory,
|
||||
@ -115,6 +119,18 @@ export function createModel (builder: Builder): void {
|
||||
},
|
||||
setting.ids.ManageStatuses
|
||||
)
|
||||
builder.createDoc(
|
||||
setting.class.SettingsCategory,
|
||||
core.space.Model,
|
||||
{
|
||||
name: 'classes',
|
||||
label: setting.string.ClassSetting,
|
||||
icon: setting.icon.Setting,
|
||||
component: setting.component.ClassSetting,
|
||||
order: 4500
|
||||
},
|
||||
setting.ids.ClassSetting
|
||||
)
|
||||
builder.createDoc(
|
||||
setting.class.SettingsCategory,
|
||||
core.space.Model,
|
||||
@ -180,6 +196,26 @@ export function createModel (builder: Builder): void {
|
||||
},
|
||||
setting.ids.TxIntegrationDisable
|
||||
)
|
||||
|
||||
builder.mixin(core.class.TypeString, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: setting.component.StringTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.TypeBoolean, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: setting.component.BooleanTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.TypeDate, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: setting.component.DateTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.TypeNumber, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: setting.component.NumberTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.RefTo, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: setting.component.RefEditor
|
||||
})
|
||||
}
|
||||
|
||||
export { settingOperation } from './migration'
|
||||
|
@ -27,5 +27,12 @@ export default mergeIds(settingId, setting, {
|
||||
},
|
||||
ids: {
|
||||
TxIntegrationDisable: '' as Ref<TxViewlet>
|
||||
},
|
||||
component: {
|
||||
StringTypeEditor: '' as AnyComponent,
|
||||
BooleanTypeEditor: '' as AnyComponent,
|
||||
NumberTypeEditor: '' as AnyComponent,
|
||||
DateTypeEditor: '' as AnyComponent,
|
||||
RefEditor: '' as AnyComponent
|
||||
}
|
||||
})
|
||||
|
@ -277,26 +277,6 @@ export function createModel (builder: Builder): void {
|
||||
classPresenter(builder, core.class.Space, view.component.ObjectPresenter)
|
||||
classPresenter(builder, core.class.Class, view.component.ClassPresenter)
|
||||
|
||||
builder.mixin(core.class.TypeString, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: view.component.StringTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.TypeBoolean, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: view.component.BooleanTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.TypeDate, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: view.component.DateTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.TypeNumber, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: view.component.NumberTypeEditor
|
||||
})
|
||||
|
||||
builder.mixin(core.class.RefTo, core.class.Class, view.mixin.ObjectEditor, {
|
||||
editor: view.component.RefEditor
|
||||
})
|
||||
|
||||
builder.createDoc(
|
||||
view.class.ActionCategory,
|
||||
core.space.Model,
|
||||
|
@ -78,11 +78,6 @@ export default mergeIds(viewId, view, {
|
||||
RolePresenter: '' as AnyComponent,
|
||||
YoutubePresenter: '' as AnyComponent,
|
||||
GithubPresenter: '' as AnyComponent,
|
||||
StringTypeEditor: '' as AnyComponent,
|
||||
BooleanTypeEditor: '' as AnyComponent,
|
||||
NumberTypeEditor: '' as AnyComponent,
|
||||
DateTypeEditor: '' as AnyComponent,
|
||||
RefEditor: '' as AnyComponent,
|
||||
ClassPresenter: '' as AnyComponent
|
||||
},
|
||||
string: {
|
||||
|
@ -18,7 +18,7 @@ import type { AnyAttribute, Class, Classifier, Doc, Domain, Interface, Mixin, Ob
|
||||
import { ClassifierKind } from './classes'
|
||||
import core from './component'
|
||||
import { _createMixinProxy, _mixinClass, _toDoc } from './proxy'
|
||||
import type { Tx, TxCreateDoc, TxMixin } from './tx'
|
||||
import type { Tx, TxCreateDoc, TxMixin, TxRemoveDoc, TxUpdateDoc } from './tx'
|
||||
import { TxProcessor } from './tx'
|
||||
|
||||
/**
|
||||
@ -27,6 +27,7 @@ import { TxProcessor } from './tx'
|
||||
export class Hierarchy {
|
||||
private readonly classifiers = new Map<Ref<Classifier>, Classifier>()
|
||||
private readonly attributes = new Map<Ref<Classifier>, Map<string, AnyAttribute>>()
|
||||
private readonly attributesById = new Map<Ref<AnyAttribute>, AnyAttribute>()
|
||||
private readonly descendants = new Map<Ref<Classifier>, Ref<Classifier>[]>()
|
||||
private readonly ancestors = new Map<Ref<Classifier>, Ref<Classifier>[]>()
|
||||
private readonly proxies = new Map<Ref<Mixin<Doc>>, ProxyHandler<Doc>>()
|
||||
@ -124,6 +125,12 @@ export class Hierarchy {
|
||||
case core.class.TxCreateDoc:
|
||||
this.txCreateDoc(tx as TxCreateDoc<Doc>)
|
||||
return
|
||||
case core.class.TxUpdateDoc:
|
||||
this.txUpdateDoc(tx as TxUpdateDoc<Doc>)
|
||||
return
|
||||
case core.class.TxRemoveDoc:
|
||||
this.txRemoveDoc(tx as TxRemoveDoc<Doc>)
|
||||
return
|
||||
case core.class.TxMixin:
|
||||
this.txMixin(tx as TxMixin<Doc, Doc>)
|
||||
}
|
||||
@ -145,6 +152,26 @@ export class Hierarchy {
|
||||
}
|
||||
}
|
||||
|
||||
private txUpdateDoc (tx: TxUpdateDoc<Doc>): void {
|
||||
if (tx.objectClass === core.class.Attribute) {
|
||||
const updateTx = tx as TxUpdateDoc<AnyAttribute>
|
||||
const doc = this.attributesById.get(updateTx.objectId)
|
||||
if (doc === undefined) return
|
||||
this.addAttribute(TxProcessor.updateDoc2Doc(doc, updateTx))
|
||||
}
|
||||
}
|
||||
|
||||
private txRemoveDoc (tx: TxRemoveDoc<Doc>): void {
|
||||
if (tx.objectClass === core.class.Attribute) {
|
||||
const removeTx = tx as TxRemoveDoc<AnyAttribute>
|
||||
const doc = this.attributesById.get(removeTx.objectId)
|
||||
if (doc === undefined) return
|
||||
const map = this.attributes.get(doc.attributeOf)
|
||||
map?.delete(doc.name)
|
||||
this.attributesById.delete(removeTx.objectId)
|
||||
}
|
||||
}
|
||||
|
||||
private txMixin (tx: TxMixin<Doc, Doc>): void {
|
||||
if (this.isDerived(tx.objectClass, core.class.Class)) {
|
||||
const obj = this.getClass(tx.objectId as Ref<Class<Obj>>) as any
|
||||
@ -287,6 +314,7 @@ export class Hierarchy {
|
||||
this.attributes.set(_class, attributes)
|
||||
}
|
||||
attributes.set(attribute.name, attribute)
|
||||
this.attributesById.set(attribute._id, attribute)
|
||||
}
|
||||
|
||||
getAllAttributes (clazz: Ref<Classifier>, to?: Ref<Classifier>): Map<string, AnyAttribute> {
|
||||
@ -300,10 +328,13 @@ export class Hierarchy {
|
||||
break
|
||||
}
|
||||
}
|
||||
ancestors = ancestors.filter((c) => this.isDerived(c, to as Ref<Class<Doc>>) && c !== to)
|
||||
ancestors = ancestors.filter(
|
||||
(c) => c !== to && (this.isInterface(this.classifiers.get(c)) || this.isDerived(c, to as Ref<Class<Doc>>))
|
||||
)
|
||||
}
|
||||
|
||||
for (const cls of ancestors) {
|
||||
for (let index = ancestors.length - 1; index >= 0; index--) {
|
||||
const cls = ancestors[index]
|
||||
const attributes = this.attributes.get(cls)
|
||||
if (attributes !== undefined) {
|
||||
for (const [name, attr] of attributes) {
|
||||
|
@ -75,6 +75,9 @@ const predicates: Record<string, PredicateFactory> = {
|
||||
},
|
||||
$lte: (o, propertyKey) => {
|
||||
return (docs) => execPredicate(docs, propertyKey, (value) => value <= o)
|
||||
},
|
||||
$exist: (o, propertyKey) => {
|
||||
return (docs) => execPredicate(docs, propertyKey, (value) => (value !== undefined) === o)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ export type QuerySelector<T> = {
|
||||
$gte?: T extends number ? number : never
|
||||
$lt?: T extends number ? number : never
|
||||
$lte?: T extends number ? number : never
|
||||
$exist?: boolean
|
||||
$like?: string
|
||||
$regex?: string
|
||||
$options?: string
|
||||
|
@ -24,6 +24,7 @@
|
||||
"NoMatchesInThis": "No matches in this {space}",
|
||||
"NoMatchesFound": "No matches found",
|
||||
"NotInThis": "Not in this {space}",
|
||||
"Add": "Add"
|
||||
"Add": "Add",
|
||||
"Edit": "Edit"
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
"NoMatchesInThis": "В этом {space} совпадения не обнаружены",
|
||||
"NoMatchesFound": "Не найдено соответсвий",
|
||||
"NotInThis": "Не в этом {space}",
|
||||
"Add": "Добавить"
|
||||
"Add": "Добавить",
|
||||
"Edit": "Редактировать"
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ export default plugin(presentationId, {
|
||||
NoMatchesInThis: '' as IntlString,
|
||||
NoMatchesFound: '' as IntlString,
|
||||
NotInThis: '' as IntlString,
|
||||
Add: '' as IntlString
|
||||
Add: '' as IntlString,
|
||||
Edit: '' as IntlString
|
||||
},
|
||||
metadata: {
|
||||
RequiredVersion: '' as Metadata<string>
|
||||
|
@ -29,6 +29,17 @@
|
||||
"DeleteStatusConfirm": "Do you want to delete this status?",
|
||||
"Reconnect": "Reconnect",
|
||||
"IntegrationDisabled": " has been disabled",
|
||||
"IntegrationWith": "Integration with "
|
||||
"IntegrationWith": "Integration with ",
|
||||
"ClassSetting": "Class setting",
|
||||
"Attributes": "Attributes",
|
||||
"DeleteAttribute": "Delete attribute",
|
||||
"DeleteAttributeConfirm": "Do you want to delete this attribute?",
|
||||
"DeleteAttributeExistConfirm": "Do you want to delete this attribute? Data will be lost",
|
||||
"Attribute": "Attribute",
|
||||
"Custom": "Custom",
|
||||
"Type": "Type",
|
||||
"WithTime": "WithTime",
|
||||
"CreatingAttribute": "Creating an attribute",
|
||||
"EditAttribute": "Edit attribute"
|
||||
}
|
||||
}
|
@ -29,6 +29,17 @@
|
||||
"DeleteStatusConfirm": "Вы действительно хотите удалить этот статус?",
|
||||
"Reconnect": "Переподключить",
|
||||
"IntegrationDisabled": " была отключена",
|
||||
"IntegrationWith": "Интеграция с "
|
||||
"IntegrationWith": "Интеграция с ",
|
||||
"ClassSetting": "Настройки класса",
|
||||
"Attributes": "Атрибуты",
|
||||
"DeleteAttribute": "Удалить атрибут",
|
||||
"DeleteAttributeConfirm": "Вы действительно хотите удалить этот атрибут?",
|
||||
"DeleteAttributeExistConfirm": "Вы действительно хотите удалить этот атрибут? Данные будут утеряны",
|
||||
"Attribute": "Атрибут",
|
||||
"Custom": "Пользовательский",
|
||||
"Type": "Тип",
|
||||
"WithTime": "Со временем",
|
||||
"CreatingAttribute": "Создание атрибута",
|
||||
"EditAttribute": "Редактирование атрибута"
|
||||
}
|
||||
}
|
@ -44,6 +44,7 @@
|
||||
"@anticrm/login-resources": "~0.6.2",
|
||||
"@anticrm/task": "~0.6.0",
|
||||
"@anticrm/contact-resources": "~0.6.0",
|
||||
"@anticrm/login": "~0.6.1"
|
||||
"@anticrm/login": "~0.6.1",
|
||||
"@anticrm/model": "~0.6.0"
|
||||
}
|
||||
}
|
||||
|
145
plugins/setting-resources/src/components/ClassAttributes.svelte
Normal file
145
plugins/setting-resources/src/components/ClassAttributes.svelte
Normal file
@ -0,0 +1,145 @@
|
||||
<!--
|
||||
// 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 core, { AnyAttribute, Class, Doc, Ref } from '@anticrm/core'
|
||||
import presentation, { getClient, MessageBox } from '@anticrm/presentation'
|
||||
import {
|
||||
Action,
|
||||
CircleButton,
|
||||
eventToHTMLElement,
|
||||
IconAdd,
|
||||
IconDelete,
|
||||
IconEdit,
|
||||
Label,
|
||||
Menu,
|
||||
IconMoreV,
|
||||
showPopup
|
||||
} from '@anticrm/ui'
|
||||
import BooleanPresenter from '@anticrm/view-resources/src/components/BooleanPresenter.svelte'
|
||||
import setting from '../plugin'
|
||||
import CreateAttribute from './CreateAttribute.svelte'
|
||||
import EditAttribute from './EditAttribute.svelte'
|
||||
export let _class: Ref<Class<Doc>>
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
$: attributes = getCustomAttributes(_class)
|
||||
|
||||
function getCustomAttributes (_class: Ref<Class<Doc>>): AnyAttribute[] {
|
||||
const attributes = Array.from(hierarchy.getAllAttributes(_class, core.class.AttachedDoc).values())
|
||||
const filtred = attributes.filter((p) => !p.hidden)
|
||||
return filtred
|
||||
}
|
||||
|
||||
function update () {
|
||||
attributes = getCustomAttributes(_class)
|
||||
}
|
||||
|
||||
function createAttribute () {
|
||||
showPopup(CreateAttribute, { _class }, 'top', update)
|
||||
}
|
||||
|
||||
async function editAttribute (attribute: AnyAttribute, exist: boolean): Promise<void> {
|
||||
showPopup(EditAttribute, { attribute, exist }, 'top', update)
|
||||
}
|
||||
|
||||
async function removeAttribute (attribute: AnyAttribute, exist: boolean): Promise<void> {
|
||||
showPopup(
|
||||
MessageBox,
|
||||
{
|
||||
label: setting.string.DeleteAttribute,
|
||||
message: exist ? setting.string.DeleteAttributeExistConfirm : setting.string.DeleteAttributeConfirm
|
||||
},
|
||||
'top',
|
||||
async (result) => {
|
||||
if (result) {
|
||||
await client.remove(attribute)
|
||||
update()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
async function showMenu (ev: MouseEvent, attribute: AnyAttribute) {
|
||||
const exist = (await client.findOne(attribute.attributeOf, { [attribute.name]: { $exist: true } })) !== undefined
|
||||
|
||||
const actions: Action[] = [
|
||||
{
|
||||
label: presentation.string.Edit,
|
||||
icon: IconEdit,
|
||||
action: async () => {
|
||||
editAttribute(attribute, exist)
|
||||
}
|
||||
},
|
||||
{
|
||||
label: presentation.string.Remove,
|
||||
icon: IconDelete,
|
||||
action: async () => {
|
||||
removeAttribute(attribute, exist)
|
||||
}
|
||||
}
|
||||
]
|
||||
showPopup(Menu, { actions }, eventToHTMLElement(ev), () => {})
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex-between trans-title mb-3">
|
||||
<Label label={setting.string.Attributes} />
|
||||
<CircleButton icon={IconAdd} size="medium" on:click={createAttribute} />
|
||||
</div>
|
||||
<table class="antiTable">
|
||||
<thead class="scroller-thead">
|
||||
<tr class="scroller-thead__tr">
|
||||
<th>
|
||||
<div class="antiTable-cells">
|
||||
<Label label={setting.string.Attribute} />
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="antiTable-cells">
|
||||
<Label label={setting.string.Type} />
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<div class="antiTable-cells">
|
||||
<Label label={setting.string.Custom} />
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each attributes as attr}
|
||||
<tr class="antiTable-body__row" on:contextmenu|preventDefault={(ev) => showMenu(ev, attr)}>
|
||||
<td>
|
||||
<div class="antiTable-cells__firstCell">
|
||||
<Label label={attr.label} />
|
||||
{#if attr.isCustom}
|
||||
<div id="context-menu" class="antiTable-cells__firstCell-menuRow" on:click={(ev) => showMenu(ev, attr)}>
|
||||
<IconMoreV size={'small'} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<Label label={attr.type.label} />
|
||||
</td>
|
||||
<td>
|
||||
<BooleanPresenter value={attr.isCustom ?? false} />
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
@ -0,0 +1,62 @@
|
||||
<!--
|
||||
// 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 { Class, ClassifierKind, Doc, Ref } from '@anticrm/core'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { Label } from '@anticrm/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
export let classes: Ref<Class<Doc>>[] = ['contact:class:Contact' as Ref<Class<Doc>>]
|
||||
export let _class: Ref<Class<Doc>> | undefined
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function getDescendants (_class: Ref<Class<Doc>>): Ref<Class<Doc>>[] {
|
||||
const result: Ref<Class<Doc>>[] = []
|
||||
const desc = hierarchy.getDescendants(_class)
|
||||
for (const clazz of desc) {
|
||||
const cls = hierarchy.getClass(clazz)
|
||||
if (
|
||||
cls.extends === _class &&
|
||||
!cls.hidden &&
|
||||
[ClassifierKind.CLASS, ClassifierKind.MIXIN].includes(cls.kind) &&
|
||||
cls.label !== undefined
|
||||
) {
|
||||
result.push(clazz)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
</script>
|
||||
|
||||
{#each classes as cl}
|
||||
{@const clazz = hierarchy.getClass(cl)}
|
||||
{@const desc = getDescendants(cl)}
|
||||
<div
|
||||
class="ac-column__list-item"
|
||||
class:selected={cl === _class}
|
||||
on:click={() => {
|
||||
dispatch('select', cl)
|
||||
}}
|
||||
>
|
||||
<Label label={clazz.label} />
|
||||
</div>
|
||||
{#if desc.length}
|
||||
<div class="ml-2 mt-3 mb-3">
|
||||
<svelte:self classes={desc} {_class} on:select />
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
65
plugins/setting-resources/src/components/ClassSetting.svelte
Normal file
65
plugins/setting-resources/src/components/ClassSetting.svelte
Normal file
@ -0,0 +1,65 @@
|
||||
<!--
|
||||
// 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 core, { Class, Doc, Ref } from '@anticrm/core'
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { getCurrentLocation, Icon, Label, navigate } from '@anticrm/ui'
|
||||
import setting from '../plugin'
|
||||
import ClassAttributes from './ClassAttributes.svelte'
|
||||
import ClassHierarchy from './ClassHierarchy.svelte'
|
||||
|
||||
const loc = getCurrentLocation()
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
let _class: Ref<Class<Doc>> | undefined = loc.query?._class as Ref<Class<Doc>> | undefined
|
||||
|
||||
$: if (_class !== undefined) {
|
||||
const loc = getCurrentLocation()
|
||||
loc.query = undefined
|
||||
navigate(loc)
|
||||
}
|
||||
|
||||
const classes = hierarchy
|
||||
.getDescendants(core.class.Doc)
|
||||
.map((p) => hierarchy.getClass(p))
|
||||
.filter((p) => hierarchy.hasMixin(p, setting.mixin.Editable))
|
||||
.map((p) => p._id)
|
||||
</script>
|
||||
|
||||
<div class="antiComponent">
|
||||
<div class="ac-header short divide">
|
||||
<div class="ac-header__icon"><Icon icon={setting.icon.Setting} size={'medium'} /></div>
|
||||
<div class="ac-header__title"><Label label={setting.string.ClassSetting} /></div>
|
||||
</div>
|
||||
<div class="ac-body columns hScroll">
|
||||
<div class="ac-column">
|
||||
<div class="overflow-y-auto">
|
||||
<ClassHierarchy
|
||||
{classes}
|
||||
{_class}
|
||||
on:select={(e) => {
|
||||
_class = e.detail
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ac-column max">
|
||||
{#if _class !== undefined}
|
||||
<ClassAttributes {_class} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -19,7 +19,8 @@
|
||||
import { AnyComponent, Component, DropdownLabelsIntl, EditBox, Label } from '@anticrm/ui'
|
||||
import { DropdownIntlItem } from '@anticrm/ui/src/types'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import view from '../plugin'
|
||||
import setting from '../plugin'
|
||||
import view from '@anticrm/view'
|
||||
|
||||
export let _class: Ref<Class<Doc>>
|
||||
let name: string
|
||||
@ -77,7 +78,7 @@
|
||||
</script>
|
||||
|
||||
<Card
|
||||
label={view.string.CreatingAttribute}
|
||||
label={setting.string.CreatingAttribute}
|
||||
okAction={save}
|
||||
canSave={!(type === undefined || name === undefined || name.trim().length === 0)}
|
||||
on:close={() => {
|
||||
@ -87,10 +88,10 @@
|
||||
<div class="mb-2"><EditBox bind:value={name} placeholder={core.string.Name} maxWidth="13rem" /></div>
|
||||
<div class="flex-col mb-2">
|
||||
<div class="flex-row-center flex-grow">
|
||||
<Label label={view.string.Type} />
|
||||
<Label label={setting.string.Type} />
|
||||
<div class="ml-4">
|
||||
<DropdownLabelsIntl
|
||||
label={view.string.Type}
|
||||
label={setting.string.Type}
|
||||
{items}
|
||||
width="8rem"
|
||||
bind:selected={selectedType}
|
||||
@ -109,9 +110,5 @@
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<Label label={view.string.CreatingAttributeConfirm} />
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
127
plugins/setting-resources/src/components/EditAttribute.svelte
Normal file
127
plugins/setting-resources/src/components/EditAttribute.svelte
Normal file
@ -0,0 +1,127 @@
|
||||
<!--
|
||||
// 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 core, { AnyAttribute, Class, DocumentUpdate, IndexKind, PropertyType, Ref, Type } from '@anticrm/core'
|
||||
import { getEmbeddedLabel, translate } from '@anticrm/platform'
|
||||
import presentation, { Card, getClient } from '@anticrm/presentation'
|
||||
import setting from '../plugin'
|
||||
import { AnyComponent, Component, DropdownIntlItem, DropdownLabelsIntl, EditBox, Label } from '@anticrm/ui'
|
||||
import view from '@anticrm/view-resources/src/plugin'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let attribute: AnyAttribute
|
||||
export let exist: boolean
|
||||
let name: string
|
||||
let type: Type<PropertyType> | undefined
|
||||
let index: IndexKind | undefined
|
||||
let is: AnyComponent | undefined
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
translate(attribute.label, {}).then((p) => (name = p))
|
||||
|
||||
async function save (): Promise<void> {
|
||||
const update: DocumentUpdate<AnyAttribute> = {}
|
||||
const newLabel = getEmbeddedLabel(name)
|
||||
if (newLabel !== attribute.label) {
|
||||
update.label = newLabel
|
||||
}
|
||||
if (!exist) {
|
||||
if (index !== attribute.index) {
|
||||
update.index = index
|
||||
}
|
||||
if (type !== attribute.type) {
|
||||
update.type = type
|
||||
}
|
||||
}
|
||||
await client.updateDoc(attribute._class, attribute.space, attribute._id, update)
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
function getTypes (): DropdownIntlItem[] {
|
||||
const descendants = hierarchy.getDescendants(core.class.Type)
|
||||
const res: DropdownIntlItem[] = []
|
||||
for (const descendant of descendants) {
|
||||
const _class = hierarchy.getClass(descendant)
|
||||
if (_class.label !== undefined && hierarchy.hasMixin(_class, view.mixin.ObjectEditor)) {
|
||||
res.push({
|
||||
label: _class.label,
|
||||
id: _class._id
|
||||
})
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
const items = getTypes()
|
||||
let selectedType: Ref<Class<Type<PropertyType>>> = attribute.type._class
|
||||
|
||||
$: selectedType && selectType(selectedType)
|
||||
|
||||
function selectType (type: Ref<Class<Type<PropertyType>>>): void {
|
||||
const _class = hierarchy.getClass(type)
|
||||
const editor = hierarchy.as(_class, view.mixin.ObjectEditor)
|
||||
if (editor.editor !== undefined) {
|
||||
is = editor.editor
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Card
|
||||
label={setting.string.EditAttribute}
|
||||
okLabel={presentation.string.Save}
|
||||
okAction={save}
|
||||
canSave={!(name === undefined || name.trim().length === 0)}
|
||||
on:close={() => {
|
||||
dispatch('close')
|
||||
}}
|
||||
>
|
||||
<div class="mb-2"><EditBox bind:value={name} placeholder={core.string.Name} maxWidth="13rem" /></div>
|
||||
<div class="flex-col mb-2">
|
||||
<div class="flex-row-center flex-grow">
|
||||
<Label label={setting.string.Type} />
|
||||
</div>
|
||||
<div class="flex-col mb-2">
|
||||
{#if exist}
|
||||
<Label label={attribute.type.label} />
|
||||
{:else}
|
||||
<div class="flex-row-center flex-grow">
|
||||
<div class="ml-4">
|
||||
<DropdownLabelsIntl
|
||||
label={setting.string.Type}
|
||||
{items}
|
||||
width="8rem"
|
||||
bind:selected={selectedType}
|
||||
on:selected={(e) => selectType(e.detail)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{#if is}
|
||||
<div class="flex mt-4">
|
||||
<Component
|
||||
{is}
|
||||
on:change={(e) => {
|
||||
type = e.detail?.type
|
||||
index = e.detail?.index
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
@ -16,8 +16,8 @@
|
||||
import { TypeDate } from '@anticrm/model'
|
||||
import { Label } from '@anticrm/ui'
|
||||
import { createEventDispatcher, onMount } from 'svelte'
|
||||
import view from '../../plugin'
|
||||
import BooleanEditor from '../BooleanEditor.svelte'
|
||||
import setting from '../../plugin'
|
||||
import BooleanEditor from '@anticrm/view-resources/src/components/BooleanEditor.svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
</script>
|
||||
|
||||
<div class="flex-row-center">
|
||||
<Label label={view.string.WithTime} />
|
||||
<Label label={setting.string.WithTime} />
|
||||
<div class="ml-2">
|
||||
<BooleanEditor
|
||||
withoutUndefined
|
@ -18,7 +18,7 @@
|
||||
import { getClient } from '@anticrm/presentation'
|
||||
import { DOMAIN_STATE } from '@anticrm/task'
|
||||
import { DropdownLabelsIntl, Label } from '@anticrm/ui'
|
||||
import view from '../../plugin'
|
||||
import view from '@anticrm/view-resources/src/plugin'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
const dispatch = createEventDispatcher()
|
@ -23,8 +23,14 @@ import Support from './components/Support.svelte'
|
||||
import Privacy from './components/Privacy.svelte'
|
||||
import Terms from './components/Terms.svelte'
|
||||
import Settings from './components/Settings.svelte'
|
||||
import ClassSetting from './components/ClassSetting.svelte'
|
||||
import TxIntegrationDisable from './components/activity/TxIntegrationDisable.svelte'
|
||||
import TxIntegrationDisableReconnect from './components/activity/TxIntegrationDisableReconnect.svelte'
|
||||
import StringTypeEditor from './components/typeEditors/StringTypeEditor.svelte'
|
||||
import BooleanTypeEditor from './components/typeEditors/BooleanTypeEditor.svelte'
|
||||
import DateTypeEditor from './components/typeEditors/DateTypeEditor.svelte'
|
||||
import NumberTypeEditor from './components/typeEditors/NumberTypeEditor.svelte'
|
||||
import RefEditor from './components/typeEditors/RefEditor.svelte'
|
||||
|
||||
export default async (): Promise<Resources> => ({
|
||||
activity: {
|
||||
@ -40,6 +46,12 @@ export default async (): Promise<Resources> => ({
|
||||
Support,
|
||||
Privacy,
|
||||
Terms,
|
||||
ManageStatuses
|
||||
ManageStatuses,
|
||||
ClassSetting,
|
||||
StringTypeEditor,
|
||||
BooleanTypeEditor,
|
||||
NumberTypeEditor,
|
||||
RefEditor,
|
||||
DateTypeEditor
|
||||
}
|
||||
})
|
||||
|
@ -22,6 +22,16 @@ export default mergeIds(settingId, setting, {
|
||||
IntegrationDisabled: '' as IntlString,
|
||||
IntegrationWith: '' as IntlString,
|
||||
DeleteStatus: '' as IntlString,
|
||||
DeleteStatusConfirm: '' as IntlString
|
||||
DeleteStatusConfirm: '' as IntlString,
|
||||
DeleteAttribute: '' as IntlString,
|
||||
DeleteAttributeConfirm: '' as IntlString,
|
||||
DeleteAttributeExistConfirm: '' as IntlString,
|
||||
Attribute: '' as IntlString,
|
||||
Attributes: '' as IntlString,
|
||||
Custom: '' as IntlString,
|
||||
WithTime: '' as IntlString,
|
||||
Type: '' as IntlString,
|
||||
CreatingAttribute: '' as IntlString,
|
||||
EditAttribute: '' as IntlString
|
||||
}
|
||||
})
|
||||
|
@ -16,7 +16,7 @@
|
||||
import { Asset, IntlString, plugin, Resource } from '@anticrm/platform'
|
||||
import type { Plugin } from '@anticrm/platform'
|
||||
import { AnyComponent } from '@anticrm/ui'
|
||||
import type { Class, Doc, Ref } from '@anticrm/core'
|
||||
import type { Class, Doc, Mixin, Ref } from '@anticrm/core'
|
||||
|
||||
/**
|
||||
* @public
|
||||
@ -44,6 +44,11 @@ export interface Integration extends Doc {
|
||||
value: string
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Editable extends Class<Doc> {}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@ -72,7 +77,11 @@ export default plugin(settingId, {
|
||||
ManageStatuses: '' as Ref<Doc>,
|
||||
Support: '' as Ref<Doc>,
|
||||
Privacy: '' as Ref<Doc>,
|
||||
Terms: '' as Ref<Doc>
|
||||
Terms: '' as Ref<Doc>,
|
||||
ClassSetting: '' as Ref<Doc>
|
||||
},
|
||||
mixin: {
|
||||
Editable: '' as Ref<Mixin<Editable>>
|
||||
},
|
||||
class: {
|
||||
SettingsCategory: '' as Ref<Class<SettingsCategory>>,
|
||||
@ -88,7 +97,8 @@ export default plugin(settingId, {
|
||||
ManageStatuses: '' as AnyComponent,
|
||||
Support: '' as AnyComponent,
|
||||
Privacy: '' as AnyComponent,
|
||||
Terms: '' as AnyComponent
|
||||
Terms: '' as AnyComponent,
|
||||
ClassSetting: '' as AnyComponent
|
||||
},
|
||||
string: {
|
||||
Settings: '' as IntlString,
|
||||
@ -116,7 +126,8 @@ export default plugin(settingId, {
|
||||
Signout: '' as IntlString,
|
||||
InviteWorkspace: '' as IntlString,
|
||||
SelectWorkspace: '' as IntlString,
|
||||
Reconnect: '' as IntlString
|
||||
Reconnect: '' as IntlString,
|
||||
ClassSetting: '' as IntlString
|
||||
},
|
||||
icon: {
|
||||
EditProfile: '' as Asset,
|
||||
|
@ -33,10 +33,6 @@
|
||||
"Navigation": "Navigation",
|
||||
"Editor": "Editor",
|
||||
"MarkdownFormatting": "Formatting",
|
||||
"Type": "Type",
|
||||
"WithTime": "WithTime",
|
||||
"CreatingAttribute": "Creating an attribute",
|
||||
"CreatingAttributeConfirm": "Warning: It will not be possible for now to change or delete created attribute.",
|
||||
"CustomizeView": "Customize view",
|
||||
"Filter": "Filter",
|
||||
"ClearFilters": "Clear filters",
|
||||
|
@ -21,10 +21,6 @@
|
||||
"Navigation": "Навигация",
|
||||
"Editor": "Редактор",
|
||||
"MarkdownFormatting": "Форматирование",
|
||||
"Type": "Тип",
|
||||
"WithTime": "Со временем",
|
||||
"CreatingAttribute": "Создание атрибута",
|
||||
"CreatingAttributeConfirm": "Предупреждение: Изменить или удалить аттрибут в текущей версии невозможно.",
|
||||
"MoveLeft": "Переместить влево",
|
||||
"MoveRight": "Переместить вправо",
|
||||
"MoveUp": "Переместить вверх",
|
||||
|
@ -14,10 +14,9 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { Class, Doc, Ref } from '@anticrm/core'
|
||||
import presentation, { AttributesBar, getClient, KeyedAttribute } from '@anticrm/presentation'
|
||||
import { Button, IconAdd, Label, showPopup, Tooltip } from '@anticrm/ui'
|
||||
import view from '@anticrm/view'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { AttributesBar, getClient, KeyedAttribute } from '@anticrm/presentation'
|
||||
import setting from '@anticrm/setting'
|
||||
import { Button, getCurrentLocation, Label, navigate, Tooltip } from '@anticrm/ui'
|
||||
import { collectionsFilter, getFiltredKeys } from '../utils'
|
||||
|
||||
export let object: Doc
|
||||
@ -39,8 +38,6 @@
|
||||
$: updateKeys(ignoreKeys)
|
||||
|
||||
$: label = hierarchy.getClass(_class).label
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
</script>
|
||||
|
||||
{#if vertical}
|
||||
@ -62,16 +59,19 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="tool">
|
||||
<Tooltip label={presentation.string.Create}>
|
||||
<Tooltip label={setting.string.ClassSetting}>
|
||||
<Button
|
||||
icon={IconAdd}
|
||||
icon={setting.icon.Setting}
|
||||
kind={'transparent'}
|
||||
on:click={(ev) => {
|
||||
ev.stopPropagation()
|
||||
showPopup(view.component.CreateAttribute, { _class }, 'top', () => {
|
||||
updateKeys(ignoreKeys)
|
||||
dispatch('update')
|
||||
})
|
||||
const loc = getCurrentLocation()
|
||||
loc.path[1] = setting.ids.SettingApp
|
||||
loc.path[2] = 'classes'
|
||||
loc.path.length = 3
|
||||
loc.query = { _class }
|
||||
loc.fragment = undefined
|
||||
navigate(loc)
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
@ -38,12 +38,6 @@ import UpDownNavigator from './components/UpDownNavigator.svelte'
|
||||
import GithubPresenter from './components/linkPresenters/GithubPresenter.svelte'
|
||||
import YoutubePresenter from './components/linkPresenters/YoutubePresenter.svelte'
|
||||
import ActionsPopup from './components/ActionsPopup.svelte'
|
||||
import CreateAttribute from './components/CreateAttribute.svelte'
|
||||
import StringTypeEditor from './components/typeEditors/StringTypeEditor.svelte'
|
||||
import BooleanTypeEditor from './components/typeEditors/BooleanTypeEditor.svelte'
|
||||
import DateTypeEditor from './components/typeEditors/DateTypeEditor.svelte'
|
||||
import NumberTypeEditor from './components/typeEditors/NumberTypeEditor.svelte'
|
||||
import RefEditor from './components/typeEditors/RefEditor.svelte'
|
||||
import DocAttributeBar from './components/DocAttributeBar.svelte'
|
||||
import ViewletSetting from './components/ViewletSetting.svelte'
|
||||
import TableBrowser from './components/TableBrowser.svelte'
|
||||
@ -88,12 +82,6 @@ export default async (): Promise<Resources> => ({
|
||||
TimestampFilter,
|
||||
TableBrowser,
|
||||
ViewletSetting,
|
||||
CreateAttribute,
|
||||
StringTypeEditor,
|
||||
BooleanTypeEditor,
|
||||
NumberTypeEditor,
|
||||
RefEditor,
|
||||
DateTypeEditor,
|
||||
SpacePresenter,
|
||||
StringEditor,
|
||||
StringPresenter,
|
||||
|
@ -35,12 +35,8 @@ export default mergeIds(viewId, view, {
|
||||
DeleteObjectConfirm: '' as IntlString,
|
||||
Assignees: '' as IntlString,
|
||||
Labels: '' as IntlString,
|
||||
WithTime: '' as IntlString,
|
||||
Type: '' as IntlString,
|
||||
ActionPlaceholder: '' as IntlString,
|
||||
CreatingAttribute: '' as IntlString,
|
||||
RestoreDefaults: '' as IntlString,
|
||||
CreatingAttributeConfirm: '' as IntlString,
|
||||
Filter: '' as IntlString,
|
||||
ClearFilters: '' as IntlString,
|
||||
FilterIs: '' as IntlString,
|
||||
|
@ -389,7 +389,6 @@ const view = plugin(viewId, {
|
||||
component: {
|
||||
ObjectPresenter: '' as AnyComponent,
|
||||
EditDoc: '' as AnyComponent,
|
||||
CreateAttribute: '' as AnyComponent,
|
||||
ViewletSetting: '' as AnyComponent,
|
||||
SpacePresenter: '' as AnyComponent
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user