);
break;
+ };
- case I.RelationType.Object:
+ case I.RelationType.Object: {
Item = (element: any) => {
const type = dbStore.getTypeById(element.type);
@@ -150,8 +151,9 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
);
break;
+ };
- case I.RelationType.Checkbox:
+ case I.RelationType.Checkbox: {
value = (
);
break;
+ };
- case I.RelationType.Date:
+ case I.RelationType.Date: {
if ([ I.FilterQuickOption.NumberOfDaysAgo, I.FilterQuickOption.NumberOfDaysNow ].includes(item.quickOption)) {
value = (
@@ -201,10 +204,10 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
);
onSubmit = (e: any) => { this.onSubmitDate(e); };
};
-
break;
+ };
- default:
+ default: {
value = (
{ this.onChange('value', v, true); }}
- onSelect={(e: any) => { this.onSelect(e); }}
+ onKeyUp={(e: any, v: string) => this.onChange('value', v, true)}
+ onSelect={e => this.onSelect(e)}
/>
);
break;
+ };
+ };
+
+ if (Relation.isDictionary(item.relationKey)) {
+ value = (
+
+
+ );
};
if ([ I.FilterCondition.None, I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(item.condition)) {
@@ -333,12 +352,18 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
const relationOptions = this.getRelationOptions();
const relationOption: any = relationOptions.find(it => it.id == item.relationKey) || {};
- const conditionOptions = Relation.filterConditionsByType(relation.format);
- const conditionOption: any = conditionOptions.find(it => it.id == item.condition) || {};
-
const filterQuickOptions = Relation.filterQuickOptions(relation.format, item.condition);
const filterOption: any = filterQuickOptions.find(it => it.id == item.quickOption) || {};
+ let conditionOptions = [];
+ if (Relation.isDictionary(item.relationKey)) {
+ conditionOptions = Relation.filterConditionsDictionary();
+ } else {
+ conditionOptions = Relation.filterConditionsByType(relation.format);
+ };
+
+ const conditionOption: any = conditionOptions.find(it => it.id == item.condition) || {};
+
const ret: any[] = [
{ id: 'relation', icon: relationOption.icon, name: relationOption.name, arrow: true },
{ id: 'condition', icon: '', name: conditionOption.name, format: relation.format, arrow: true },
@@ -352,7 +377,11 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
};
onOver (e: any, item: any) {
- const { getId, getSize, setActive } = this.props;
+ const { getId, getSize, setActive, param } = this.props;
+ const { data } = param;
+ const { getView, itemId } = data;
+ const view = getView();
+ const filter = view.getFilter(itemId);
if (!keyboard.isMouseDisabled) {
setActive(item, false);
@@ -369,7 +398,11 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
};
case 'condition': {
- options = Relation.filterConditionsByType(item.format);
+ if (Relation.isDictionary(filter.relationKey)) {
+ options = Relation.filterConditionsDictionary();
+ } else {
+ options = Relation.filterConditionsByType(item.format);
+ };
break;
};
diff --git a/src/ts/component/menu/dataview/object/list.tsx b/src/ts/component/menu/dataview/object/list.tsx
index 06b7af5567..c35f38be04 100644
--- a/src/ts/component/menu/dataview/object/list.tsx
+++ b/src/ts/component/menu/dataview/object/list.tsx
@@ -253,7 +253,7 @@ const MenuDataviewObjectList = observer(class MenuDataviewObjectList extends Rea
const { data } = param;
const { types, filter } = data;
const filters: I.Filter[] = [
- { operator: I.FilterOperator.And, relationKey: 'layout', condition: I.FilterCondition.NotIn, value: UtilObject.getSystemLayouts() }
+ { operator: I.FilterOperator.And, relationKey: 'layout', condition: I.FilterCondition.NotIn, value: UtilObject.excludeFromSet() }
].concat(data.filters || []);
const sorts = [
{ relationKey: 'lastOpenedDate', type: I.SortType.Desc },
diff --git a/src/ts/component/menu/dataview/view/layout.tsx b/src/ts/component/menu/dataview/view/layout.tsx
index cb5c106276..6a24b39db7 100644
--- a/src/ts/component/menu/dataview/view/layout.tsx
+++ b/src/ts/component/menu/dataview/view/layout.tsx
@@ -141,7 +141,7 @@ const MenuViewLayout = observer(class MenuViewLayout extends React.Component
{
if (clearGroups) {
Dataview.groupUpdate(rootId, blockId, current.id, []);
@@ -389,6 +392,8 @@ const MenuViewLayout = observer(class MenuViewLayout extends React.Component
};
onAdd () {
- const { param, getId, getSize, close } = this.props;
+ const { param, close } = this.props;
const { data } = param;
- const { rootId, blockId, getView, loadData, getSources, isInline, getTarget, onViewSwitch } = data;
+ const { rootId, blockId, getView, getSources, isInline, getTarget, onViewSwitch } = data;
const view = getView();
const sources = getSources();
- const relations = UtilCommon.objectCopy(view.relations);
const filters: I.Filter[] = [];
- const allowed = blockStore.checkFlags(rootId, blockId, [ I.RestrictionDataview.View ]);
const object = getTarget();
- for (const relation of relations) {
- if (relation.isHidden || !relation.isVisible) {
- continue;
- };
-
- filters.push({
- relationKey: relation.relationKey,
- operator: I.FilterOperator.And,
- condition: I.FilterCondition.None,
- value: null,
- });
- };
-
const newView = {
- name: '',
+ name: Dataview.defaultViewName(I.ViewType.Grid),
type: I.ViewType.Grid,
groupRelationKey: Relation.getGroupOption(rootId, blockId, view.type, '')?.id,
- filters,
cardSize: I.CardSize.Medium,
+ filters,
+ sorts: [],
};
C.BlockDataviewViewCreate(rootId, blockId, newView, sources, (message: any) => {
@@ -256,9 +241,7 @@ const MenuViewList = observer(class MenuViewList extends React.Component
const view = dbStore.getView(rootId, blockId, message.viewId);
close();
- window.setTimeout(() => {
- onViewSwitch(view);
- }, Constant.delay.menu);
+ window.setTimeout(() => onViewSwitch(view), Constant.delay.menu);
analytics.event('AddView', {
type: view.type,
diff --git a/src/ts/component/menu/dataview/view/settings.tsx b/src/ts/component/menu/dataview/view/settings.tsx
index 7681274a87..771eb08eeb 100644
--- a/src/ts/component/menu/dataview/view/settings.tsx
+++ b/src/ts/component/menu/dataview/view/settings.tsx
@@ -218,6 +218,9 @@ const MenuViewSettings = observer(class MenuViewSettings extends React.Component
this.param.name = this.getViewName();
};
+ let view = data.view.get();
+ view = Object.assign(view, this.param);
+
C.BlockDataviewViewUpdate(rootId, blockId, current.id, this.param, onSave);
};
diff --git a/src/ts/component/menu/graph/settings.tsx b/src/ts/component/menu/graph/settings.tsx
index 14efe0f4c7..24d67b2994 100644
--- a/src/ts/component/menu/graph/settings.tsx
+++ b/src/ts/component/menu/graph/settings.tsx
@@ -84,7 +84,7 @@ const MenuGraphSettings = observer(class MenuGraphSettings extends React.Compone
};
getSections (): any[] {
- const { graph } = commonStore;
+ const { graph, config } = commonStore;
let sections: any[] = [
{
@@ -99,12 +99,13 @@ const MenuGraphSettings = observer(class MenuGraphSettings extends React.Compone
{ id: 'link', name: translate('menuGraphSettingsLinks') },
{ id: 'relation', name: translate('menuGraphSettingsRelations') },
{ id: 'orphan', name: translate('menuGraphSettingsUnlinkedObjects') },
+ config.experimental ? { id: 'local', name: translate('menuGraphSettingsLocal') } : null,
]
}
];
sections = sections.map(s => {
- s.children = s.children.map(c => {
+ s.children = s.children.filter(it => it).map(c => {
c.switchValue = graph[c.id];
c.withSwitch = true;
c.onSwitch = (e: any, v: boolean) => { this.onClick(e, c); };
diff --git a/src/ts/component/menu/item/filter.tsx b/src/ts/component/menu/item/filter.tsx
index d7f061e1c3..dd878c38a9 100644
--- a/src/ts/component/menu/item/filter.tsx
+++ b/src/ts/component/menu/item/filter.tsx
@@ -23,7 +23,15 @@ const MenuItemFilter = observer(class MenuItemFilter extends React.Component it.id == condition) || {};
const filterOptions = Relation.filterQuickOptions(relation.format, conditionOption.id);
const filterOption: any = filterOptions.find(it => it.id == quickOption) || {};
@@ -124,6 +132,15 @@ const MenuItemFilter = observer(class MenuItemFilter extends React.Component it.id == v);
+
+ if (option) {
+ v = option.name;
+ };
+ };
+
if ([ I.FilterCondition.None, I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(condition)) {
v = null;
};
diff --git a/src/ts/component/menu/onboarding.tsx b/src/ts/component/menu/onboarding.tsx
index 9f7af4140e..e6478e1042 100644
--- a/src/ts/component/menu/onboarding.tsx
+++ b/src/ts/component/menu/onboarding.tsx
@@ -226,12 +226,6 @@ const MenuOnboarding = observer(class MenuSelect extends React.Component {
} else {
content = (
-
+
{wrap}
@@ -155,8 +155,7 @@ const Page = observer(class Page extends React.Component
{
const { account } = authStore;
const { isPopup } = this.props;
const match = this.getMatch();
- const param = this.getMatchParams();
- const { page, action, spaceId } = this.getMatchParams();
+ const { page, action } = this.getMatchParams();
const isIndex = this.isIndex();
const isAuth = this.isAuth();
const isMain = this.isMain();
@@ -224,7 +223,7 @@ const Page = observer(class Page extends React.Component {
const { id } = this.getMatchParams();
const isPopup = keyboard.isPopup();
- if (!home || !id || (home.id != id) || isPopup || Storage.getOnboarding('dashboard')) {
+ if (!home || !id || (home.id != id) || isPopup) {
return;
};
@@ -232,7 +231,12 @@ const Page = observer(class Page extends React.Component {
return;
};
- Onboarding.start('dashboard', false, false);
+ if (!Onboarding.isCompleted('dashboard')) {
+ Onboarding.start('dashboard', false, false);
+ } else
+ if (!Onboarding.isCompleted('navigation') && !$('#navigationPanel').hasClass('hide')) {
+ Onboarding.start('navigation', false, false);
+ };
};
unbind () {
diff --git a/src/ts/component/page/main/navigation.tsx b/src/ts/component/page/main/navigation.tsx
index 15f7ea69c4..19f8fe0823 100644
--- a/src/ts/component/page/main/navigation.tsx
+++ b/src/ts/component/page/main/navigation.tsx
@@ -108,7 +108,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
const { name, description, layout, snippet, coverType, coverId, coverX, coverY, coverScale } = item;
return (
-
+
@@ -116,7 +116,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
{coverId && coverType ?
: ''}
-
@@ -344,16 +344,10 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
this.setActive();
});
- keyboard.shortcut('enter, space', e, (pressed: string) => {
+ keyboard.shortcut('enter, space', e, () => {
const item = items[this.n];
- if (!item) {
- return;
- };
-
- if (this.panel == Panel.Center) {
- this.onConfirm(e, item);
- } else {
- this.loadPage(item.id);
+ if (item) {
+ UtilObject.openAuto({ ...item, layout: I.ObjectLayout.Navigation });
};
});
};
@@ -426,13 +420,11 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
return;
};
- let pagesIn = message.object.links.inbound.map(this.getPage);
- let pagesOut = message.object.links.outbound.map(this.getPage);
-
- pagesIn = pagesIn.filter(this.filterMapper);
- pagesOut = pagesOut.filter(this.filterMapper);
+ const pagesIn = message.object.links.inbound.map(this.getPage).filter(this.filterMapper);
+ const pagesOut = message.object.links.outbound.map(this.getPage).filter(this.filterMapper);
this.panel = Panel.Center;
+
this.setState({
loading: false,
info: this.getPage(message.object.info),
diff --git a/src/ts/component/popup/search.tsx b/src/ts/component/popup/search.tsx
index f427b997a7..49780fc0c4 100644
--- a/src/ts/component/popup/search.tsx
+++ b/src/ts/component/popup/search.tsx
@@ -174,6 +174,10 @@ const PopupSearch = observer(class PopupSearch extends React.Component
{
this.unbind();
win.on('updateGraphSettings.graph', () => { this.updateSettings(); });
- win.on('updateGraphRoot.graph', (e: any, data: any) => { this.setRootId(data.id); });
+ win.on('updateGraphRoot.graph', (e: any, data: any) => this.setRootId(data.id));
win.on('updateTheme.graph', () => { this.send('updateTheme', { theme: commonStore.getThemeClass() }); });
};
@@ -138,8 +138,14 @@ const Graph = observer(class Graph extends React.Component {
.call(this.zoom)
.call(this.zoom.transform, d3.zoomIdentity.translate(0, 0).scale(1.5))
.on('click', (e: any) => {
+ const { local } = commonStore.graph;
const [ x, y ] = d3.pointer(e);
- this.send(e.shiftKey ? 'onSelect' : 'onClick', { x, y });
+
+ if (local) {
+ this.send('onSetRootId', { x, y });
+ } else {
+ this.send(e.shiftKey ? 'onSelect' : 'onClick', { x, y });
+ };
})
.on('dblclick', (e: any) => {
if (e.shiftKey) {
@@ -464,7 +470,7 @@ const Graph = observer(class Graph extends React.Component {
};
setRootId (id: string) {
- this.send('onSetRootId', { rootId: id });
+ this.send('setRootId', { rootId: id });
};
send (id: string, param: any, transfer?: any[]) {
diff --git a/src/ts/component/util/navigation.tsx b/src/ts/component/util/navigation.tsx
index 55ce643718..4e33b9c1bd 100644
--- a/src/ts/component/util/navigation.tsx
+++ b/src/ts/component/util/navigation.tsx
@@ -125,7 +125,7 @@ class Navigation extends React.Component {
};
onSearch () {
- keyboard.onSearchPopup();
+ keyboard.onSearchPopup('Navigation');
};
onProfile () {
diff --git a/src/ts/component/util/progress.tsx b/src/ts/component/util/progress.tsx
index 835801806d..706131b25c 100644
--- a/src/ts/component/util/progress.tsx
+++ b/src/ts/component/util/progress.tsx
@@ -72,7 +72,7 @@ const Progress = observer(class Progress extends React.Component {
node.addClass('hide');
win.off('resize.progress');
- window.setTimeout(() => { commonStore.progressClear(); }, 200);
+ window.setTimeout(() => commonStore.progressClear(), 200);
};
};
@@ -87,23 +87,6 @@ const Progress = observer(class Progress extends React.Component {
C.ProcessCancel(id);
};
- resize () {
- if (!this._isMounted) {
- return;
- };
-
- const node = $(this.node);
- const coords = Storage.get('progress');
-
- this.obj = node.find('#inner');
- this.height = this.obj.outerHeight();
- this.width = this.obj.outerWidth();
-
- if (coords) {
- this.setStyle(coords.x, coords.y);
- };
- };
-
onDragStart (e: any) {
const win = $(window);
const offset = this.obj.offset();
@@ -148,11 +131,30 @@ const Progress = observer(class Progress extends React.Component {
return { x, y };
};
+ resize () {
+ if (!this._isMounted) {
+ return;
+ };
+
+ const node = $(this.node);
+ const coords = Storage.get('progress');
+
+ this.obj = node.find('#inner');
+ this.height = this.obj.outerHeight();
+ this.width = this.obj.outerWidth();
+
+ if (coords) {
+ this.setStyle(coords.x, coords.y);
+ };
+ };
+
setStyle (x: number, y: number) {
const coords = this.checkCoords(x, y);
-
- this.obj.css({ margin: 0, left: coords.x, top: coords.y });
- Storage.set('progress', coords);
+
+ if ((coords.x !== null) && (coords.y !== null)) {
+ this.obj.css({ margin: 0, left: coords.x, top: coords.y });
+ Storage.set('progress', coords, true);
+ };
};
});
diff --git a/src/ts/component/widget/index.tsx b/src/ts/component/widget/index.tsx
index 1ebc2d20e7..a0c79581f6 100644
--- a/src/ts/component/widget/index.tsx
+++ b/src/ts/component/widget/index.tsx
@@ -403,7 +403,7 @@ const WidgetIndex = observer(class WidgetIndex extends React.Component {
};
case Constant.widgetId.recentEdit: {
- filters.push({ operator: I.FilterOperator.And, relationKey: 'lastModifiedDate', condition: I.FilterCondition.Greater, value: space.createdDate });
+ filters.push({ operator: I.FilterOperator.And, relationKey: 'lastModifiedDate', condition: I.FilterCondition.Greater, value: space.createdDate + 3 });
break;
};
diff --git a/src/ts/docs/help/onboarding.ts b/src/ts/docs/help/onboarding.ts
index 193469215b..eefc1aa920 100644
--- a/src/ts/docs/help/onboarding.ts
+++ b/src/ts/docs/help/onboarding.ts
@@ -5,15 +5,9 @@ export default {
category: translate('onboardingMainGraph'),
items: [
{
- description: `
- ${translate('onboardingMainGraph11')}
- ${translate('onboardingMainGraph12')}
- `,
+ description: translate('onboardingMainGraph11'),
video: './img/help/onboarding/space.mp4',
- noButton: true,
- buttons: [
- { text: translate('commonNext'), action: 'dashboard' },
- ],
+ buttonText: translate('commonFinish'),
}
],
@@ -185,31 +179,19 @@ export default {
category: translate('onboardingDashboard'),
showConfetti: true,
onComplete: (force: boolean) => {
- Onboarding.start('navigation', keyboard.isPopup(), force);
+ if (!$('#navigationPanel').hasClass('hide')) {
+ Onboarding.start('navigation', keyboard.isPopup(), force);
+ };
},
items: [
{
description: `
${translate('onboardingDashboard11')}
${translate('onboardingDashboard12')}
+ ${translate('onboardingDashboard13')}
`,
video: './img/help/onboarding/homepage.mp4',
},
- {
- description: `
- ${translate('onboardingDashboard21')}
- ${translate('onboardingDashboard22')}
- ${translate('onboardingDashboard23')}
- `,
- video: './img/help/onboarding/sets.mp4',
- },
- {
- description: `
- ${translate('onboardingDashboard31')}
- ${translate('onboardingDashboard32')}
- `,
- video: './img/help/onboarding/objects.mp4',
- },
{
description: `
${translate('onboardingDashboard41')}
diff --git a/src/ts/docs/help/whatsNew.ts b/src/ts/docs/help/whatsNew.ts
index 53b952fb1a..7733b8035e 100644
--- a/src/ts/docs/help/whatsNew.ts
+++ b/src/ts/docs/help/whatsNew.ts
@@ -28,7 +28,6 @@ export default [
video('./img/help/36/1.mp4', 'c70'),
text(`Spaces were first introduced in June of this year as a container for your graph of objects. From today's release onwards, you'll be able to level up your space game by creating separate spaces, each with their own graph of objects, widget sidebar, and eventually - privacy settings.`),
text(`Simply click your profile picture to create new spaces, or navigate between existing ones. Use the space management menu at the top of your sidebar to customize your space settings or delete your space. For now, your account is limited to 10 spaces.`),
- img('./img/help/36/2.png', 'c70'),
h3(`Calendar View for Sets & Collections`),
video('./img/help/36/3.mp4', 'c70'),
diff --git a/src/ts/lib/analytics.ts b/src/ts/lib/analytics.ts
index fa00fa7e8c..d81fac3979 100644
--- a/src/ts/lib/analytics.ts
+++ b/src/ts/lib/analytics.ts
@@ -391,9 +391,7 @@ class Analytics {
popupMapper (params: any): string {
const { id } = params;
- const map = {
- search: 'ScreenSearch',
- };
+ const map = {};
return map[id] || '';
};
diff --git a/src/ts/lib/api/command.ts b/src/ts/lib/api/command.ts
index 38bf93e82c..39da2f7799 100644
--- a/src/ts/lib/api/command.ts
+++ b/src/ts/lib/api/command.ts
@@ -92,7 +92,7 @@ const WalletCloseSession = (token: string, callBack?: (message: any) => void) =>
const WorkspaceCreate = (details: any, usecase: I.Usecase, callBack?: (message: any) => void) => {
const request = new Rpc.Workspace.Create.Request();
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setUsecase(usecase as number);
dispatcher.request(WorkspaceCreate.name, request, callBack);
@@ -127,7 +127,7 @@ const WorkspaceSetInfo = (spaceId:string, details: any, callBack?: (message: any
const request = new Rpc.Workspace.SetInfo.Request();
request.setSpaceid(spaceId);
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
dispatcher.request(WorkspaceSetInfo.name, request, callBack);
};
@@ -391,7 +391,7 @@ const BlockSetFields = (contextId: string, blockId: string, fields: any, callBac
request.setContextid(contextId);
request.setBlockid(blockId);
- request.setFields(Encode.encodeStruct(fields || {}));
+ request.setFields(Encode.struct(fields || {}));
dispatcher.request(BlockSetFields.name, request, callBack);
};
@@ -579,9 +579,9 @@ const BlockLinkCreateWithObject = (contextId: string, targetId: string, details:
request.setContextid(contextId);
request.setTargetid(targetId);
request.setPosition(position as number);
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setTemplateid(templateId);
- request.setFields(Encode.encodeStruct(fields || {}));
+ request.setFields(Encode.struct(fields || {}));
request.setInternalflagsList(flags.map(Mapper.To.InternalFlag));
request.setObjecttypeuniquekey(typeKey);
request.setSpaceid(spaceId);
@@ -1169,7 +1169,7 @@ const ObjectTypeRelationRemove = (objectTypeId: string, relationKeys: string[],
const ObjectCreate = (details: any, flags: I.ObjectFlag[], templateId: string, typeKey: string, spaceId: string, callBack?: (message: any) => void) => {
const request = new Rpc.Object.Create.Request();
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setInternalflagsList(flags.map(Mapper.To.InternalFlag));
request.setTemplateid(templateId);
request.setSpaceid(spaceId);
@@ -1182,7 +1182,7 @@ const ObjectCreateSet = (sources: string[], details: any, templateId: string, sp
const request = new Rpc.Object.CreateSet.Request();
request.setSourceList(sources);
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setTemplateid(templateId);
request.setSpaceid(spaceId);
@@ -1192,7 +1192,7 @@ const ObjectCreateSet = (sources: string[], details: any, templateId: string, sp
const ObjectCreateBookmark = (details: any, spaceId: string, callBack?: (message: any) => void) => {
const request = new Rpc.Object.CreateBookmark.Request();
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setSpaceid(spaceId);
dispatcher.request(ObjectCreateBookmark.name, request, callBack);
@@ -1201,7 +1201,7 @@ const ObjectCreateBookmark = (details: any, spaceId: string, callBack?: (message
const ObjectCreateObjectType = (details: any, flags: I.ObjectFlag[], spaceId: string, callBack?: (message: any) => void) => {
const request = new Rpc.Object.CreateObjectType.Request();
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setInternalflagsList(flags.map(Mapper.To.InternalFlag));
request.setSpaceid(spaceId);
@@ -1213,7 +1213,7 @@ const ObjectCreateRelation = (details: any, spaceId: string, callBack?: (message
const request = new Rpc.Object.CreateRelation.Request();
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setSpaceid(spaceId);
dispatcher.request(ObjectCreateRelation.name, request, callBack);
@@ -1222,7 +1222,7 @@ const ObjectCreateRelation = (details: any, spaceId: string, callBack?: (message
const ObjectCreateRelationOption = (details: any, spaceId: string, callBack?: (message: any) => void) => {
const request = new Rpc.Object.CreateRelation.Request();
- request.setDetails(Encode.encodeStruct(details));
+ request.setDetails(Encode.struct(details));
request.setSpaceid(spaceId);
dispatcher.request(ObjectCreateRelationOption.name, request, callBack);
diff --git a/src/ts/lib/api/dispatcher.ts b/src/ts/lib/api/dispatcher.ts
index a8f9f6df56..e7352e155d 100644
--- a/src/ts/lib/api/dispatcher.ts
+++ b/src/ts/lib/api/dispatcher.ts
@@ -205,7 +205,7 @@ class Dispatcher {
};
case 'accountDetails': {
- detailStore.update(Constant.subId.profile, { id: UtilObject.getIdentityId(), details: Decode.decodeStruct(data.getDetails()) }, false);
+ detailStore.update(Constant.subId.profile, { id: UtilObject.getIdentityId(), details: Decode.struct(data.getDetails()) }, false);
break;
};
@@ -330,7 +330,7 @@ class Dispatcher {
break;
};
- blockStore.update(rootId, id, { fields: data.hasFields() ? Decode.decodeStruct(data.getFields()) : {} });
+ blockStore.update(rootId, id, { fields: data.hasFields() ? Decode.struct(data.getFields()) : {} });
break;
};
@@ -366,7 +366,7 @@ class Dispatcher {
};
if (data.hasFields()) {
- block.content.fields = Decode.decodeStruct(data.getFields());
+ block.content.fields = Decode.struct(data.getFields());
};
blockStore.updateContent(rootId, id, block.content);
@@ -862,7 +862,7 @@ class Dispatcher {
id = data.getId();
subIds = data.getSubidsList() || [];
block = blockStore.getLeaf(rootId, id);
- details = Decode.decodeStruct(data.getDetails());
+ details = Decode.struct(data.getDetails());
this.detailsUpdate(details, rootId, id, subIds, true);
break;
@@ -875,7 +875,7 @@ class Dispatcher {
details = {};
for (const item of (data.getDetailsList() || [])) {
- details[item.getKey()] = Decode.decodeValue(item.getValue());
+ details[item.getKey()] = Decode.value(item.getValue());
};
this.detailsUpdate(details, rootId, id, subIds, false);
@@ -1067,6 +1067,10 @@ class Dispatcher {
UtilRouter.switchSpace(authStore.accountSpaceId, '');
};
+ if (!rootId) {
+ return;
+ };
+
detailStore.update(rootId, { id, details }, clear);
const root = blockStore.getLeaf(rootId, id);
diff --git a/src/ts/lib/api/mapper.ts b/src/ts/lib/api/mapper.ts
index 005132899a..24400a1463 100644
--- a/src/ts/lib/api/mapper.ts
+++ b/src/ts/lib/api/mapper.ts
@@ -80,14 +80,14 @@ export const Mapper = {
ObjectInfo: (obj: any): I.PageInfo => {
return {
id: obj.getId(),
- details: Decode.decodeStruct(obj.getDetails()),
+ details: Decode.struct(obj.getDetails()),
snippet: obj.getSnippet(),
hasInboundLinks: obj.getHasinboundlinks(),
};
},
Record: (obj: any): any => {
- return Decode.decodeStruct(obj);
+ return Decode.struct(obj);
},
Range: (obj: any): I.TextRange => {
@@ -119,7 +119,7 @@ export const Mapper = {
Details: (obj: any): any => {
return {
id: obj.getId(),
- details: Decode.decodeStruct(obj.getDetails()),
+ details: Decode.struct(obj.getDetails()),
};
},
@@ -251,7 +251,7 @@ export const Mapper = {
id: obj.getId(),
type: type,
childrenIds: obj.getChildrenidsList() || [],
- fields: Decode.decodeStruct(obj.getFields()),
+ fields: Decode.struct(obj.getFields()),
hAlign: obj.getAlign(),
vAlign: obj.getVerticalalign(),
bgColor: obj.getBackgroundcolor(),
@@ -330,7 +330,7 @@ export const Mapper = {
operator: obj.getOperator(),
condition: obj.getCondition(),
quickOption: obj.getQuickoption(),
- value: obj.hasValue() ? Decode.decodeValue(obj.getValue()) : null,
+ value: obj.hasValue() ? Decode.value(obj.getValue()) : null,
};
},
@@ -339,7 +339,7 @@ export const Mapper = {
id: obj.getId(),
relationKey: obj.getRelationkey(),
type: obj.getType(),
- customOrder: (obj.getCustomorderList() || []).map(Decode.decodeValue),
+ customOrder: (obj.getCustomorderList() || []).map(Decode.value),
};
},
@@ -507,7 +507,7 @@ export const Mapper = {
const item = new Rpc.Object.SetDetails.Detail();
item.setKey(obj.key);
- item.setValue(Encode.encodeValue(obj.value));
+ item.setValue(Encode.value(obj.value));
return item;
},
@@ -516,7 +516,7 @@ export const Mapper = {
const item = new Rpc.Block.ListSetFields.Request.BlockField();
item.setBlockid(obj.blockId);
- item.setFields(Encode.encodeStruct(obj.fields || {}));
+ item.setFields(Encode.struct(obj.fields || {}));
return item;
},
@@ -665,7 +665,7 @@ export const Mapper = {
};
if (obj.fields) {
- block.setFields(Encode.encodeStruct(obj.fields || {}));
+ block.setFields(Encode.struct(obj.fields || {}));
};
const fb = UtilCommon.toCamelCase('set-' + obj.type.toLowerCase());
@@ -702,7 +702,7 @@ export const Mapper = {
item.setOperator(obj.operator);
item.setCondition(obj.condition);
item.setQuickoption(obj.quickOption);
- item.setValue(Encode.encodeValue(obj.value));
+ item.setValue(Encode.value(obj.value));
item.setIncludetime(obj.includeTime);
return item;
@@ -714,7 +714,7 @@ export const Mapper = {
item.setId(obj.id);
item.setRelationkey(obj.relationKey);
item.setType(obj.type);
- item.setCustomorderList((obj.customOrder || []).map(Encode.encodeValue));
+ item.setCustomorderList((obj.customOrder || []).map(Encode.value));
item.setFormat(obj.format);
item.setIncludetime(obj.includeTime);
diff --git a/src/ts/lib/api/response.ts b/src/ts/lib/api/response.ts
index 7ae1c6ed9a..8f439c8caf 100644
--- a/src/ts/lib/api/response.ts
+++ b/src/ts/lib/api/response.ts
@@ -111,28 +111,28 @@ export const WalletCreateSession = (response: Rpc.Wallet.CreateSession.Response)
export const ObjectCreate = (response: Rpc.Object.Create.Response) => {
return {
objectId: response.getObjectid(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
export const ObjectCreateSet = (response: Rpc.Object.CreateSet.Response) => {
return {
objectId: response.getObjectid(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
export const ObjectCreateBookmark = (response: Rpc.Object.CreateBookmark.Response) => {
return {
objectId: response.getObjectid(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
export const ObjectCreateObjectType = (response: Rpc.Object.CreateObjectType.Response) => {
return {
objectId: response.getObjectid(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
@@ -140,14 +140,14 @@ export const ObjectCreateRelation = (response: Rpc.Object.CreateRelation.Respons
return {
objectId: response.getObjectid(),
relationKey: response.getKey(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
export const ObjectCreateRelationOption = (response: Rpc.Object.CreateRelationOption.Response) => {
return {
objectId: response.getObjectid(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
@@ -165,7 +165,7 @@ export const ObjectShow = (response: Rpc.Object.Show.Response) => {
export const ObjectSearch = (response: Rpc.Object.Search.Response) => {
return {
- records: (response.getRecordsList() || []).map(Decode.decodeStruct),
+ records: (response.getRecordsList() || []).map(Decode.struct),
};
};
@@ -184,22 +184,22 @@ export const ObjectSearchSubscribe = (response: Rpc.Object.SearchSubscribe.Respo
nextCount: counters.getNextcount(),
prevCount: counters.getPrevcount(),
},
- records: (response.getRecordsList() || []).map(Decode.decodeStruct),
- dependencies: (response.getDependenciesList() || []).map(Decode.decodeStruct),
+ records: (response.getRecordsList() || []).map(Decode.struct),
+ dependencies: (response.getDependenciesList() || []).map(Decode.struct),
};
};
export const ObjectSubscribeIds = (response: Rpc.Object.SubscribeIds.Response) => {
return {
- records: (response.getRecordsList() || []).map(Decode.decodeStruct),
- dependencies: (response.getDependenciesList() || []).map(Decode.decodeStruct),
+ records: (response.getRecordsList() || []).map(Decode.struct),
+ dependencies: (response.getDependenciesList() || []).map(Decode.struct),
};
};
export const ObjectGraph = (response: Rpc.Object.Graph.Response) => {
return {
edges: (response.getEdgesList() || []).map(Mapper.From.GraphEdge),
- nodes: (response.getNodesList() || []).map(Decode.decodeStruct),
+ nodes: (response.getNodesList() || []).map(Decode.struct),
};
};
@@ -374,7 +374,7 @@ export const WorkspaceOpen = (response: Rpc.Workspace.Open.Response) => {
export const WorkspaceObjectAdd = (response: Rpc.Workspace.Object.Add.Response) => {
return {
objectId: response.getObjectid(),
- details: Decode.decodeStruct(response.getDetails()),
+ details: Decode.struct(response.getDetails()),
};
};
diff --git a/src/ts/lib/api/struct.ts b/src/ts/lib/api/struct.ts
index e29a67a77c..7abce55bbf 100644
--- a/src/ts/lib/api/struct.ts
+++ b/src/ts/lib/api/struct.ts
@@ -1,32 +1,42 @@
import Struct from 'google-protobuf/google/protobuf/struct_pb.js';
+const prepare = (o: any) => {
+ if (typeof o === 'undefined') {
+ o = null;
+ } else
+ if (typeof o === 'object') {
+ for (const k in o) {
+ if (typeof o[k] === 'object') {
+ o[k] = prepare(o[k]);
+ } else
+ if (typeof o[k] === 'undefined') {
+ o[k] = null;
+ };
+ };
+ };
+ return o;
+};
+
export class Encode {
- static encodeStruct (obj: any) {
- if (typeof obj === 'undefined') {
- obj = null;
- };
- return Struct.Struct.fromJavaScript(obj);
+ public static struct (obj: any) {
+ return Struct.Struct.fromJavaScript(prepare(obj));
};
- static encodeValue (value: any) {
- if (typeof value === 'undefined') {
- value = null;
- };
- return Struct.Value.fromJavaScript(value);
+ public static value (value: any) {
+ return Struct.Value.fromJavaScript(prepare(value));
};
-
};
export class Decode {
- static decodeValue (value: any) {
+ public static value (value: any) {
let data = null;
try { data = value ? value.toJavaScript() : null; } catch (e) { /**/ };
return data;
};
- static decodeStruct (struct: any) {
+ public static struct (struct: any) {
let data = {};
try { data = struct ? struct.toJavaScript() : {}; } catch (e) { /**/ };
return data;
diff --git a/src/ts/lib/keyboard.ts b/src/ts/lib/keyboard.ts
index a4673c2d95..9d56f0f2a1 100644
--- a/src/ts/lib/keyboard.ts
+++ b/src/ts/lib/keyboard.ts
@@ -206,7 +206,7 @@ class Keyboard {
return;
};
- this.onSearchPopup();
+ this.onSearchPopup('Shortcut');
});
this.shortcut(`${cmd}+l`, e, () => {
@@ -698,6 +698,8 @@ class Keyboard {
if (clearTheme) {
UtilCommon.addBodyClass('theme', '');
};
+
+ $('#link-prism').remove();
focus.clearRange(true);
};
@@ -764,9 +766,9 @@ class Keyboard {
}, Constant.delay.menu);
};
- onSearchPopup () {
+ onSearchPopup (route: string) {
popupStore.open('search', {
- data: { isPopup: this.isPopup() },
+ data: { isPopup: this.isPopup(), route },
});
};
diff --git a/src/ts/lib/relation.ts b/src/ts/lib/relation.ts
index f1eec5c849..8eb3bd405b 100644
--- a/src/ts/lib/relation.ts
+++ b/src/ts/lib/relation.ts
@@ -99,6 +99,16 @@ class Relation {
return ret;
};
+ public filterConditionsDictionary () {
+ return [
+ { id: I.FilterCondition.None, name: translate('filterConditionNone') },
+ { id: I.FilterCondition.Equal, name: translate('filterConditionEqual') },
+ { id: I.FilterCondition.NotEqual, name: translate('filterConditionNotEqual') },
+ { id: I.FilterCondition.Empty, name: translate('filterConditionEmpty') },
+ { id: I.FilterCondition.NotEmpty, name: translate('filterConditionNotEmpty') },
+ ];
+ };
+
public filterQuickOptions (type: I.RelationType, condition: I.FilterCondition) {
if ([ I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(condition)) {
return [];
@@ -263,7 +273,7 @@ class Relation {
case 'origin': {
value = Number(value) || I.ObjectOrigin.None;
- return (value == I.ObjectOrigin.None) ? null : translate(`objectOrigin${value}`);
+ return (value == I.ObjectOrigin.None) ? null : translate(`origin${value}`);
};
};
return null;
@@ -385,6 +395,24 @@ class Relation {
return options.map(it => ({ id: it, name: it }));
};
+ public getDictionaryOptions (relationKey: string) {
+ const options = [];
+ const dictionary = {
+ layout: I.ObjectLayout,
+ origin: I.ObjectOrigin,
+ };
+
+ const item = dictionary[relationKey];
+ if (item) {
+ const keys = Object.keys(item).filter(v => !isNaN(Number(v)));
+ keys.forEach((key, index) => {
+ options.push({ id: index, name: translate(`${relationKey}${index}`) });
+ });
+ };
+
+ return options;
+ };
+
public getStringValue (value: any) {
if ((typeof value === 'object') && value && UtilCommon.hasProperty(value, 'length')) {
return String(value.length ? value[0] : '');
@@ -551,9 +579,17 @@ class Relation {
return this.systemKeys().filter(it => !skipKeys.includes(it));
};
- isSystem (relationKey: string) {
+ isSystem (relationKey: string): boolean {
return this.systemKeys().includes(relationKey);
};
+
+ dictionaryKeys () {
+ return [ 'layout', 'origin' ];
+ };
+
+ isDictionary (relationKey: string): boolean {
+ return this.dictionaryKeys().includes(relationKey);
+ };
};
diff --git a/src/ts/lib/util/data.ts b/src/ts/lib/util/data.ts
index 0e545db975..6f7bdc4068 100644
--- a/src/ts/lib/util/data.ts
+++ b/src/ts/lib/util/data.ts
@@ -399,39 +399,37 @@ class UtilData {
const { withSet, withBookmark, withCollection, withDefault } = param || {};
const { space, config } = commonStore;
const pageLayouts = UtilObject.getPageLayouts();
+ const bookmark = dbStore.getTypeByKey(Constant.typeKey.bookmark);
+ const collection = dbStore.getTypeByKey(Constant.typeKey.collection);
+ const set = dbStore.getTypeByKey(Constant.typeKey.set);
+ const task = dbStore.getTypeByKey(Constant.typeKey.task);
+ const page = dbStore.getTypeByKey(Constant.typeKey.page);
+ const note = dbStore.getTypeByKey(Constant.typeKey.note);
let items: any[] = [];
if (!withDefault) {
- const skipLayouts = [
- I.ObjectLayout.Note,
- I.ObjectLayout.Page,
- I.ObjectLayout.Task,
- I.ObjectLayout.Bookmark,
- ].concat(UtilObject.getSetLayouts());
+ const skipIds = [ bookmark, collection, set, task, page, note ].filter(it => it).map(it => it.id);
items = items.concat(dbStore.getTypes().filter(it => {
- return pageLayouts.includes(it.recommendedLayout) && !skipLayouts.includes(it.recommendedLayout) && (it.spaceId == space);
+ return pageLayouts.includes(it.recommendedLayout) && !skipIds.includes(it.id) && (it.spaceId == space);
}));
items.sort(this.sortByName);
};
if (withBookmark) {
- items.unshift(dbStore.getTypeByKey(Constant.typeKey.bookmark));
+ items.unshift(bookmark);
};
if (withCollection) {
- items.unshift(dbStore.getTypeByKey(Constant.typeKey.collection));
+ items.unshift(collection);
};
if (withSet) {
- items.unshift(dbStore.getTypeByKey(Constant.typeKey.set));
+ items.unshift(set);
};
- items.unshift(dbStore.getTypeByKey(Constant.typeKey.task));
- items.unshift(dbStore.getTypeByKey(Constant.typeKey.page));
- items.unshift(dbStore.getTypeByKey(Constant.typeKey.note));
-
+ items = [ note, page, task ].concat(items);
items = items.filter(it => it);
if (!config.debug.ho) {
diff --git a/src/ts/store/common.ts b/src/ts/store/common.ts
index 54e8dbdb12..dff864f69b 100644
--- a/src/ts/store/common.ts
+++ b/src/ts/store/common.ts
@@ -16,6 +16,7 @@ interface Graph {
label: boolean;
relation: boolean;
link: boolean;
+ local: boolean;
filter: string;
};
@@ -64,6 +65,7 @@ class CommonStore {
label: true,
relation: true,
link: true,
+ local: false,
filter: '',
};
diff --git a/src/ts/store/detail.ts b/src/ts/store/detail.ts
index 9f4fa76f84..ced6f804c7 100644
--- a/src/ts/store/detail.ts
+++ b/src/ts/store/detail.ts
@@ -27,6 +27,11 @@ class DetailStore {
/** Idempotent. adds details to the detail store. */
public set (rootId: string, items: Item[]) {
+ if (!rootId) {
+ console.log('[detailStore].set: rootId is not defined');
+ return;
+ };
+
const map = observable.map(new Map());
for (const item of items) {
@@ -52,7 +57,13 @@ class DetailStore {
/** Idempotent. updates details in the detail store. if clear is set, map wil delete details by item id. */
public update (rootId: string, item: Item, clear: boolean): void {
+ if (!rootId) {
+ console.log('[detailStore].update: rootId is not defined');
+ return;
+ };
+
if (!item.details) {
+ console.log('[detailStore].update: details are not defined');
return;
};