diff --git a/package.json b/package.json index cdda2e3a8..517bd8e10 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "build:docs-all": "yarn build:typedoc && yarn build:docs", "build:docker": "docker build -t tnocs/csnext .", "publish:npm": "lerna publish --force-publish=*", + "publish:alpha": "lerna publish --force-publish=* --canary --preid alpha --yes", "publish:beta": "lerna publish --force-publish=* --canary --preid beta --yes", "publish:release": "lerna publish from-git --yes", "publish:feature": "lerna publish --force-publish=* --canary --dist-tag crossfilter --preid beta --yes", diff --git a/packages/cs-client/package.json b/packages/cs-client/package.json index 0152a9da1..476965625 100644 --- a/packages/cs-client/package.json +++ b/packages/cs-client/package.json @@ -35,7 +35,8 @@ }, "devDependencies": { "base64-inline-loader": "^1.1.1", - "@mdi/font": "6.6.96" + "@mdi/font": "6.6.96", + "vue-template-compiler": "2.6.14" }, "gitHead": "2dd8a401ccb96079185452d8413f26921fe2063e" } \ No newline at end of file diff --git a/packages/cs-client/src/components/cs-app/cs-app.css b/packages/cs-client/src/components/cs-app/cs-app.css deleted file mode 100644 index f27634b67..000000000 --- a/packages/cs-client/src/components/cs-app/cs-app.css +++ /dev/null @@ -1,116 +0,0 @@ -.cstabs { - margin-top: 0px; -} - -html { - /* overflow-y: hidden !important; */ -} - -.v-toolbar--clipped { - z-index: 4 !important; -} - -.cs-navigation-tabbar { - margin-left: 20px; -} - -.cs-navigation-tabbar .v-tabs__div { - font-size: 20px; - font-weight: 800; -} - -.cs-navigation-tabbar .tabs__bar { - /* background-color: transparent !important; */ -} - -.input-file { - position: fixed; - top: -100em; -} - -.notification-icon { - margin-right: 3px; - margin-top: -3px; -} - - -.dialog-widget { - height: 100%; - width: 100%; -} - -.menu { - background-color: red; -} - -.app-menu { - color: red !important; - /** margin-left:5px; */ -} - -@media only screen and (max-width: 480px) { - .header-breadcrumbs { - display: none !important; - } -} - -.notification-title { - align-self: center; - margin-left: 10px; -} - -.sidebar { - /* z-index:200 !important; */ -} - -.right-sidebar-title { - margin-right: 10px; -} - -.header-breadcrumbs { - padding: 0 !important; -} - -.header-breadcrumbs>li { - padding: 0 !important; -} - -.floating { - margin-top: -64px !important; -} - -.leftsidebar-pin { - float: right; - margin: 4px; -} - -.leftsidebar-minify { - position: absolute; - right: 4px; - bottom: 5px; - z-index: 300; -} - -.content--wrap { - height: 100%; -} - -.app-project-logo { - height: 40px; - margin: 4px; -} - -.invert-logo { - filter: invert(1); -} - -.content { - height: 100%; - padding: 0; -} - -.rightsidebar-toggle { - width: 20px; - height: 20px; - position: absolute; -} \ No newline at end of file diff --git a/packages/cs-client/src/components/cs-app/cs-app.html b/packages/cs-client/src/components/cs-app/cs-app.html deleted file mode 100644 index 2bc997edf..000000000 --- a/packages/cs-client/src/components/cs-app/cs-app.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - -
- - {{ dialog.title }} - - - -
- - - {{ $cs.Translate('CANCEL')}} - - {{ $cs.Translate('OK')}} - - -
-
- -
-
- - - - - {{ action }} - - -
-
-
-
- - - - - - - - - - {{ dashboard.title }} - {{ dashboard.icon }} - - - - - - - - - {{lastNotification.icon}} - - {{ $cs.Translate(lastNotification.title) }} - - - {{ $cs.Translate(lastNotification.buttonText) }} - - - - - - -
\ No newline at end of file diff --git a/packages/cs-client/src/components/cs-app/cs-app.ts b/packages/cs-client/src/components/cs-app/cs-app.vue similarity index 68% rename from packages/cs-client/src/components/cs-app/cs-app.ts rename to packages/cs-client/src/components/cs-app/cs-app.vue index 0f00d0873..7abf90cb5 100644 --- a/packages/cs-client/src/components/cs-app/cs-app.ts +++ b/packages/cs-client/src/components/cs-app/cs-app.vue @@ -1,10 +1,108 @@ + + + + + \ No newline at end of file diff --git a/packages/cs-client/src/components/cs-dashboard/cs-dashboard.css b/packages/cs-client/src/components/cs-dashboard/cs-dashboard.css deleted file mode 100644 index f65f837b8..000000000 --- a/packages/cs-client/src/components/cs-dashboard/cs-dashboard.css +++ /dev/null @@ -1,25 +0,0 @@ -.dashboard-content { - height: 100% !important; - /* overflow-y: hidden; */ -} - -.cs-dashboard { - height: 100%; -} - -.dashboard-toolbar-flex { - max-height: 100% !important; - /* align-items: stretch; */ -} - -.cs-dashboard-col.col { - display: flex; - flex-direction: column; - height: 100%; -} - -.dashboard-stepper { - background: transparent !important; - box-shadow: none !important; - width: 100%; -} diff --git a/packages/cs-client/src/components/cs-dashboard/cs-dashboard.html b/packages/cs-client/src/components/cs-dashboard/cs-dashboard.html deleted file mode 100644 index 95e126e00..000000000 --- a/packages/cs-client/src/components/cs-dashboard/cs-dashboard.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - {{ dashboard.options.icon }} - {{ $cs.Translate(dashboard.title) }} - - - - - - - - - - - - - - diff --git a/packages/cs-client/src/components/cs-dashboard/cs-dashboard.ts b/packages/cs-client/src/components/cs-dashboard/cs-dashboard.vue similarity index 62% rename from packages/cs-client/src/components/cs-dashboard/cs-dashboard.ts rename to packages/cs-client/src/components/cs-dashboard/cs-dashboard.vue index dae57edbc..acd4277c1 100644 --- a/packages/cs-client/src/components/cs-dashboard/cs-dashboard.ts +++ b/packages/cs-client/src/components/cs-dashboard/cs-dashboard.vue @@ -1,13 +1,138 @@ + + + + + \ No newline at end of file diff --git a/packages/cs-client/src/components/cs-header/cs-header.css b/packages/cs-client/src/components/cs-header/cs-header.css index fd2f47d3d..6e768e833 100644 --- a/packages/cs-client/src/components/cs-header/cs-header.css +++ b/packages/cs-client/src/components/cs-header/cs-header.css @@ -2,6 +2,22 @@ margin-left: 20px; } + +@media only screen and (max-width: 480px) { + .header-breadcrumbs { + display: none !important; + } +} + +.header-breadcrumbs { + padding: 0 !important; +} + +.header-breadcrumbs>li { + padding: 0 !important; +} + + #main-toolbar { padding-right: 0px; } diff --git a/packages/cs-client/src/components/cs-header/cs-header.ts b/packages/cs-client/src/components/cs-header/cs-header.ts index 5afecee37..01c5776c9 100644 --- a/packages/cs-client/src/components/cs-header/cs-header.ts +++ b/packages/cs-client/src/components/cs-header/cs-header.ts @@ -9,7 +9,8 @@ import { Loader, } from "@csnext/cs-core"; import { Prop, Watch } from "vue-property-decorator"; -import { AppState, CsApp, CsLanguageSwitch, CsSettings } from "../../"; +import { AppState, CsLanguageSwitch, Constants } from "../../"; +import CsApp from "../cs-app/cs-app.vue"; import { CsToolbarMenus } from "../cs-toolbar-menus/cs-toolbar-menus"; import "./cs-header.css"; @Component({ @@ -44,7 +45,7 @@ export class CsHeader extends Vue { } if (this.$cs.project.header && this.$cs.project.header.showLoadingIcon) { this.loadingMenuIcon = { - id: CsApp.LOADING_MENU_ID, + id: Constants.LOADING_MENU_ID, icon: "autorenew", title: "LOADING", toolTip: "LOADING", @@ -58,11 +59,11 @@ export class CsHeader extends Vue { ) { if ( !this.$cs.project.menus.find( - (menu) => menu.id === CsApp.LANGUAGE_SWITCH_ID + (menu) => menu.id === Constants.LANGUAGE_SWITCH_ID ) ) { this.languageSwitchMenu = { - id: CsApp.LANGUAGE_SWITCH_ID, + id: Constants.LANGUAGE_SWITCH_ID, icon: "translate", title: "LANGUAGE", type: "icon", diff --git a/packages/cs-client/src/components/cs-sidebar/cs-sidebar.ts b/packages/cs-client/src/components/cs-sidebar/cs-sidebar.ts index 78e9fb23b..26dec788b 100644 --- a/packages/cs-client/src/components/cs-sidebar/cs-sidebar.ts +++ b/packages/cs-client/src/components/cs-sidebar/cs-sidebar.ts @@ -75,7 +75,7 @@ export class CsSidebar extends Vue { } } - @Watch('sideBar.dashboard.options.sidebarTemporary') + // @Watch('sideBar.dashboard.options.sidebarTemporary') @Watch('sideBar.temporary') public get sidebarTemporary() { if (this.isExpanded) { return true; } diff --git a/packages/cs-client/src/components/cs-widget/cs-widget.css b/packages/cs-client/src/components/cs-widget/cs-widget.css deleted file mode 100644 index 5bd81d588..000000000 --- a/packages/cs-client/src/components/cs-widget/cs-widget.css +++ /dev/null @@ -1,47 +0,0 @@ -.widget-default { - height: 100%; - width: 100%; - background: transparent; -} - -.widget-container { - height: 100%; -} - -.widget-toolbar { - height: 40px !important; -} - -.widget-buttons-container{ - position:absolute !important; - right: 10px; - top: 3px; - z-index: 1000; -} - -.widget-button{ - /* margin:0 !important; */ - /* width:18px !important; - height:18px !important; */ -} - -.widget-button-icon -{ - width:16px !important; - height:16px !important; -} - - -/* Borders */ - -.widget-border-shadow { - margin: 2px; - box-shadow: 0 1px 7px rgba(0, 0, 0, 0.4); - height: calc(100% - 4px); -} - -.widget-border-line { - border-style: solid; - border-width: 1px; - border-color: black; -} diff --git a/packages/cs-client/src/components/cs-widget/cs-widget.html b/packages/cs-client/src/components/cs-widget/cs-widget.html deleted file mode 100644 index 40385d847..000000000 --- a/packages/cs-client/src/components/cs-widget/cs-widget.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - {{ options.icon }} - {{ $cs.Translate(options.title) }} - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/cs-client/src/components/cs-widget/cs-widget.ts b/packages/cs-client/src/components/cs-widget/cs-widget.vue similarity index 61% rename from packages/cs-client/src/components/cs-widget/cs-widget.ts rename to packages/cs-client/src/components/cs-widget/cs-widget.vue index f3b050a5f..e62ebfd71 100644 --- a/packages/cs-client/src/components/cs-widget/cs-widget.ts +++ b/packages/cs-client/src/components/cs-widget/cs-widget.vue @@ -1,33 +1,84 @@ -import Vue from "vue"; -import Component from "vue-class-component"; -import { - IWidget, - IMenu, - MessageBusService, - MessageBusHandle, - guidGenerator, - WidgetOptions, - Topics, - idGenerator, -} from "@csnext/cs-core"; -import resize from "vue-resize-directive"; -import "./cs-widget.css"; -import { AppState } from "../.."; -import { CsToolbarMenus } from "../cs-toolbar-menus/cs-toolbar-menus"; + + + + + diff --git a/packages/cs-client/src/index.ts b/packages/cs-client/src/index.ts index e9e4efd8d..8d212badf 100644 --- a/packages/cs-client/src/index.ts +++ b/packages/cs-client/src/index.ts @@ -17,7 +17,7 @@ export * from './datasources/log/log-manager'; // layout managers export * from './layout/layout-component'; export * from './layout/single/single'; -export * from './layout/grid-layout/grid-layout'; +// export * from './layout/grid-layout/grid-layout'; export * from './layout/css-grid/css-grid'; export * from './layout/css-grid/css-grid-templates'; export * from './layout/flex-grid/flex-grid'; @@ -28,25 +28,24 @@ export * from './layout/mobile-flow/mobile-flow'; // export * from './layout/drag-grid/drag-layout'; // export * from './layout/drag-grid/drag-layout-options'; export * from './layout/flex-grid/flex-widget-options'; +export * from './utils/constants' // components -import { CsApp } from './components/cs-app/cs-app'; -import { CsWidget } from './components/cs-widget/cs-widget'; -import { CsDashboard } from './components/cs-dashboard/cs-dashboard'; +import CsApp from './components/cs-app/cs-app.vue'; +// import { CsWidget } from './components/cs-widget/cs-widget'; +import CsDashboard from './components/cs-dashboard/cs-dashboard.vue'; +import CsWidget from './components/cs-widget/cs-widget.vue'; +import GridLayout from "./layout/grid-layout/grid-layout.vue"; import { CsSidebar } from './components/cs-sidebar/cs-sidebar'; import Vue, { VueConstructor } from 'vue'; -import { VegaWidget } from './widgets/vega/vega-widget'; import { CardWidget } from './widgets/card/card-widget'; import { HtmlWidget } from './widgets/html-widget/html-widget'; import './components/cs-label'; - import '@mdi/font/css/materialdesignicons.css'; // export components -export * from './components/cs-app/cs-app'; -export * from './components/cs-widget/cs-widget'; -export * from './components/cs-dashboard/cs-dashboard'; +// export * from './components/cs-app/cs-app'; export * from './components/cs-settings/cs-settings'; export * from './components/cs-language-switch/cs-language-switch'; export * from './components/cs-toolbar-menus/cs-toolbar-menus'; @@ -66,18 +65,16 @@ export * from './widgets/intro/intro-widget-options'; export * from './widgets/card/card-widget'; export * from './widgets/card/card-widget-options'; export * from './components/cs-label'; +export { CsApp, CsDashboard, CsWidget, GridLayout }; - - + export const CsNext = { install: (vue: VueConstructor): void => { const a = AppState.Instance; vue.component('cs-dashboard', CsDashboard); vue.component('cs-widget', CsWidget); vue.component('cs-app', CsApp); - vue.component('cs-sidebar', CsSidebar); - vue.component('cs-widget', CsWidget); - vue.component('vega-widget', VegaWidget); + vue.component('cs-sidebar', CsSidebar); vue.component('vega-widget', HtmlWidget); vue.component('card-widget', CardWidget); } diff --git a/packages/cs-client/src/layout/grid-layout/grid-layout.css b/packages/cs-client/src/layout/grid-layout/grid-layout.css deleted file mode 100644 index 92e232b5a..000000000 --- a/packages/cs-client/src/layout/grid-layout/grid-layout.css +++ /dev/null @@ -1,8 +0,0 @@ -.grid-manager { - left: 0; - right: 0; - top: 0; - bottom: 0; - /* position: relative; */ - -} diff --git a/packages/cs-client/src/layout/grid-layout/grid-layout.html b/packages/cs-client/src/layout/grid-layout/grid-layout.html deleted file mode 100644 index cabdebe2e..000000000 --- a/packages/cs-client/src/layout/grid-layout/grid-layout.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/packages/cs-client/src/layout/grid-layout/grid-layout.ts b/packages/cs-client/src/layout/grid-layout/grid-layout.vue similarity index 57% rename from packages/cs-client/src/layout/grid-layout/grid-layout.ts rename to packages/cs-client/src/layout/grid-layout/grid-layout.vue index 4463d94de..ef3359f1d 100644 --- a/packages/cs-client/src/layout/grid-layout/grid-layout.ts +++ b/packages/cs-client/src/layout/grid-layout/grid-layout.vue @@ -1,19 +1,22 @@ + + + + diff --git a/packages/cs-client/src/services/app-state.ts b/packages/cs-client/src/services/app-state.ts index 6333ff868..430afc2c5 100644 --- a/packages/cs-client/src/services/app-state.ts +++ b/packages/cs-client/src/services/app-state.ts @@ -14,6 +14,7 @@ import { IMenu, INotificationOptions, idGenerator, + SyncStore } from '@csnext/cs-core'; // tslint:disable-next-line:no-var-requires import { @@ -34,6 +35,8 @@ import { DefaultProject } from './default-project'; import { KeyboardManager } from './keyboard-manager'; import { Framework } from 'vuetify'; + + /** AppState is a singleton class used for project defintion, keeping track of available dashboard managers and datasource handlers. It also includes a generic EventBus and logger instance */ export class AppState extends AppStateBase { public static DIALOG = 'dialog'; @@ -62,6 +65,8 @@ export class AppState extends AppStateBase { public static FILE_UPLOAD_START = 'file-upload-start'; public static LEFT_SIDEBAR_STATE = 'lsb'; + + /** used for singleton */ private static pInstance: AppState; @@ -642,18 +647,18 @@ export class AppState extends AppStateBase { return new Promise((resolve) => { const cb = (action: string) => { resolve( - action === this.Translate(AppState.YES) ? AppState.YES : AppState.NO + action === this.translate(AppState.YES) ? AppState.YES : AppState.NO ); }; const d = { fullscreen: false, toolbar: true, - title: this.Translate(title), - text: this.Translate(text), + title: this.translate(title), + text: this.translate(text), visible: true, persistent: true, width: 400, - actions: [this.Translate(AppState.YES), this.Translate(AppState.NO)], + actions: [this.translate(AppState.YES), this.translate(AppState.NO)], actionCallback: cb, } as IDialog; this.triggerDialog(d); @@ -668,12 +673,12 @@ export class AppState extends AppStateBase { const d = { fullscreen: false, toolbar: true, - title: this.Translate(title), - text: this.Translate(text), + title: this.translate(title), + text: this.translate(text), visible: true, persistent: true, width: 400, - actions: actions.map((a) => this.Translate(a)), + actions: actions.map((a) => this.translate(a)), } as IDialog; return this.triggerDialog(d); } @@ -688,8 +693,8 @@ export class AppState extends AppStateBase { const d = { fullscreen: false, toolbar: true, - title: this.Translate(title), - text: this.Translate(text), + title: this.translate(title), + text: this.translate(text), visible: true, textInput: true, defaultText: defaultValue, @@ -991,7 +996,32 @@ export class AppState extends AppStateBase { } } + public static parseStateValue(state: any, value: string) { + if (value?.startsWith('$state')) { + const stateValue = state[value.substring(7)]; + if (stateValue) { + return stateValue; + } + } + return value; + } + + public setState(store: SyncStore, key: string, value: any) { + switch (store) { + case 'global': { + $cs.data[key] = value; + } + } + } + + /** + * @deprecated use translate + */ public Translate(textKey: string, values?: { [key: string]: any }): string { + return this.translate(textKey, values); + } + + public translate(textKey: string, values?: { [key: string]: any }): string { if (this.i18n) { return this.i18n.t(textKey, values).toString(); } else { diff --git a/packages/cs-client/src/utils/constants.ts b/packages/cs-client/src/utils/constants.ts new file mode 100644 index 000000000..f58aba873 --- /dev/null +++ b/packages/cs-client/src/utils/constants.ts @@ -0,0 +1,5 @@ +export class Constants { + public static LANGUAGE_SWITCH_ID = 'switch_language'; + public static LOADING_MENU_ID = 'loading_menu'; + +} \ No newline at end of file diff --git a/packages/cs-client/src/utils/shimx-vue.d.ts b/packages/cs-client/src/utils/shimx-vue.d.ts new file mode 100644 index 000000000..820e82b69 --- /dev/null +++ b/packages/cs-client/src/utils/shimx-vue.d.ts @@ -0,0 +1,6 @@ +declare module "*.vue" { + import Vue from "vue"; + export default Vue; + } + + \ No newline at end of file diff --git a/packages/cs-client/src/widgets/widget-base.ts b/packages/cs-client/src/widgets/widget-base.ts index b1eabe406..7d8e44e16 100644 --- a/packages/cs-client/src/widgets/widget-base.ts +++ b/packages/cs-client/src/widgets/widget-base.ts @@ -1,6 +1,6 @@ import Vue from 'vue'; import Component from 'vue-class-component'; -import { IWidget, IMessageBusService, IMessageBusCallback, MessageBusManager, IMenu } from '@csnext/cs-core'; +import { IWidget, IMessageBusService, IMessageBusCallback, MessageBusManager, IMenu, SyncStore } from '@csnext/cs-core'; import { Logger } from '../'; @Component({ @@ -19,9 +19,7 @@ export class WidgetBase extends Vue { super(); } - public get state() : any { - console.log('get data') - console.log(this); + public get state() : any { if (this.widget?.options?.sync) { switch (this.widget.options.sync) { case 'dashboard': return this.widget?._dashboard?.data; diff --git a/packages/cs-core/src/card/card-options.ts b/packages/cs-core/src/card/card-options.ts new file mode 100644 index 000000000..944c5fde6 --- /dev/null +++ b/packages/cs-core/src/card/card-options.ts @@ -0,0 +1,5 @@ +export enum CardSize { + small = 'small', + medium = 'medium', + large = 'large' +} \ No newline at end of file diff --git a/packages/cs-core/src/form/form-decorators.ts b/packages/cs-core/src/form/form-decorators.ts index 13ef9665f..2250be93a 100644 --- a/packages/cs-core/src/form/form-decorators.ts +++ b/packages/cs-core/src/form/form-decorators.ts @@ -91,6 +91,8 @@ export interface IFormFieldOptions extends IFormFieldBaseOptions { canEditKey?: boolean; data?: any; placeholder?: string; + filled?: boolean; + rounded?: boolean; addUsingDialog?: boolean; newItem?: ()=>any; readonly?: boolean; diff --git a/packages/cs-core/src/index.ts b/packages/cs-core/src/index.ts index ccf43c33c..d730ce0de 100644 --- a/packages/cs-core/src/index.ts +++ b/packages/cs-core/src/index.ts @@ -46,5 +46,8 @@ export * from './utils/guid'; export * from './utils/function'; export * from './utils/info'; export * from './utils/loader'; +export * from './utils/sync-store'; export * from './form/form-decorators'; + +export * from './card/card-options'; diff --git a/packages/cs-core/src/interactions/dialog.ts b/packages/cs-core/src/interactions/dialog.ts index bf130880c..939d709d8 100644 --- a/packages/cs-core/src/interactions/dialog.ts +++ b/packages/cs-core/src/interactions/dialog.ts @@ -18,5 +18,5 @@ export interface IDialog { data?: any; width?: number | string; actions?: string[]; - actionCallback?(action: string); + actionCallback?(action: string, data?: string); } diff --git a/packages/cs-core/src/interactions/menu.ts b/packages/cs-core/src/interactions/menu.ts index 8af2858df..583ef1249 100644 --- a/packages/cs-core/src/interactions/menu.ts +++ b/packages/cs-core/src/interactions/menu.ts @@ -21,7 +21,8 @@ export interface IMenu { toolTip?: string; method?: string; items?: IMenu[]; - action?: (menu: IMenu, dashboard?: IDashboard) => void; + isActive?: boolean | Function; + action?: (menu: IMenu, dashboard?: IDashboard, options?: any) => void; component?: any; plugin?: any; widget?: IWidget; diff --git a/packages/cs-core/src/utils/sync-store.ts b/packages/cs-core/src/utils/sync-store.ts new file mode 100644 index 000000000..274f080e5 --- /dev/null +++ b/packages/cs-core/src/utils/sync-store.ts @@ -0,0 +1 @@ +export type SyncStore = 'widget' | 'dashboard' | 'manager' | 'datasource' | 'global'; \ No newline at end of file diff --git a/packages/cs-core/src/widget/widget-options.ts b/packages/cs-core/src/widget/widget-options.ts index 1814605f3..022aa8d74 100644 --- a/packages/cs-core/src/widget/widget-options.ts +++ b/packages/cs-core/src/widget/widget-options.ts @@ -1,5 +1,6 @@ import { IMenu, ToolbarOptions } from './../'; import { FormField, Form } from '../form/form-decorators'; +import { SyncStore } from '../utils/sync-store'; @Form({ title: 'Widget Options' }) export class WidgetOptions { @@ -50,5 +51,5 @@ export class WidgetOptions { public hideSidebarButton?: boolean; /** if using a cssgrid dashboard with area defintions, you can define the area defintition here */ public area?: string; - public sync?: 'widget' | 'dashboard' | 'manager' | 'datasource' | 'global'; + public sync?: SyncStore; } diff --git a/packages/cs-data/src/classes/filter/graph-filter.ts b/packages/cs-data/src/classes/filter/graph-filter.ts index 480cf692c..1d3d8d437 100644 --- a/packages/cs-data/src/classes/filter/graph-filter.ts +++ b/packages/cs-data/src/classes/filter/graph-filter.ts @@ -1,6 +1,6 @@ import { PropertyType } from '../..'; -export type ValueOperatorType = ">" | ">=" | "<" | "<=" | "==" | "!=" | 'set' | 'not set'; +export type ValueOperatorType = ">" | ">=" | "<" | "<=" | "==" | "!=" | 'set' | 'not set' | 'includes'; export class GraphFilter { public hasIncomingTypeRelation?: any; @@ -18,6 +18,6 @@ export class GraphElementFilter { export class GraphPropertyFilter { public property?: any; public operator!: ValueOperatorType; - public value?: any; + public value?: any | any[]; public _property?: PropertyType; } \ No newline at end of file diff --git a/packages/cs-data/src/classes/graph/filter-graph-element.ts b/packages/cs-data/src/classes/graph/filter-graph-element.ts index d87545459..75b699b13 100644 --- a/packages/cs-data/src/classes/graph/filter-graph-element.ts +++ b/packages/cs-data/src/classes/graph/filter-graph-element.ts @@ -46,6 +46,10 @@ export class GraphLayout { unitRadius?: number; kr?: number; kg?: number; + /** node seperation for dagre layout in px */ + nodesep?: number; + /** level seperation for dagre layout in px */ + ranksep?: number; defaultEdgeType?: string; collideStrength?: number; alpha?: number; diff --git a/packages/cs-data/src/classes/graph/graph-element.ts b/packages/cs-data/src/classes/graph/graph-element.ts index 95647ccbe..12a8647de 100644 --- a/packages/cs-data/src/classes/graph/graph-element.ts +++ b/packages/cs-data/src/classes/graph/graph-element.ts @@ -113,12 +113,7 @@ export class GraphElement { e: GraphElement, activated?: boolean ): string { - if (e.backgroundColor !== undefined) { - if (activated !== null) { - if (!activated) { - return e.backgroundColor; - } - } + if (e.backgroundColor !== undefined) { return e.backgroundColor; } else if (e._featureType?.color) { e.backgroundColor = e._featureType.color; diff --git a/packages/cs-data/src/classes/types/feature-type.ts b/packages/cs-data/src/classes/types/feature-type.ts index b678ad497..00dc340b7 100644 --- a/packages/cs-data/src/classes/types/feature-type.ts +++ b/packages/cs-data/src/classes/types/feature-type.ts @@ -30,6 +30,7 @@ export class FeatureType { public notification?: string; public array?: boolean; public isEdge?: boolean; + public descriptiveProperties?: string[]; // public featureType?: string; // public _featureType?: FeatureType; // public patterns?: ObservationPattern[]; diff --git a/packages/cs-data/src/classes/types/meta-entity.ts b/packages/cs-data/src/classes/types/meta-entity.ts index f518f7132..1abecc86d 100644 --- a/packages/cs-data/src/classes/types/meta-entity.ts +++ b/packages/cs-data/src/classes/types/meta-entity.ts @@ -5,9 +5,10 @@ export class MetaEntity { public text?: string; public id?: string; public kg_id?: string; + public source?: string; public _node?: GraphElement; public _edge?: GraphElement; - public _included?: boolean; - public _approved?: boolean; + // public _included?: boolean; + public _linked?: boolean; // public _relations?: TextRelation[]; } \ No newline at end of file diff --git a/packages/cs-data/src/data-sources/graph-datasource.ts b/packages/cs-data/src/data-sources/graph-datasource.ts index 4fdb12b56..337218f07 100644 --- a/packages/cs-data/src/data-sources/graph-datasource.ts +++ b/packages/cs-data/src/data-sources/graph-datasource.ts @@ -513,6 +513,8 @@ export class GraphDatasource extends DataSource { return (propVal !== undefined && propVal !== null); case 'not set': return (propVal === undefined || propVal === null); + case 'includes': + return propVal !== undefined && propVal.includes(propVal); default: console.log(`Unknown ValueOperatorType ${operator}`); return false; @@ -540,7 +542,8 @@ export class GraphDatasource extends DataSource { public getClassElements( classId: string, traversal?: boolean, - filter?: GraphFilter + filter?: GraphFilter, + state?: any ): GraphElement[] { let res: GraphElement[] = []; if (traversal) { @@ -615,8 +618,8 @@ export class GraphDatasource extends DataSource { ) ) { const value = filter.hasIncomingTypeRelation[field]; - const v = typeof value === 'function' ? value() : value; - if (r.classId === field && r.from?.id === v) { + const v = typeof value === 'function' ? value(r, state) : value; + if (r.classId === field && r.fromId === v) { return true; } } @@ -1017,13 +1020,15 @@ export class GraphDatasource extends DataSource { ); } - public searchFuse(query: string, featureType?: string, traversal = false) { + public searchFuse(query: string, featureType?: string, traversal = false, options?: { nlp?: string}) { if (!this.fuse) { return []; } let res = this.fuse.search(query); - if (featureType) { + if (options?.nlp) { + res = res.filter(r => r.item._featureType?.attributes && r.item._featureType.attributes['nlp:entity_class'] && r.item._featureType.attributes['nlp:entity_class'] === options.nlp); + } else if (featureType) { res = res.filter(r => r.item._featureType?._inheritedTypes && r.item._featureType._inheritedTypes.includes(featureType)); } return res; diff --git a/packages/cs-form/src/components/cs-form-field/cs-form-field.html b/packages/cs-form/src/components/cs-form-field/cs-form-field.html index 0586182ce..1de5dcecc 100644 --- a/packages/cs-form/src/components/cs-form-field/cs-form-field.html +++ b/packages/cs-form/src/components/cs-form-field/cs-form-field.html @@ -15,6 +15,8 @@ :hint="field.hint" itemText="title" hide-no-data + :filled="field.filled" + :rounded="field.rounded" clearable :return-object="false" itemValue="image" @@ -84,6 +86,8 @@ @@ -138,6 +144,8 @@ :disabled="field.readonly" :label="$cs.Translate(field.title)" @blur="fieldUpdated(field)" + :filled="field.filled" + :rounded="field.rounded" type="date" > @@ -158,6 +166,8 @@ mdi-clock-outline @@ -309,6 +331,8 @@ inset :label="$cs.Translate(field.title)" :hint="field.hint" + :filled="field.filled" + :rounded="field.rounded" :persistentHint="field.persistentHint" v-model="target[field._key]" :disabled="field.readonly" @@ -323,6 +347,8 @@ :key="option" :label="option" :value="option" + :filled="field.filled" + :rounded="field.rounded" @change="fieldUpdated(field)" :disabled="field.readonly" v-model="target[field._key]" @@ -334,6 +360,8 @@ v-if="field._key" v-model.number="target[field._key]" type="number" + :filled="field.filled" + :rounded="field.rounded" :rules="[rules.valueMin, rules.valueMax, rules.required]" :label="$cs.Translate(field.title)" :clearable="field.clearable" @@ -351,6 +379,8 @@ :required="field.required" :clearable="field.clearable" :hint="field.hint" + :filled="field.filled" + :rounded="field.rounded" :persistentHint="field.persistentHint" :disabled="field.readonly" @change="fieldUpdated(field)" diff --git a/packages/cs-form/src/components/cs-form/cs-form.css b/packages/cs-form/src/components/cs-form/cs-form.css index eabdbc476..50895b1f0 100644 --- a/packages/cs-form/src/components/cs-form/cs-form.css +++ b/packages/cs-form/src/components/cs-form/cs-form.css @@ -6,4 +6,10 @@ .form-title { font-weight: 600; font-size: 125%; - } \ No newline at end of file + } + +.optional-field-title { + font-weight: 600; + + +} \ No newline at end of file diff --git a/packages/cs-form/src/components/cs-form/cs-form.html b/packages/cs-form/src/components/cs-form/cs-form.html index bc485f583..17f229577 100644 --- a/packages/cs-form/src/components/cs-form/cs-form.html +++ b/packages/cs-form/src/components/cs-form/cs-form.html @@ -30,9 +30,10 @@ - +
+
mdi-plus Add optional field
+ {{field.icon}}mdi-plus{{field.title || field._key}} +
diff --git a/packages/cs-form/src/components/fields/chips-editor.vue b/packages/cs-form/src/components/fields/chips-editor.vue index cc5232e81..2e5110904 100644 --- a/packages/cs-form/src/components/fields/chips-editor.vue +++ b/packages/cs-form/src/components/fields/chips-editor.vue @@ -10,6 +10,8 @@ :hint="field.hint" :persistentHint="field.persistentHint" :clearable="field.clearable" + :filled="field.filled" + :rounded="field.rounded" solo multiple text diff --git a/packages/cs-form/src/components/fields/group-buttons-editor.vue b/packages/cs-form/src/components/fields/group-buttons-editor.vue index 35cf033f0..2bcfc53e2 100644 --- a/packages/cs-form/src/components/fields/group-buttons-editor.vue +++ b/packages/cs-form/src/components/fields/group-buttons-editor.vue @@ -4,7 +4,7 @@ v-model="target[field._key]" tile :hint="field.hint" - + class="group-btn-toggle" @change="fieldUpdated(field)" group > @@ -31,6 +31,9 @@ diff --git a/packages/cs-graph/src/components/datamodel/class-viewer.vue b/packages/cs-graph/src/components/datamodel/class-viewer.vue index c92c6ed2f..8f7767b58 100644 --- a/packages/cs-graph/src/components/datamodel/class-viewer.vue +++ b/packages/cs-graph/src/components/datamodel/class-viewer.vue @@ -28,6 +28,7 @@ import simplebar from 'simplebar-vue'; import G6, { Graph, GraphData } from '@antv/g6'; import { FeatureType, RelationType } from '@csnext/cs-data'; +import { GraphUtils } from '../..'; @Component({ components: { simplebar }, @@ -96,7 +97,7 @@ export default class ClassViewer extends WidgetBase { let node = { id: e.type, classId: e.type, - label: this.fittingString(e.title!, 50, 10), + label: GraphUtils.fittingString(e.title!, 80, 10), title: e.title, hidden: false, style: { @@ -164,44 +165,14 @@ export default class ClassViewer extends WidgetBase { } } - private fittingString(str: string, maxWidth: number, fontSize: number) { - let currentWidth = 0; - let res = str; - const pattern = new RegExp('[ ]+'); // distinguish the Chinese charactors and letters - str.split('').forEach((letter, i) => { - if (currentWidth > maxWidth) return; - if (pattern.test(letter)) { - // Chinese charactors - currentWidth += fontSize; - } else { - // get the width of single letter according to the fontSize - currentWidth += G6.Util.getLetterWidth(letter, fontSize); - } - if (currentWidth > maxWidth) { - res = `${str.substr(0, i)}\n${str.substr(i)}`; - } - }); - return res; - } - public updateGraph() { if (!this.graphSource?.featureTypes || !this.graph) { return; } - // if (!this.data) { this.data = { nodes: [], edges: [] }; - // this.graph.data(this.data); - // } for (const e of Object.values(this.graphSource.featureTypes)) { if (e.type && !e.isEdge) { - this.updateNode(e); - // if (e.class) { - // this.updateEdge({ - // source: e.id, - // target: e.class.id, - // label: "is", - // } as any); - // } + this.updateNode(e); } } diff --git a/packages/cs-graph/src/components/document-management/relation-editor.vue b/packages/cs-graph/src/components/document-management/relation-editor.vue index 2d37f7b88..4aef46aab 100644 --- a/packages/cs-graph/src/components/document-management/relation-editor.vue +++ b/packages/cs-graph/src/components/document-management/relation-editor.vue @@ -4,7 +4,7 @@
diff --git a/packages/cs-graph/src/components/document/document-viewer.vue b/packages/cs-graph/src/components/document/document-viewer.vue index 119e12d53..2015f766b 100644 --- a/packages/cs-graph/src/components/document/document-viewer.vue +++ b/packages/cs-graph/src/components/document/document-viewer.vue @@ -16,7 +16,7 @@
- + - + + + + {{ action.icon }} + mdi-import @@ -86,76 +93,90 @@ - +
+
- {{ currentDocument.properties.name }} + + + mdi-content-save + mdi-pencil + + + {{ currentDocument.properties.name }} +
Created {{ publishedDate() }} ago, @@ -204,7 +225,7 @@ :editor="editor" />
- +
@@ -214,42 +235,41 @@ import { WidgetBase } from '@csnext/cs-client'; import { DateUtils, FeatureType, TextEntity } from '@csnext/cs-data'; import { SimpleRelationLineSection } from '@csnext/cs-map'; import Dropcursor from '@tiptap/extension-dropcursor'; -import Mention from "@tiptap/extension-mention"; +import Mention from '@tiptap/extension-mention'; import Highlight from '@tiptap/extension-highlight'; import Placeholder from '@tiptap/extension-placeholder'; import StarterKit from '@tiptap/starter-kit'; import { BubbleMenu, Editor, EditorContent, FloatingMenu, Node } from '@tiptap/vue-2'; -import simplebar from 'simplebar-vue'; +// import simplebar from 'simplebar-vue'; import { Component, Prop, Ref, Vue } from 'vue-property-decorator'; -import { IImportPlugin } from '../..'; +import { IImportPlugin, suggestion } from '../..'; import { DocUtils } from '../../utils/doc-utils'; import { DocDatasource, GraphDocument, ITool } from './../../'; import Commands from './plugins/commands/commands'; import commandSuggestion from './plugins/commands/commands-suggestion'; -import ElementCardExtension from './plugins/element-card-extension'; -import ParagraphExtension from './plugins/paragraph-extension'; -import SnippetList from './plugins/snippet-list.vue'; -import SuggestionList from './plugins/text-entity-suggestion/suggestion-list.vue'; -import suggestion from './plugins/text-entity-suggestion/suggestion'; +import ElementCardExtension from './nodes/element-card/element-card-extension'; + +import ParagraphExtension from './nodes/node-paragraph/paragraph-extension'; +import ElementPropertyExtension from './nodes/element-property/element-property-extension'; + +import TaskList from '@tiptap/extension-task-list'; +import TaskItem from '@tiptap/extension-task-item'; import ActionList from './plugins/text-action/text-action-list.vue'; import textAction from './plugins/text-action/text-action'; -import TextExtension from './plugins/text-extension'; -import { TextMention } from './plugins/text-mention'; +import TextExtension from './nodes/text-entity/text-extension'; import SelectionPopup from './selection-popup.vue'; - +import { IMenu } from '@csnext/cs-core'; @Component({ components: { - simplebar, + // simplebar, EditorContent, BubbleMenu, FloatingMenu, SimpleRelationLineSection, - SuggestionList, ActionList, - SnippetList, // EditorMenuBubble, SelectionPopup, }, @@ -264,6 +284,12 @@ export default class DocumentViewer extends WidgetBase { public dragInitialized = false; public contextMenuitems: any[] = []; + // actions that apply to part of document (bold, heading, etc.) + public documentToolsMenu: IMenu[] = []; + + // tools that apply to whole document + public documentActionsMenu: IMenu[] = []; + public set editor(value: Editor | undefined | null) { if (this.source) { this.source.editor = value; @@ -271,7 +297,93 @@ export default class DocumentViewer extends WidgetBase { } public get hideHeader(): boolean { - return ((this.widget?.options) as any).hideHeader || false; + return (this.widget?.options as any).hideHeader || false; + } + + public toggleTitle() { + this.editTitle = !this.editTitle; + if (!this.editTitle && this.source && this.currentDocument) { + this.source.saveNode(this.currentDocument); + } + } + + public async selectDocumentTool(tool: IMenu) { + if (tool.action && this.currentDocument) { + await tool.action(tool); + } + } + + public async selectDocumentAction(tool: IMenu) { + if (tool.action && this.currentDocument) { + await tool.action(tool); + } + } + + public updateDocumentTools() { + this.documentToolsMenu = [ + { + icon: 'mdi-label', + action: (m, a) => { + this.setTextEntity(); + }, + isActive: false, + }, + { + icon: 'mdi-card', + action: () => { + this.setElementCard(); + }, + }, + { + icon: 'mdi-format-bold', + action: () => { + this.editor!.chain().focus().toggleBold().run(); + }, + isActive: ()=> this.editor!.isActive('bold') + }, + { + icon: 'mdi-format-italic', + action: () => { + this.editor!.chain().focus().toggleItalic().run(); + }, + }, + { + icon: 'mdi-format-strikethrough', + action: () => { + this.editor!.chain().focus().toggleStrike().run(); + }, + }, + ]; + } + + // + // mdi-format-bold + // + // + // mdi-format-italic + // + // + // mdi-format-strikethrough + // + // + // mdi-marker + // + + public updateDocumentActions() { + if (!this.source?.tools || !this.currentDocument) { + return; + } + this.documentActionsMenu.splice(0, this.documentToolsMenu.length); + for (const tool of this.source.tools) { + if (tool.documentActions && typeof tool.documentActions === 'function') { + let actions = tool.documentActions(this.currentDocument); + if (actions) { + for (const mi of actions) { + this.documentActionsMenu.push(mi); + } + } + } + } } @Prop() @@ -290,6 +402,7 @@ export default class DocumentViewer extends WidgetBase { public isLoading?: boolean; public showPopup = true; public extendedToolbar = false; + public editTitle = false; // public document?: GraphDocument; public node?: Node; // v-if="selectionTo !== undefined && selectionFrom !== undefined" @@ -298,6 +411,8 @@ export default class DocumentViewer extends WidgetBase { public source: DocDatasource | undefined = undefined; public entityBubbleSelection: FeatureType | null = null; + public doc; + public setEntity() { if (!this.source || !this.currentDocument || !this.editor || !this.entityBubbleSelection?.type) { return; @@ -306,8 +421,6 @@ export default class DocumentViewer extends WidgetBase { this.editor.chain().focus().setTextEntity({ spacy_label: this.entityBubbleSelection?.type }).run(); this.syncDocumentState(); DocUtils.syncEntities(this.currentDocument, this.source, this.currentDocument.properties?.doc?.content, true); - - // alert(this.entityBubbleSelection?.title); } public setEditorMode(mode: string) { @@ -316,7 +429,6 @@ export default class DocumentViewer extends WidgetBase { this.editor!.setEditable(mode === 'EDIT'); } this.$forceUpdate(); - // this.currentDocument!.properties!.edit_mode = mode; } public setElementCard() { @@ -340,22 +452,8 @@ export default class DocumentViewer extends WidgetBase { } this.editor.chain().focus().toggleNodeParagraph().run(); - // this.syncDocumentState(); - // this.source.syncEntities( - // this.currentDocument, - // this.currentDocument.doc.content, - // true - // ); - - // alert(this.entityBubbleSelection?.title); } - // public get document(): GraphDocument | undefined { - // if (this.currentDocument) { - // return this.currentDocument; - // } - // } - public updateContextMenu() { this.contextMenuitems = []; this.contextMenuitems.push({ @@ -395,19 +493,6 @@ export default class DocumentViewer extends WidgetBase { DocUtils.syncEntities(this.currentDocument, this.source, this.currentDocument.properties?.doc?.content, true); } - // public setTextParagraph() { - // if (!this.currentDocument || !this.editor) { - // return; - // } - // this.editor.chain().focus().setTextParagraph().run(); - // this.syncDocumentState(); - // this.source.syncEntities( - // this.currentDocument, - // this.currentDocument.doc.content, - // true - // ); - // } - public beforeDestroy() { if (!this.editor) { return; @@ -429,10 +514,12 @@ export default class DocumentViewer extends WidgetBase { public currentDocument: GraphDocument | undefined; public openElement(document: GraphDocument) { - this.loadDocument(document); - this.updateEditor(); - this.updateContent(); - this.initTools(); + Vue.nextTick(()=> { + this.loadDocument(document); + this.updateEditor(); + this.updateContent(); + this.initTools(); + }) } public testEntity() { @@ -481,10 +568,10 @@ export default class DocumentViewer extends WidgetBase { public updateStartMenu() { if (!this.currentDocument?.properties?.doc) { - this.startMenu = true; - } else { - this.startMenu = false; - } + this.startMenu = true; + } else { + this.startMenu = false; + } } public updateEditor(destroy = true) { @@ -493,21 +580,13 @@ export default class DocumentViewer extends WidgetBase { return; } - - - - // this.highlight = new Highlight({ - // disableRegex: false, - // // entities: this.currentDocument?.entities - // }); - if (this.editor && destroy) { this.editor.destroy(); this.source.editor = undefined; } if (!this.editor) { - this.editor = new Editor({ + extensions: [ StarterKit, // SmilieReplacer, @@ -515,19 +594,21 @@ export default class DocumentViewer extends WidgetBase { Dropcursor, ParagraphExtension, ElementCardExtension, + ElementPropertyExtension, + TaskList, + TaskItem, Highlight, Placeholder, Commands.configure({ commandSuggestion, }), Mention.extend({ - name: 'text-action'}).configure({ - suggestion: textAction - }), - TextMention.configure({ - // renderLabel: (props) => { - // return 'text-entity' - // }, + document: this.currentDocument, + name: 'text-action', + }).configure({ + suggestion: textAction, + }), + Mention.configure({ HTMLAttributes: { class: 'text-entity', name: 'text-entity', @@ -535,25 +616,7 @@ export default class DocumentViewer extends WidgetBase { suggestion, }), ], - onTransaction({ transaction }) { - // transaction. - // if (transaction.steps) { - // for (const step of transaction.steps) { - // console.log(step); - // } - // } - // console.log(transaction); - // debugger; - }, - // content: ` - //

- // This is still the text editor you’re used to, but enriched with node views. - //

- // component 1 - //

- // Did you see that? That’s a Vue component. We are really living in the future. - //

- // `, + onTransaction({ transaction }) {}, content: this.currentDocument?.properties?.doc, editable: true, editorProps: { @@ -581,7 +644,7 @@ export default class DocumentViewer extends WidgetBase { type: 'doc', content: [ { - type: 'paragraph', + type: 'node-paragraph', content: [ { type: 'text', @@ -593,27 +656,14 @@ export default class DocumentViewer extends WidgetBase { }; } this.currentDocument = doc; - this.state.element = doc; + + // check if entities from document are also included in doc._entities + DocUtils.syncEntities(doc, this.source!, doc.properties.doc.content, false); + // link doc._entities to graph entities + this.source.parseEntities(doc); this.loaded = true; - - // this.source.activateDocument(doc).then(() => { - // this.widget.options!.title = doc.name; - // if (this.currentDocument) { - // // this.source?.openDocumentDetails(this.currentDocument, false); - // if (this.currentDocument._entities) { - // for (const ent of this.currentDocument._entities) { - // if (ent._node) { - // // ent._node._included = true; - // } - // } - // } - - // this.loaded = true; - // this.busManager.subscribe(this.source!.bus, 'document-entities', () => {}); - // } - // }); } } @@ -658,16 +708,6 @@ export default class DocumentViewer extends WidgetBase { this.updateEditor(); } - if (this.currentDocument.properties?.doc) { - // this.currentDocument.properties.doc = JSON.parse( - // JSON.stringify(this.currentDocument.properties.doc, (key, value: any) => { - // if (value === null) { - // return undefined; - // } - // return value; - // })) - } - this.editor?.chain().clearContent().setContent(this.currentDocument.properties?.doc, false).run(); this.updateEntityTypes(); }); @@ -726,6 +766,7 @@ export default class DocumentViewer extends WidgetBase { this.currentDocument.properties!.doc = d.properties.doc; this.updateContent(); DocUtils.syncEntities(this.currentDocument!, this.source!, this.currentDocument!.properties!.doc, true); + this.source!.parseEntities(this.currentDocument!); } }); } @@ -748,7 +789,7 @@ export default class DocumentViewer extends WidgetBase { } plugin .callImport(this.currentDocument, this.source) - .then((r) => { + .then((r) => { this.updateContent(); }) .catch((e) => {}) @@ -773,71 +814,74 @@ export default class DocumentViewer extends WidgetBase { return; } this.source = source; - this.updateContextMenu(); + console.log('document content loaded'); this.busManager.subscribe(this.source!.bus, DocDatasource.DOCUMENT_ENTITIES, (a: string, d: any) => { if (a === DocDatasource.ENTITIES_UPDATED) { console.log('document content updated from messagebus'); - this.checkDocumentIdQuery(); - this.updateEditor(); - this.updateContent(); - this.initTools(); - this.$forceUpdate(); + // this.checkDocumentIdQuery(); } }); this.busManager.subscribe(this.source!.bus, 'document', (a: string, d: any) => { - this.updateEditor(); - this.updateContent(); - this.initTools(); + console.log('document updated'); + this.$forceUpdate(); + // this.updateEditor(); + // this.updateContent(); + // this.initTools(); }); - if (this.state && this.state.elementId) { - const doc = this.source.getElement(this.state.elementId) as GraphDocument; - this.loadDocument(doc); - this.updateEditor(); - this.updateContent(); - this.initTools(); + if (this.state && this.state.elementid) { + const doc = this.source.getElement(this.state.elementid) as GraphDocument; + this.openElement(doc); + } else if (this.checkDocumentIdQuery()) { + console.log('got from uri') } else { - this.checkDocumentIdQuery(); - this.updateEditor(); - this.updateContent(); - this.initTools(); + if (this.state?.element) { + this.openElement(this.state.element); + } } + // this.initTools(); this.initDragging(); + this.updateContextMenu(); } - private checkDocumentIdQuery() { + private checkDocumentIdQuery() : boolean { if (!$cs.router || !this.source) { - return; + return false; } - if ($cs.router.currentRoute?.query?.id) { - if (this.currentDocument?.id !== $cs.router!.currentRoute?.query?.id) { - const doc = this.source.getElement($cs.router.currentRoute.query.id as string) as GraphDocument; + if ($cs.router.currentRoute?.query?.docid) { + if (this.currentDocument?.id !== $cs.router!.currentRoute?.query?.docid) { + const doc = this.source.getElement($cs.router.currentRoute.query.docid as string) as GraphDocument; if (doc) { - this.loadDocument(doc); + this.openElement(doc); } } else { - this.loadDocument(this.currentDocument); - } - } else { - let d: GraphDocument = (this.source.activeElement as GraphDocument) || this.currentDocument; - if (d) { - this.loadDocument(d); - - const combined = { - ...$cs.router!.currentRoute.query, - ...{ id: d.id }, - }; - $cs.router.replace( - { path: $cs.router!.currentRoute.params[0], query: combined }, - () => {}, - () => { - // console.log(err); - } - ); + this.openElement(this.currentDocument); } + return true; + } else { + return false; } + + // else { + // let d: GraphDocument = (this.source.activeElement as GraphDocument) || this.currentDocument; + // if (d) { + // this.openElement(d); + + // const combined = { + // ...$cs.router!.currentRoute.query, + // ...{ docid: d.id }, + // }; + // $cs.router.replace( + // { path: $cs.router!.currentRoute.params[0], query: combined }, + // () => {}, + // () => { + // // console.log(err); + // } + // ); + // } + } private dragMoveListener(event) { @@ -950,58 +994,21 @@ export default class DocumentViewer extends WidgetBase { widget: this.widget, subtitle: 'Entity Recognition, Search, Linking, Geo/time recognition', image: 'images/entity_analysis.png', - action: async () => { - try { - this.updateEntityTypes(); - await this.refresh(); - return Promise.resolve(true); - } catch (e) { - return Promise.resolve(false); - } + documentActions: (e) => { + return [ + { + icon: 'mdi-sim-outline', + title: 'Entity Recognition', + action: async () => { + await this.refresh(); + this.updateEntityTypes(); + }, + }, + ]; }, - } as ITool); - this.source.addTool({ - id: 'observation_extraction', - title: 'Observation Extraction', - subtitle: 'find observations', - widget: this.widget, - disabled: true, - // subtitle: 'Entity Recognition, Search, Linking', - // image: 'images/entity_analysis.png', action: async () => { try { - // await this.refresh(); this.updateEntityTypes(); - return Promise.resolve(true); - } catch (e) { - return Promise.resolve(false); - } - }, - } as ITool); - this.source.addTool({ - id: 'geo_time_extraction', - title: 'Geo & time extraction', - subtitle: 'Recognize locations and time entities', - widget: this.widget, - disabled: true, - // subtitle: 'Entity Recognition, Search, Linking', - // image: 'images/entity_analysis.png', - action: async () => { - try { - await this.refresh(); - return Promise.resolve(true); - } catch (e) { - return Promise.resolve(false); - } - }, - } as ITool); - this.source.addTool({ - id: 'language_detection', - title: 'Language Detection', - disabled: true, - widget: this.widget, - action: async () => { - try { await this.refresh(); return Promise.resolve(true); } catch (e) { @@ -1009,6 +1016,8 @@ export default class DocumentViewer extends WidgetBase { } }, } as ITool); + this.updateDocumentActions(); + this.updateDocumentTools(); } initDragging() { @@ -1158,6 +1167,32 @@ export default class DocumentViewer extends WidgetBase { } + + + +function async(arg0: (e: any) => { icon: string; title: string; action: any; }[]): (element: +import("@csnext/cs-data").GraphElement) => import("@csnext/cs-core").IMenu[] { throw new +Error('Function not implemented.'); } diff --git a/packages/cs-graph/src/components/document/node-entities.ts b/packages/cs-graph/src/components/document/node-entities.ts index 8d66a9072..cd903c734 100644 --- a/packages/cs-graph/src/components/document/node-entities.ts +++ b/packages/cs-graph/src/components/document/node-entities.ts @@ -6,7 +6,7 @@ export class EntityList { public edge?: GraphElement; public instances: TextEntity[] = []; public _hover = false; - public _approved = false; + public _linked = false; public _relations = 0; public _togglemore = false; diff --git a/packages/cs-graph/src/components/document/plugins/element-card-component.vue b/packages/cs-graph/src/components/document/nodes/element-card/element-card-component.vue similarity index 78% rename from packages/cs-graph/src/components/document/plugins/element-card-component.vue rename to packages/cs-graph/src/components/document/nodes/element-card/element-card-component.vue index b739e41a7..82736b535 100644 --- a/packages/cs-graph/src/components/document/plugins/element-card-component.vue +++ b/packages/cs-graph/src/components/document/nodes/element-card/element-card-component.vue @@ -3,8 +3,8 @@ > - - + + @@ -22,12 +22,6 @@ + + diff --git a/packages/cs-graph/src/components/document/nodes/element-property/element-property-extension.ts b/packages/cs-graph/src/components/document/nodes/element-property/element-property-extension.ts new file mode 100644 index 000000000..e67368a77 --- /dev/null +++ b/packages/cs-graph/src/components/document/nodes/element-property/element-property-extension.ts @@ -0,0 +1,79 @@ +import { mergeAttributes } from '@tiptap/core' +import { VueNodeViewRenderer } from '@tiptap/vue-2' +import ElementPropertyComponent from './element-property-component.vue'; +import { GraphElement } from '@csnext/cs-data' +import Paragraph from '@tiptap/extension-paragraph'; + +declare module '@tiptap/core' { + interface Commands { + elementProperty: { + /** + * Add a text entity + */ + setElementProperty: (entity?: GraphElement) => any, + toggleElementProperty: (attributes?: any) => ReturnType; + } + } +} + + +export default Paragraph.extend({ + name: 'element-property', + + draggable: true, + group: 'inline', + content: 'inline*', + inline: true, + atom: true, + // content: 'inline*', + + addAttributes() { + return { + key: { default: null }, + value: { default: undefined } + } + + }, + + parseHTML() { + return [ + { + tag: 'element-property', + }, + ] + }, + + + renderHTML({ HTMLAttributes }) { + return ['element-property', mergeAttributes(HTMLAttributes), 0] + }, + + addCommands() { + return { + toggleElementProperty: attributes => ({ commands }) => { + return commands.toggleNode('element-property', 'text', attributes) + }, + setElementProperty: (entity?: GraphElement, key?: string, value?: any) => ({ tr, dispatch }) => { + // debugger; + if (dispatch) { + + // } else { + // // debugger; + // } + } + + return true + }, + } + }, + + // onUpdate(a: any) { + // console.log(a) + // // debugger; + // }, + + + addNodeView() { + return VueNodeViewRenderer(ElementPropertyComponent) + }, +}) \ No newline at end of file diff --git a/packages/cs-graph/src/components/document/plugins/paragraph-component.vue b/packages/cs-graph/src/components/document/nodes/node-paragraph/paragraph-component.vue similarity index 86% rename from packages/cs-graph/src/components/document/plugins/paragraph-component.vue rename to packages/cs-graph/src/components/document/nodes/node-paragraph/paragraph-component.vue index d2d22c018..5f4e6eb4c 100644 --- a/packages/cs-graph/src/components/document/plugins/paragraph-component.vue +++ b/packages/cs-graph/src/components/document/nodes/node-paragraph/paragraph-component.vue @@ -49,9 +49,8 @@ diff --git a/packages/cs-graph/src/components/document/plugins/paragraph-extension.ts b/packages/cs-graph/src/components/document/nodes/node-paragraph/paragraph-extension.ts similarity index 100% rename from packages/cs-graph/src/components/document/plugins/paragraph-extension.ts rename to packages/cs-graph/src/components/document/nodes/node-paragraph/paragraph-extension.ts diff --git a/packages/cs-graph/src/components/document/plugins/text-entity-component.vue b/packages/cs-graph/src/components/document/nodes/text-entity/text-entity-component.vue similarity index 67% rename from packages/cs-graph/src/components/document/plugins/text-entity-component.vue rename to packages/cs-graph/src/components/document/nodes/text-entity/text-entity-component.vue index c25b945aa..f981a980a 100644 --- a/packages/cs-graph/src/components/document/plugins/text-entity-component.vue +++ b/packages/cs-graph/src/components/document/nodes/text-entity/text-entity-component.vue @@ -1,20 +1,24 @@ -