this.node = ref} className="body">
@@ -89,13 +90,14 @@ const WidgetViewCalendar = observer(class WidgetViewCalendar extends React.Compo
cn.push('first');
};
- const check = this.checkItems(item.d, item.m, item.y, groupRelationKey);
+ const check = dotMap.get([ item.d, item.m, item.y ].join('-'));
return (
this.onClick(item.d, item.m, item.y)}
+ onContextMenu={(e: any) => this.onContextMenu(e, item)}
>
{item.d}
@@ -110,6 +112,23 @@ const WidgetViewCalendar = observer(class WidgetViewCalendar extends React.Compo
);
};
+ onContextMenu = (e: any, item: any) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ S.Menu.open('select', {
+ element: '#' + [ 'day', item.d, item.m, item.y ].join('-'),
+ offsetY: 4,
+ noFlipY: true,
+ data: {
+ options: [ { id: 'open', icon: 'expand', name: translate('commonOpenObject') } ],
+ onSelect: () => {
+ U.Object.openDateByTimestamp(U.Date.timestamp(item.y, item.m, item.d), 'auto');
+ }
+ }
+ });
+ };
+
componentDidMount(): void {
this.setSelectsValue(this.state.value);
};
@@ -220,14 +239,23 @@ const WidgetViewCalendar = observer(class WidgetViewCalendar extends React.Compo
];
};
- checkItems (d: number, m: number, y: number, relationKey: string) {
+ getDotMap (relationKey: string): Map {
+ const { value } = this.state;
const { rootId } = this.props;
+ const data = U.Date.getCalendarMonth(value);
const items = S.Record.getRecords(S.Record.getSubId(rootId, J.Constant.blockId.dataview), [ relationKey ]);
- const current = [ d, m, y ].join('-');
+ const ret = new Map();
- return !!items.find(it => U.Date.date('j-n-Y', it[relationKey]) == current);
- };
+ data.forEach(it => {
+ const current = [ it.d, it.m, it.y ].join('-');
+ if (items.find(it => U.Date.date('j-n-Y', it[relationKey]) == current)) {
+ ret.set(current, true);
+ };
+ });
+
+ return ret;
+ };
});
diff --git a/src/ts/interface/block/dataview.ts b/src/ts/interface/block/dataview.ts
index 9092e30bf1..e3b57044db 100644
--- a/src/ts/interface/block/dataview.ts
+++ b/src/ts/interface/block/dataview.ts
@@ -12,6 +12,9 @@ export enum DateFormat {
Short = 2, // 30/07/2020
ShortUS = 3, // 07/30/2020
ISO = 4, // 2020-07-30
+ Long = 5, // July 15, 2020
+ Nordic = 6, // 15. Jul 2020
+ European = 7, // 15.07.2020
};
export enum TimeFormat {
@@ -130,8 +133,6 @@ export interface ViewRelation {
isVisible?: boolean;
width?: number;
includeTime?: boolean;
- dateFormat?: I.DateFormat;
- timeFormat?: I.TimeFormat;
formulaType?: I.FormulaType;
};
diff --git a/src/ts/lib/action.ts b/src/ts/lib/action.ts
index 75e2f91892..cf111fc043 100644
--- a/src/ts/lib/action.ts
+++ b/src/ts/lib/action.ts
@@ -732,7 +732,7 @@ class Action {
let layout = I.WidgetLayout.Link;
if (object && !object._empty_) {
- if (U.Object.isInFileOrSystemLayouts(object.layout)) {
+ if (U.Object.isInFileOrSystemLayouts(object.layout) || U.Object.isDateLayout(object.layout)) {
layout = I.WidgetLayout.Link;
} else
if (U.Object.isInSetLayouts(object.layout)) {
diff --git a/src/ts/lib/api/command.ts b/src/ts/lib/api/command.ts
index 5bafdb5c9d..953c484b84 100644
--- a/src/ts/lib/api/command.ts
+++ b/src/ts/lib/api/command.ts
@@ -1773,6 +1773,15 @@ export const ObjectChatAdd = (objectId: string, callBack?: (message: any) => voi
dispatcher.request(ObjectChatAdd.name, request, callBack);
};
+export const ObjectDateByTimestamp = (spaceId: string, timestamp: number, callBack?: (message: any) => void) => {
+ const request = new Rpc.Object.DateByTimestamp.Request();
+
+ request.setSpaceid(spaceId);
+ request.setTimestamp(timestamp);
+
+ dispatcher.request(ObjectDateByTimestamp.name, request, callBack);
+};
+
// ---------------------- OBJECT LIST ---------------------- //
export const ObjectListDuplicate = (ids: string[], callBack?: (message: any) => void) => {
@@ -2234,3 +2243,12 @@ export const ChatGetMessagesByIds = (objectId: string, ids: string[], callBack?:
dispatcher.request(ChatGetMessagesByIds.name, request, callBack);
};
+
+export const RelationListWithValue = (spaceId: string, value: any, callBack?: (message: any) => void) => {
+ const request = new Rpc.Relation.ListWithValue.Request();
+
+ request.setSpaceid(spaceId);
+ request.setValue(Encode.value(value));
+
+ dispatcher.request(RelationListWithValue.name, request, callBack);
+};
diff --git a/src/ts/lib/api/mapper.ts b/src/ts/lib/api/mapper.ts
index 879f71ced8..5d2730285a 100644
--- a/src/ts/lib/api/mapper.ts
+++ b/src/ts/lib/api/mapper.ts
@@ -353,8 +353,6 @@ export const Mapper = {
isVisible: obj.getIsvisible(),
width: obj.getWidth(),
includeTime: obj.getDateincludetime(),
- timeFormat: obj.getTimeformat(),
- dateFormat: obj.getDateformat(),
formulaType: obj.getFormula(),
};
},
@@ -905,8 +903,6 @@ export const Mapper = {
item.setIsvisible(obj.isVisible);
item.setWidth(obj.width);
item.setDateincludetime(obj.includeTime);
- item.setTimeformat(obj.timeFormat);
- item.setDateformat(obj.dateFormat);
item.setFormula(obj.formulaType);
return item;
diff --git a/src/ts/lib/api/response.ts b/src/ts/lib/api/response.ts
index 12ce7d565f..deae5de905 100644
--- a/src/ts/lib/api/response.ts
+++ b/src/ts/lib/api/response.ts
@@ -304,6 +304,12 @@ export const ObjectChatAdd = (response: Rpc.Object.ChatAdd.Response) => {
};
};
+export const ObjectDateByTimestamp = (response: Rpc.Object.DateByTimestamp.Response) => {
+ return {
+ details: Decode.struct(response.getDetails()),
+ };
+};
+
export const BlockCreate = (response: Rpc.Block.Create.Response) => {
return {
blockId: response.getBlockid(),
@@ -586,4 +592,15 @@ export const ChatAddMessage = (response: Rpc.Chat.AddMessage.Response) => {
return {
messageId: response.getMessageid(),
};
-};
\ No newline at end of file
+};
+
+export const RelationListWithValue = (response: Rpc.Relation.ListWithValue.Response) => {
+ return {
+ relations: (response.getListList() || []).map(it => {
+ return {
+ relationKey: it.getRelationkey(),
+ counter: it.getCounter(),
+ };
+ }),
+ };
+};
diff --git a/src/ts/lib/dataview.ts b/src/ts/lib/dataview.ts
index a9cd41f6c2..a98833a557 100644
--- a/src/ts/lib/dataview.ts
+++ b/src/ts/lib/dataview.ts
@@ -551,7 +551,7 @@ class Dataview {
return null;
};
- const { formulaType, includeTime, timeFormat, dateFormat, relationKey } = viewRelation;
+ const { formulaType, includeTime, relationKey } = viewRelation;
const relation = S.Record.getRelationByKey(relationKey);
if (!relation) {
@@ -573,8 +573,8 @@ class Dataview {
};
const date = (t: number) => {
- const date = U.Date.dateWithFormat(dateFormat, t);
- const time = U.Date.timeWithFormat(timeFormat, t);
+ const date = U.Date.dateWithFormat(S.Common.dateFormat, t);
+ const time = U.Date.timeWithFormat(S.Common.timeFormat, t);
return includeTime ? [ date, time ].join(' ') : date;
};
diff --git a/src/ts/lib/util/data.ts b/src/ts/lib/util/data.ts
index b03bbfe515..486c6763f1 100644
--- a/src/ts/lib/util/data.ts
+++ b/src/ts/lib/util/data.ts
@@ -1002,7 +1002,6 @@ class UtilData {
};
graphFilters () {
- const { space } = S.Common;
const templateType = S.Record.getTemplateType();
const filters: any[] = [
{ relationKey: 'isHidden', condition: I.FilterCondition.NotEqual, value: true },
diff --git a/src/ts/lib/util/date.ts b/src/ts/lib/util/date.ts
index c37865c129..cd6c87d751 100644
--- a/src/ts/lib/util/date.ts
+++ b/src/ts/lib/util/date.ts
@@ -186,6 +186,9 @@ class UtilDate {
case I.DateFormat.Short: f = 'd.m.Y'; break;
case I.DateFormat.ShortUS: f = 'm.d.Y'; break;
case I.DateFormat.ISO: f = 'Y-m-d'; break;
+ case I.DateFormat.Long: f = 'F j, Y'; break;
+ case I.DateFormat.Nordic: f = 'j. M Y'; break;
+ case I.DateFormat.European: f = 'j.m.Y'; break;
};
return f;
};
diff --git a/src/ts/lib/util/graph.ts b/src/ts/lib/util/graph.ts
index ecccf6eafe..e0934e08b6 100644
--- a/src/ts/lib/util/graph.ts
+++ b/src/ts/lib/util/graph.ts
@@ -16,6 +16,11 @@ class UtilGraph {
break;
};
+ case I.ObjectLayout.Date: {
+ src = `img/icon/relation/date.svg`;
+ break;
+ };
+
case I.ObjectLayout.Audio:
case I.ObjectLayout.Video:
case I.ObjectLayout.Pdf:
diff --git a/src/ts/lib/util/menu.ts b/src/ts/lib/util/menu.ts
index f7b7043602..0f833d7368 100644
--- a/src/ts/lib/util/menu.ts
+++ b/src/ts/lib/util/menu.ts
@@ -409,7 +409,7 @@ class UtilMenu {
if (!isSystem) {
const isSet = U.Object.isInSetLayouts(layout);
const setLayouts = U.Object.getSetLayouts();
- const treeSkipLayouts = setLayouts.concat(U.Object.getFileAndSystemLayouts()).concat([ I.ObjectLayout.Participant ]);
+ const treeSkipLayouts = setLayouts.concat(U.Object.getFileAndSystemLayouts()).concat([ I.ObjectLayout.Participant, I.ObjectLayout.Date ]);
// Sets can only become Link and List layouts, non-sets can't become List
if (treeSkipLayouts.includes(layout)) {
@@ -1043,6 +1043,9 @@ class UtilMenu {
{ id: I.DateFormat.Short },
{ id: I.DateFormat.ShortUS },
{ id: I.DateFormat.ISO },
+ { id: I.DateFormat.Long },
+ { id: I.DateFormat.Nordic },
+ { id: I.DateFormat.European },
] as any[]).map(it => {
it.name = U.Date.dateWithFormat(it.id, U.Date.now());
return it;
diff --git a/src/ts/lib/util/object.ts b/src/ts/lib/util/object.ts
index 1a2e046457..4acf59328c 100644
--- a/src/ts/lib/util/object.ts
+++ b/src/ts/lib/util/object.ts
@@ -26,6 +26,7 @@ class UtilObject {
case I.ObjectLayout.Empty: r = 'empty'; break;
case I.ObjectLayout.Space:
case I.ObjectLayout.Chat: r = 'chat'; break;
+ case I.ObjectLayout.Date: r = 'date'; break;
};
return r;
};
@@ -409,7 +410,6 @@ class UtilObject {
return [
I.ObjectLayout.Set,
I.ObjectLayout.Collection,
- I.ObjectLayout.Date,
];
};
@@ -483,6 +483,22 @@ class UtilObject {
return this.getPageLayouts().includes(layout);
};
+ openDateByTimestamp (t: number, method?: string) {
+ method = method || 'auto';
+
+ const fn = U.Common.toCamelCase(`open-${method}`);
+
+ C.ObjectDateByTimestamp(S.Common.space, t, (message: any) => {
+ if (!message.error.code) {
+ if (U.Object[fn]) {
+ U.Object[fn](message.details);
+ } else {
+ U.Object.openConfig(message.details);
+ };
+ };
+ });
+ };
+
};
export default new UtilObject();
\ No newline at end of file
diff --git a/src/ts/model/viewRelation.ts b/src/ts/model/viewRelation.ts
index adfa564f94..bfa0f6bd82 100644
--- a/src/ts/model/viewRelation.ts
+++ b/src/ts/model/viewRelation.ts
@@ -7,8 +7,6 @@ class ViewRelation implements I.ViewRelation {
width = 0;
isVisible = false;
includeTime = false;
- dateFormat: I.DateFormat = I.DateFormat.MonthAbbrBeforeDay;
- timeFormat: I.TimeFormat = I.TimeFormat.H12;
formulaType: I.FormulaType = I.FormulaType.None;
constructor (props: I.ViewRelation) {
@@ -16,16 +14,12 @@ class ViewRelation implements I.ViewRelation {
this.width = Number(props.width) || 0;
this.isVisible = Boolean(props.isVisible);
this.includeTime = Boolean(props.includeTime);
- this.dateFormat = Number(props.dateFormat) || I.DateFormat.MonthAbbrBeforeDay;
- this.timeFormat = Number(props.timeFormat) || I.TimeFormat.H12;
this.formulaType = Number(props.formulaType) || I.FormulaType.None;
makeObservable(this, {
width: observable,
isVisible: observable,
includeTime: observable,
- dateFormat: observable,
- timeFormat: observable,
formulaType: observable,
});
diff --git a/src/ts/store/common.ts b/src/ts/store/common.ts
index ccf16d7246..f9e8ab6b71 100644
--- a/src/ts/store/common.ts
+++ b/src/ts/store/common.ts
@@ -39,6 +39,8 @@ class CommonStore {
public fullscreenObjectValue = null;
public navigationMenuValue = null;
public linkStyleValue = null;
+ public dateFormatValue = null;
+ public timeFormatValue = null;
public isOnlineValue = false;
public shareTooltipValue = false;
public showVaultValue = null;
@@ -132,6 +134,8 @@ class CommonStore {
spaceStorageSet: action,
navigationMenuSet: action,
linkStyleSet: action,
+ dateFormatSet: action,
+ timeFormatSet: action,
isOnlineSet: action,
shareTooltipSet: action,
membershipTiersListSet: action,
@@ -248,6 +252,22 @@ class CommonStore {
return Number(ret) || I.LinkCardStyle.Text;
};
+ get dateFormat (): I.DateFormat {
+ let ret = this.dateFormatValue;
+ if (ret === null) {
+ ret = Storage.get('dateFormat');
+ };
+ return Number(ret) || I.DateFormat.Long;
+ };
+
+ get timeFormat (): I.TimeFormat {
+ let ret = this.timeFormatValue;
+ if (ret === null) {
+ ret = Storage.get('timeFormat');
+ };
+ return Number(ret) || I.TimeFormat.H12;
+ };
+
get dataPath (): string {
return String(this.dataPathValue || '');
};
@@ -487,6 +507,18 @@ class CommonStore {
Storage.set('linkStyle', v);
};
+ dateFormatSet (v: I.DateFormat) {
+ v = Number(v);
+ this.dateFormatValue = v;
+ Storage.set('dateFormat', v);
+ };
+
+ timeFormatSet (v: I.TimeFormat) {
+ v = Number(v);
+ this.timeFormatValue = v;
+ Storage.set('timeFormat', v);
+ };
+
isOnlineSet (v: boolean) {
this.isOnlineValue = Boolean(v);
console.log('[Online status]:', v);
diff --git a/src/ts/store/detail.ts b/src/ts/store/detail.ts
index 1418816308..d89c1feda7 100644
--- a/src/ts/store/detail.ts
+++ b/src/ts/store/detail.ts
@@ -276,6 +276,15 @@ class DetailStore {
};
private mapDate (object: any) {
+ object.timestamp = Number(object.timestamp) || 0;
+
+ if (object.timestamp) {
+ const { showRelativeDates, dateFormat } = S.Common;
+ const day = showRelativeDates ? U.Date.dayString(object.timestamp) : null;
+
+ object.name = day ? day : U.Date.dateWithFormat(dateFormat, object.timestamp);
+ };
+
return this.mapSet(object);
};