mirror of
https://github.com/anyproto/anytype-ts.git
synced 2025-06-09 09:35:02 +09:00
Merge branch 'main' of github.com:anyproto/anytype-ts into feature/native-messaging-host
This commit is contained in:
commit
6f5b8c3338
54 changed files with 478 additions and 331 deletions
BIN
dist/img/help/36/2.png
vendored
BIN
dist/img/help/36/2.png
vendored
Binary file not shown.
Before Width: | Height: | Size: 228 KiB |
115
dist/workers/graph.js
vendored
115
dist/workers/graph.js
vendored
|
@ -15,6 +15,7 @@ const util = new Util();
|
|||
// CONSTANTS
|
||||
|
||||
const transformThreshold = 1.5;
|
||||
const delayFocus = 1000;
|
||||
|
||||
const ObjectLayout = {
|
||||
Human: 1,
|
||||
|
@ -70,7 +71,9 @@ let edgeMap = new Map();
|
|||
let hoverAlpha = 0.2;
|
||||
let fontFamily = 'Helvetica, san-serif';
|
||||
let timeoutHover = 0;
|
||||
let rootId = '';
|
||||
let root = null;
|
||||
let paused = false;
|
||||
|
||||
addEventListener('message', ({ data }) => {
|
||||
if (this[data.id]) {
|
||||
|
@ -82,7 +85,7 @@ init = (param) => {
|
|||
data = param;
|
||||
canvas = data.canvas;
|
||||
settings = data.settings;
|
||||
|
||||
rootId = data.rootId;
|
||||
ctx = canvas.getContext('2d');
|
||||
|
||||
util.ctx = ctx;
|
||||
|
@ -99,16 +102,15 @@ init = (param) => {
|
|||
|
||||
initForces();
|
||||
|
||||
simulation.on('tick', () => { redraw(); });
|
||||
simulation.on('tick', () => redraw());
|
||||
simulation.tick(100);
|
||||
|
||||
// Center initially on root node
|
||||
setTimeout(() => {
|
||||
root = getNodeById(data.rootId);
|
||||
root = getNodeById(rootId);
|
||||
|
||||
let x = width / 2;
|
||||
let y = height / 2;
|
||||
|
||||
|
||||
if (root) {
|
||||
x = root.x;
|
||||
y = root.y;
|
||||
|
@ -199,10 +201,11 @@ initForces = () => {
|
|||
.y(height * forceY.y);
|
||||
|
||||
updateForces();
|
||||
redraw();
|
||||
};
|
||||
|
||||
updateForces = () => {
|
||||
let old = getNodeMap();
|
||||
const old = getNodeMap();
|
||||
|
||||
edges = util.objectCopy(data.edges);
|
||||
nodes = util.objectCopy(data.nodes);
|
||||
|
@ -217,6 +220,14 @@ updateForces = () => {
|
|||
edges = edges.filter(d => d.type != EdgeType.Relation);
|
||||
};
|
||||
|
||||
// Filte local only edges
|
||||
if (settings.local) {
|
||||
edges = edges.filter(d => (d.source == rootId) || (d.target == rootId));
|
||||
|
||||
const nodeIds = util.arrayUnique([ rootId ].concat(edges.map(d => d.source)).concat(edges.map(d => d.target)));
|
||||
nodes = nodes.filter(d => nodeIds.includes(d.id));
|
||||
};
|
||||
|
||||
let map = getNodeMap();
|
||||
edges = edges.filter(d => map.get(d.source) && map.get(d.target));
|
||||
|
||||
|
@ -237,7 +248,13 @@ updateForces = () => {
|
|||
edges = edges.filter(d => map.get(d.source) && map.get(d.target));
|
||||
|
||||
// Shallow copy to disable mutations
|
||||
nodes = nodes.map(d => Object.assign(old.get(d.id) || {}, d));
|
||||
nodes = nodes.map(d => {
|
||||
let o = old.get(d.id);
|
||||
if (!o) {
|
||||
o = settings.local ? { x: width / 2, y: width / 2 } : {};
|
||||
};
|
||||
return Object.assign(o, d);
|
||||
});
|
||||
edges = edges.map(d => Object.assign({}, d));
|
||||
|
||||
simulation.nodes(nodes);
|
||||
|
@ -258,16 +275,28 @@ updateForces = () => {
|
|||
};
|
||||
|
||||
updateSettings = (param) => {
|
||||
const needUpdate = (param.link != settings.link) ||
|
||||
(param.relation != settings.relation) ||
|
||||
(param.orphan != settings.orphan);
|
||||
const updateKeys = [ 'link', 'relation', 'orphan', 'local' ];
|
||||
|
||||
let needUpdate = false;
|
||||
let needFocus = false;
|
||||
|
||||
for (let key of updateKeys) {
|
||||
if (param[key] != settings[key]) {
|
||||
needUpdate = true;
|
||||
|
||||
if (key == 'local') {
|
||||
needFocus = true;
|
||||
};
|
||||
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
settings = Object.assign(settings, param);
|
||||
needUpdate ? updateForces() : redraw();
|
||||
|
||||
if (needUpdate) {
|
||||
updateForces();
|
||||
} else {
|
||||
redraw();
|
||||
if (needFocus) {
|
||||
setTimeout(() => this.setRootId({ rootId }), delayFocus);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -289,7 +318,7 @@ draw = (t) => {
|
|||
ctx.font = getFont();
|
||||
|
||||
edges.forEach(d => {
|
||||
drawLine(d, radius, radius * 1.3, settings.marker && d.isDouble, settings.marker);
|
||||
drawEdge(d, radius, radius * 1.3, settings.marker && d.isDouble, settings.marker);
|
||||
});
|
||||
|
||||
nodes.forEach(d => {
|
||||
|
@ -303,10 +332,12 @@ draw = (t) => {
|
|||
|
||||
redraw = () => {
|
||||
cancelAnimationFrame(frame);
|
||||
frame = requestAnimationFrame(draw);
|
||||
if (!paused) {
|
||||
frame = requestAnimationFrame(draw);
|
||||
};
|
||||
};
|
||||
|
||||
drawLine = (d, arrowWidth, arrowHeight, arrowStart, arrowEnd) => {
|
||||
drawEdge = (d, arrowWidth, arrowHeight, arrowStart, arrowEnd) => {
|
||||
const x1 = d.source.x;
|
||||
const y1 = d.source.y;
|
||||
const r1 = getRadius(d.source);
|
||||
|
@ -577,6 +608,22 @@ onSelect = ({ x, y, selectRelated }) => {
|
|||
};
|
||||
};
|
||||
|
||||
onSetRootId = ({ x, y }) => {
|
||||
const d = getNodeByCoords(x, y);
|
||||
if (d) {
|
||||
this.setRootId({ rootId: d.id });
|
||||
};
|
||||
};
|
||||
|
||||
onSetEdges = (param) => {
|
||||
data.edges = param.edges;
|
||||
updateForces();
|
||||
};
|
||||
|
||||
onSetSelected = ({ ids }) => {
|
||||
selected = ids;
|
||||
};
|
||||
|
||||
onMouseMove = ({ x, y }) => {
|
||||
const active = nodes.find(d => d.isOver);
|
||||
const d = getNodeByCoords(x, y);
|
||||
|
@ -618,12 +665,11 @@ onContextMenu = ({ x, y }) => {
|
|||
const d = getNodeByCoords(x, y);
|
||||
if (!d) {
|
||||
send('onContextSpaceClick', { x, y });
|
||||
return;
|
||||
} else {
|
||||
send('onContextMenu', { node: d, x, y });
|
||||
d.isOver = true;
|
||||
redraw();
|
||||
};
|
||||
|
||||
d.isOver = true;
|
||||
send('onContextMenu', { node: d, x, y });
|
||||
redraw();
|
||||
};
|
||||
|
||||
onAddNode = ({ target, sourceId }) => {
|
||||
|
@ -667,21 +713,12 @@ onRemoveNode = ({ ids }) => {
|
|||
data.edges = data.edges.filter(d => !ids.includes(d.source.id) && !ids.includes(d.target.id));
|
||||
|
||||
updateForces();
|
||||
redraw();
|
||||
};
|
||||
|
||||
onSetEdges = (param) => {
|
||||
data.edges = param.edges;
|
||||
setRootId = (param) => {
|
||||
rootId = param.rootId;
|
||||
root = getNodeById(rootId);
|
||||
|
||||
updateForces();
|
||||
};
|
||||
|
||||
onSetSelected = ({ ids }) => {
|
||||
selected = ids;
|
||||
};
|
||||
|
||||
onSetRootId = ({ rootId }) => {
|
||||
root = nodes.find(d => d.id == rootId);
|
||||
if (!root) {
|
||||
return;
|
||||
};
|
||||
|
@ -696,12 +733,14 @@ onSetRootId = ({ rootId }) => {
|
|||
transform = Object.assign(transform, coords);
|
||||
redraw();
|
||||
})
|
||||
.onComplete(() => {
|
||||
send('onTransform', { ...transform });
|
||||
})
|
||||
.onComplete(() => send('onTransform', { ...transform }))
|
||||
.start();
|
||||
|
||||
redraw();
|
||||
if (settings.local) {
|
||||
updateForces();
|
||||
} else {
|
||||
redraw();
|
||||
};
|
||||
};
|
||||
|
||||
restart = (alpha) => {
|
||||
|
|
4
dist/workers/lib/util.js
vendored
4
dist/workers/lib/util.js
vendored
|
@ -78,4 +78,8 @@ class Util {
|
|||
this.ctx.restore();
|
||||
};
|
||||
|
||||
arrayUnique (a) {
|
||||
return [ ...new Set(a) ];
|
||||
};
|
||||
|
||||
};
|
|
@ -1 +1 @@
|
|||
0.29.9
|
||||
0.29.11
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "anytype",
|
||||
"version": "0.35.20-beta",
|
||||
"version": "0.35.23-beta",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "anytype",
|
||||
"version": "0.35.20-beta",
|
||||
"version": "0.35.23-beta",
|
||||
"hasInstallScript": true,
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "anytype",
|
||||
"version": "0.35.20-beta",
|
||||
"version": "0.35.23-beta",
|
||||
"description": "Anytype",
|
||||
"main": "electron.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1173,6 +1173,7 @@
|
|||
"menuGraphSettingsLinks": "Links",
|
||||
"menuGraphSettingsRelations": "Relations",
|
||||
"menuGraphSettingsUnlinkedObjects": "Unlinked Objects",
|
||||
"menuGraphSettingsLocal": "Local graph",
|
||||
|
||||
"menuHelpWhatsNew": "What's New",
|
||||
"menuHelpShortcut": "Keyboard Shortcuts",
|
||||
|
@ -1440,8 +1441,7 @@
|
|||
"dispatcherImportTryAgain": "Try again",
|
||||
|
||||
"onboardingMainGraph": "Onboarding",
|
||||
"onboardingMainGraph11": "<b>Welcome to your Anytype Space.</b> Space is a graph of interconnected objects, providing a natural way to organize information.",
|
||||
"onboardingMainGraph12": "To access your Homepage, click on the <span class=\"highlight\">Next</span> button.",
|
||||
"onboardingMainGraph11": "<b>Space is essentially a graph</b>, and Anytype aims to provide a natural way of thinking where everything is represented as objects with specific relationships, just like in the real world.",
|
||||
|
||||
"onboardingMainSet": "Set & Collection",
|
||||
"onboardingMainSet11": "<b>Anytype has two basic formats: Sets and Collections.</b> As in computer science, a Set is a data structure that contains only unique elements, while a Collection is any group of objects that are stored together. You can convert any set into a collection, but not the other way around.",
|
||||
|
@ -1471,13 +1471,9 @@
|
|||
"onboardingObjectCreationFinish1Button": "Ok! I like it",
|
||||
|
||||
"onboardingDashboard": "Onboarding",
|
||||
"onboardingDashboard11": "<b>Welcome to your Homepage.</b> This is your personalized page, which you can customize to your liking.<br />We've included some materials to help you get started, but feel free to make adjustments as needed.",
|
||||
"onboardingDashboard12": "Let's take a few minutes to explore the features together.",
|
||||
"onboardingDashboard21": "<b>Sets, acting as filters for your objects</b>, are featured on your Homepage.",
|
||||
"onboardingDashboard22": "Sets make it easy to navigate and collect specific Objects, such as Notes, Links, Tasks, ideas, and more.",
|
||||
"onboardingDashboard23": "To access different Set Views, simply select them.",
|
||||
"onboardingDashboard31": "<b>Objects in Anytype</b> have specific types depending on their purpose. You can use system types or define custom ones. Structure objects with Relations and links.",
|
||||
"onboardingDashboard32": "To add an Object to a Set, click the <span class=\"highlight\">New</span> button and view its relation as properties in columns.",
|
||||
"onboardingDashboard11": "<b>Welcome to your Homepage.</b> This is your personalized page, which you can customize to your liking.",
|
||||
"onboardingDashboard12": "Feel free to make adjustments as needed.",
|
||||
"onboardingDashboard13": "Let's take a few minutes to explore the features together.",
|
||||
"onboardingDashboard41": "<b>You'll find the Sidebar on the left.</b> It's a navigation tool that you can customize with multiple widget types.",
|
||||
"onboardingDashboard42": "Change the Widget appearance and see what looks best. Make your Favorites as a Tree Widget.",
|
||||
"onboardingDashboard51": "<b>Great job!</b> You have completed this section. Feel free to explore other menus in the interface, such as Library and Sets.",
|
||||
|
@ -1577,13 +1573,13 @@
|
|||
"errorAccountRecover109": "Account has been deleted",
|
||||
"errorObjectImport7": "Import has not been completed. CSV import supports up to 1000 rows and 10 columns.",
|
||||
|
||||
"objectOrigin0": "User",
|
||||
"objectOrigin1": "Clipboard",
|
||||
"objectOrigin2": "Drag'n'Drop",
|
||||
"objectOrigin3": "Import",
|
||||
"objectOrigin4": "Webclipper",
|
||||
"objectOrigin5": "Sharing Extension",
|
||||
"objectOrigin6": "Usecase",
|
||||
"objectOrigin7": "Built-in"
|
||||
"origin0": "User",
|
||||
"origin1": "Clipboard",
|
||||
"origin2": "Drag'n'Drop",
|
||||
"origin3": "Import",
|
||||
"origin4": "Webclipper",
|
||||
"origin5": "Sharing Extension",
|
||||
"origin6": "Usecase",
|
||||
"origin7": "Built-in"
|
||||
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
.day.first { border-top-width: 0px; }
|
||||
|
||||
.day.active {
|
||||
.number {
|
||||
display: inline-block; color: $colorTextInversion; background-color: $colorSystemAccent100; border-radius: 12px;
|
||||
padding: 0px 7px; align-self: flex-end;
|
||||
.number { padding: 0px; color: $colorTextInversion; }
|
||||
.number {
|
||||
.inner { background-color: $colorSystemAccent100; border-radius: 12px; padding: 0px 7px; align-self: flex-end; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,11 @@
|
|||
}
|
||||
|
||||
.day {
|
||||
.number { @include text-paragraph; text-align: right; }
|
||||
.number { @include text-paragraph; text-align: right; padding: 0px 8px; }
|
||||
.number {
|
||||
.inner { display: inline-block; }
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex; flex-direction: row; align-items: center; gap: 0px 4px; @include text-small; @include text-overflow-nw;
|
||||
margin: 0px 0px 2px 0px; position: relative; padding: 0px 8px; border-radius: 4px;
|
||||
|
|
|
@ -19,6 +19,14 @@
|
|||
}
|
||||
|
||||
.card {
|
||||
.dropTarget { height: 100%; }
|
||||
.dropTarget.isOver { box-shadow: 0px 0px; }
|
||||
.dropTarget.isOver::before { content: ""; position: absolute; background: $colorSystemAccent100; width: 2px; height: 100%; border-radius: 2px; top: 0px; }
|
||||
.dropTarget.isOver.top::before { left: -10px; }
|
||||
.dropTarget.isOver.bottom::before { right: -10px; }
|
||||
|
||||
.selectable.isSelectionSelected::after { border-radius: 12px; }
|
||||
|
||||
.selectable { height: 100%; }
|
||||
.itemContent > .inner { padding: 16px; }
|
||||
|
||||
|
@ -92,13 +100,6 @@
|
|||
.input.name { padding: 0; height: unset; }
|
||||
}
|
||||
}
|
||||
|
||||
.viewContent.viewGallery.isCollection {
|
||||
.dropTarget.isOver { box-shadow: 0px 0px; }
|
||||
.dropTarget.isOver::before { content: ""; position: absolute; background: $colorSystemAccent100; width: 2px; height: 100%; border-radius: 2px; top: 0px; }
|
||||
.dropTarget.isOver.top::before { left: -10px; }
|
||||
.dropTarget.isOver.bottom::before { right: -10px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
|
||||
.cardName { flex-wrap: nowrap; vertical-align: top; max-width: 100%; }
|
||||
.cardName {
|
||||
.name { @include text-overflow-nw; line-height: 19px; }
|
||||
.name { @include text-overflow-nw; line-height: 19px; border-bottom: 0.075em solid; border-color: inherit; }
|
||||
}
|
||||
|
||||
.cardDescription { @include text-small; }
|
||||
|
|
|
@ -22,8 +22,14 @@
|
|||
.block.blockDataview {
|
||||
.dropTarget { padding: 0px !important; }
|
||||
|
||||
.viewItem {
|
||||
.record { left: 0px !important; top: 0px !important; overflow: hidden; }
|
||||
.viewContent {
|
||||
.record { position: relative !important; left: 0px !important; top: 0px !important; overflow: hidden; }
|
||||
.record {
|
||||
.selectable.isSelectionSelected::after { display: none; }
|
||||
}
|
||||
}
|
||||
.viewContent.viewGallery {
|
||||
.record { margin: 0px 10px 10px 0px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,9 +57,15 @@
|
|||
.day { display: flex; flex-direction: column; }
|
||||
.day {
|
||||
.number { @include text-paragraph; text-align: right; position: relative; z-index: 1; padding: 0px 8px; flex-shrink: 0; }
|
||||
.number {
|
||||
.inner { display: inline-block; }
|
||||
}
|
||||
}
|
||||
.day.active {
|
||||
.number { color: $colorSystemAccent100; }
|
||||
.number { padding: 0px; color: $colorTextInversion; }
|
||||
.number {
|
||||
.inner { background-color: $colorSystemAccent100; border-radius: 12px; padding: 0px 7px; align-self: flex-end; }
|
||||
}
|
||||
}
|
||||
.day.other {
|
||||
.number { color: $colorTextSecondary; }
|
||||
|
|
|
@ -3,7 +3,14 @@
|
|||
.pageMainNavigation {
|
||||
.wrapper > #loader { position: fixed; top: 0px; width: 100%; height: 100%; background: $colorBgPrimary; z-index: 1; }
|
||||
|
||||
.sides { display: flex; padding: 0px 16px; }
|
||||
.sideName { margin-bottom: 13px; @include text-common; font-weight: 500; padding: 0px 16px; }
|
||||
|
||||
.items { width: 33.33%; padding: 4px 0px; }
|
||||
.items.center { padding: 39px 16px 4px 16px; }
|
||||
.items {
|
||||
.row { width: 100%; padding: 0px 32px 0px 16px; }
|
||||
|
||||
.item {
|
||||
transition: $transitionAllCommon; position: relative; line-height: 48px; margin-bottom: 16px; padding: 0px;
|
||||
height: 80px; border: 1px solid $colorShapeSecondary; border-radius: 8px;
|
||||
|
@ -21,24 +28,31 @@
|
|||
width: 24px; height: 24px; position: absolute; right: -24px; top: 50%; transform: translateY(-50%);
|
||||
background-image: url('~img/arrow/nav0.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.item.active { background-color: $colorShapeHighlightMedium; }
|
||||
}
|
||||
|
||||
.sides { display: flex; padding: 0px 16px; }
|
||||
|
||||
.items { width: 33.33%; padding: 4px 0px; }
|
||||
.items.center { padding: 39px 16px 4px 16px; }
|
||||
.items {
|
||||
.row { width: 100%; padding: 0px 32px 0px 16px; }
|
||||
.item {
|
||||
.icon.arrow {
|
||||
width: 24px; height: 24px; position: absolute; right: -24px; top: 50%; transform: translateY(-50%);
|
||||
background-image: url('~img/arrow/nav0.svg');
|
||||
}
|
||||
}
|
||||
|
||||
.item.selected {
|
||||
padding: 16px; border-radius: 8px; border: 1px solid $colorShapeSecondary; transition: $transitionAllCommon; height: auto;
|
||||
}
|
||||
.item.selected {
|
||||
.iconObject { margin-bottom: 8px; }
|
||||
.name { margin-bottom: 1px; @include text-overflow-nw; height: 22px; }
|
||||
.descr { @include text-small; color: $colorTextSecondary; @include text-overflow; max-height: 54px; }
|
||||
.cover { position: relative; height: 156px; margin-top: 11px; border-radius: 2px; }
|
||||
|
||||
.buttons { margin-top: 16px; display: flex; flex-direction: row; align-items: center; gap: 0px 8px; }
|
||||
.buttons {
|
||||
.button { width: 100%; }
|
||||
.button {
|
||||
.icon.expand { background-image: url('~img/icon/expand.svg'); width: 20px; height: 20px; position: absolute; left: 8px; top: 6px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item.active { background: none; border-color: $colorSystemAccent100 !important; box-shadow: 0px 0px 0px 1px $colorSystemAccent100 inset; }
|
||||
.item.active {
|
||||
.icon.arrow { background-image: url('~img/arrow/nav1.svg'); }
|
||||
|
@ -50,25 +64,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.sideName { margin-bottom: 13px; @include text-common; font-weight: 500; padding: 0px 16px; }
|
||||
|
||||
.selected { padding: 16px; border-radius: 8px; border: 1px solid $colorShapeSecondary; transition: $transitionAllCommon; }
|
||||
.selected {
|
||||
.iconObject { margin-bottom: 8px; }
|
||||
.name { margin-bottom: 1px; @include text-overflow-nw; height: 22px; }
|
||||
.descr { @include text-small; color: $colorTextSecondary; @include text-overflow; max-height: 54px; }
|
||||
.cover { position: relative; height: 156px; margin-top: 11px; border-radius: 2px; }
|
||||
|
||||
.buttons { margin-top: 16px; display: flex; flex-direction: row; align-items: center; gap: 0px 8px; }
|
||||
.buttons {
|
||||
.button { width: 100%; }
|
||||
.button {
|
||||
.icon.expand { background-image: url('~img/icon/expand.svg'); width: 20px; height: 20px; position: absolute; left: 8px; top: 6px; }
|
||||
}
|
||||
}
|
||||
}
|
||||
.selected.active { border-color: $colorSystemAccent100 !important; box-shadow: 0px 0px 0px 1px $colorSystemAccent100; }
|
||||
|
||||
.items.right {
|
||||
.item {
|
||||
.icon.arrow { right: auto; left: -24px; }
|
||||
|
|
|
@ -265,11 +265,6 @@
|
|||
.iconObject { background-color: $colorShapeTertiary; }
|
||||
}
|
||||
}
|
||||
.block.blockLink.text {
|
||||
.linkCard {
|
||||
.cardName .name { border-color: $colorShapeTertiary; }
|
||||
}
|
||||
}
|
||||
.block.blockLink.card {
|
||||
.linkCard {
|
||||
.side.left, .side.right { border-color: $colorShapeTertiary; }
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Page, SelectionProvider, DragProvider, Progress, Toast, Preview as Prev
|
|||
import { commonStore, authStore, blockStore, detailStore, dbStore, menuStore, popupStore } from './store';
|
||||
import {
|
||||
I, C, UtilCommon, UtilRouter, UtilFile, UtilData, UtilObject, UtilMenu, keyboard, Storage, analytics, dispatcher, translate, Renderer,
|
||||
focus, Preview, Mark, Animation, Onboarding, Survey, UtilDate
|
||||
focus, Preview, Mark, Animation, Onboarding, Survey, UtilDate, Encode, Decode,
|
||||
} from 'Lib';
|
||||
import * as Docs from 'Docs';
|
||||
|
||||
|
@ -183,6 +183,8 @@ window.Lib = {
|
|||
Onboarding,
|
||||
Survey,
|
||||
Docs,
|
||||
Encode,
|
||||
Decode,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -729,8 +729,8 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
window.setTimeout(() => { ref.onClick(e); }, 15);
|
||||
};
|
||||
|
||||
analytics.event('CreateObject', {
|
||||
route: (isCollection ? 'Collection' : 'Set'),
|
||||
analytics.event('CreateObject', {
|
||||
route: this.analyticsRoute(),
|
||||
objectType: object.type,
|
||||
layout: object.layout,
|
||||
});
|
||||
|
@ -791,7 +791,7 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
const { rootId, block } = this.props;
|
||||
const menuParam = this.getMenuParam(e, dir);
|
||||
const isCollection = this.isCollection();
|
||||
const route = isCollection ? 'Collection' : 'Set';
|
||||
const route = this.analyticsRoute();
|
||||
const hasSources = isCollection || this.getSources().length;
|
||||
const view = this.getView();
|
||||
|
||||
|
@ -842,7 +842,6 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
onTemplateAdd (id?: string) {
|
||||
const typeId = id || this.getTypeId();
|
||||
const type = dbStore.getTypeById(typeId);
|
||||
const route = this.isCollection() ? 'Collection' : 'Set';
|
||||
const details: any = {
|
||||
targetObjectType: typeId,
|
||||
layout: type.recommendedLayout,
|
||||
|
@ -856,7 +855,7 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
const object = message.details;
|
||||
|
||||
focus.clear(true);
|
||||
analytics.event('CreateTemplate', { objectType: typeId, route });
|
||||
analytics.event('CreateTemplate', { objectType: typeId, route: this.analyticsRoute() });
|
||||
|
||||
UtilObject.openPopup(object);
|
||||
});
|
||||
|
@ -939,13 +938,13 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
const { x, y } = keyboard.mouse.page;
|
||||
return { width: 0, height: 0, x: x + 4, y: y };
|
||||
},
|
||||
onClose: () => { selection.clear(); },
|
||||
onClose: () => selection.clear(),
|
||||
data: {
|
||||
targetId: this.getObjectId(),
|
||||
objectIds: ids,
|
||||
subId,
|
||||
isCollection,
|
||||
route: isCollection ? 'Collection' : 'Set',
|
||||
route: this.analyticsRoute(),
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -1319,6 +1318,8 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
this.searchIds = null;
|
||||
this.reloadData();
|
||||
};
|
||||
|
||||
analytics.event('ScreenSearchDataview', { route: this.analyticsRoute() });
|
||||
}, Constant.delay.keyboard);
|
||||
};
|
||||
|
||||
|
@ -1361,6 +1362,10 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
|
|||
return this.searchIds;
|
||||
};
|
||||
|
||||
analyticsRoute () {
|
||||
return this.isCollection() ? 'Collection' : 'Set';
|
||||
};
|
||||
|
||||
resize () {
|
||||
if (this.frame) {
|
||||
raf.cancel(this.frame);
|
||||
|
|
|
@ -34,8 +34,8 @@ const CellObject = observer(class CellObject extends React.Component<I.Cell, Sta
|
|||
this.onInput = this.onInput.bind(this);
|
||||
this.onFocus = this.onFocus.bind(this);
|
||||
this.onBlur = this.onBlur.bind(this);
|
||||
this.focus = this.focus.bind(this);
|
||||
this.onDragEnd = this.onDragEnd.bind(this);
|
||||
this.focus = this.focus.bind(this);
|
||||
};
|
||||
|
||||
render () {
|
||||
|
@ -226,6 +226,7 @@ const CellObject = observer(class CellObject extends React.Component<I.Cell, Sta
|
|||
let value: any[] = Relation.getArrayValue(record[relation.relationKey]);
|
||||
value = value.map(id => detailStore.get(subId, id, []));
|
||||
value = value.filter(it => !it._empty_);
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
|
|
|
@ -328,6 +328,8 @@ const Controls = observer(class Controls extends React.Component<Props> {
|
|||
type: I.ViewType.Grid,
|
||||
groupRelationKey: view.groupRelationKey || Relation.getGroupOption(rootId, block.id, view.type, '')?.id,
|
||||
cardSize: view.cardSize || I.CardSize.Medium,
|
||||
filters: [],
|
||||
sorts: [],
|
||||
};
|
||||
|
||||
C.BlockDataviewViewCreate(rootId, block.id, newView, sources, (message: any) => {
|
||||
|
|
|
@ -80,7 +80,9 @@ const Item = observer(class Item extends React.Component<Props> {
|
|||
ref={node => this.node = node}
|
||||
className={cn.join(' ')}
|
||||
>
|
||||
<div className="number">{d}</div>
|
||||
<div className="number">
|
||||
<div className="inner">{d}</div>
|
||||
</div>
|
||||
<div className="items">
|
||||
{slice.map((item, i) => (
|
||||
<Item key={[ y, m, d, item.id ].join('-')} {...item} />
|
||||
|
|
|
@ -357,6 +357,9 @@ const BlockLink = observer(class BlockLink extends React.Component<I.BlockCompon
|
|||
const icon = node.find('.iconObject');
|
||||
const rect = (node.get(0) as Element).getBoundingClientRect();
|
||||
const mw = getWrapperWidth();
|
||||
const name = node.find('.cardName');
|
||||
|
||||
UtilCommon.textStyle(name, { border: 0.4 });
|
||||
|
||||
icon.length ? card.addClass('withIcon') : card.removeClass('withIcon');
|
||||
rect.width <= mw / 2 ? card.addClass('vertical') : card.removeClass('vertical');
|
||||
|
|
|
@ -320,9 +320,7 @@ const BlockText = observer(class BlockText extends React.Component<Props> {
|
|||
return;
|
||||
};
|
||||
|
||||
items.each((i: number, item) => {
|
||||
this.textStyle($(item));
|
||||
});
|
||||
items.each((i: number, item) => this.textStyle($(item)));
|
||||
|
||||
items.off('mouseenter.link');
|
||||
items.on('mouseenter.link', e => {
|
||||
|
|
|
@ -90,15 +90,13 @@ class DragLayer extends React.Component<object, State> {
|
|||
const node = $(this.node);
|
||||
const inner = node.find('#inner').html('');
|
||||
const container = UtilCommon.getPageContainer(keyboard.isPopup());
|
||||
|
||||
const wrap = $('<div></div>');
|
||||
let items: any[] = [];
|
||||
|
||||
switch (type) {
|
||||
case I.DropType.Block: {
|
||||
wrap.addClass('blocks');
|
||||
|
||||
items = ids.map(id => blockStore.getLeaf(rootId, id)).filter(it => it).map(it => new M.Block(UtilCommon.objectCopy(it)));
|
||||
const items = ids.map(id => blockStore.getLeaf(rootId, id)).filter(it => it).map(it => new M.Block(UtilCommon.objectCopy(it)));
|
||||
|
||||
items.forEach(block => {
|
||||
const clone = container.find(`#block-${block.id}`).clone();
|
||||
|
@ -122,7 +120,7 @@ class DragLayer extends React.Component<object, State> {
|
|||
|
||||
wrap.addClass('menus').append(add);
|
||||
|
||||
items = ids.map(relationKey => dbStore.getRelationByKey(relationKey)).filter(it => it);
|
||||
const items = ids.map(relationKey => dbStore.getRelationByKey(relationKey)).filter(it => it);
|
||||
|
||||
items.forEach(item => {
|
||||
const el = $(`#menuBlockRelationView #item-${item.id}`);
|
||||
|
@ -148,11 +146,10 @@ class DragLayer extends React.Component<object, State> {
|
|||
|
||||
ids.forEach((id: string, idx: number) => {
|
||||
const el = container.find(`#record-${id}`);
|
||||
const margin = idx * 10;
|
||||
const clone = el.clone().addClass('record');
|
||||
|
||||
view.append(clone);
|
||||
clone.css({ marginLeft: margin, marginTop: margin, zIndex: (ids.length - idx), width: el.width() });
|
||||
clone.css({ width: el.width() });
|
||||
});
|
||||
break;
|
||||
};
|
||||
|
|
|
@ -837,9 +837,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
|
|||
};
|
||||
|
||||
if (range.from == range.to) {
|
||||
keyboard.shortcut(`${cmd}+k`, e, () => {
|
||||
keyboard.onSearchPopup();
|
||||
});
|
||||
keyboard.shortcut(`${cmd}+k`, e, () => keyboard.onSearchPopup('Shortcut'));
|
||||
};
|
||||
|
||||
if (!isInsideTable && block.isText()) {
|
||||
|
|
|
@ -76,7 +76,7 @@ class Header extends React.Component<Props> {
|
|||
};
|
||||
|
||||
onSearch () {
|
||||
keyboard.onSearchPopup();
|
||||
keyboard.onSearchPopup('Header');
|
||||
};
|
||||
|
||||
onNavigation () {
|
||||
|
|
|
@ -56,7 +56,9 @@ const MenuCalendarDay = observer(class MenuCalendarDay extends React.Component<I
|
|||
|
||||
return (
|
||||
<div className={cn.join(' ')}>
|
||||
<div className="number">{d}</div>
|
||||
<div className="number">
|
||||
<div className="inner">{d}</div>
|
||||
</div>
|
||||
<div className="items">
|
||||
{items.map((item, i) => (
|
||||
<Item key={i} {...item} />
|
||||
|
|
|
@ -77,7 +77,7 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
|
|||
switch (relation.format) {
|
||||
|
||||
case I.RelationType.Tag:
|
||||
case I.RelationType.Status:
|
||||
case I.RelationType.Status: {
|
||||
Item = (element: any) => {
|
||||
return (
|
||||
<div
|
||||
|
@ -113,8 +113,9 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
|
|||
</React.Fragment>
|
||||
);
|
||||
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
|
|||
</React.Fragment>
|
||||
);
|
||||
break;
|
||||
};
|
||||
|
||||
case I.RelationType.Checkbox:
|
||||
case I.RelationType.Checkbox: {
|
||||
value = (
|
||||
<div className="item">
|
||||
<Select
|
||||
|
@ -160,13 +162,14 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
|
|||
arrowClassName="light"
|
||||
options={checkboxOptions}
|
||||
value={item.value ? '1' : '0'}
|
||||
onChange={(v: string) => { this.onChange('value', Boolean(Number(v)), true); }}
|
||||
onChange={v => this.onChange('value', Boolean(Number(v)), true)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
};
|
||||
|
||||
case I.RelationType.Date:
|
||||
case I.RelationType.Date: {
|
||||
if ([ I.FilterQuickOption.NumberOfDaysAgo, I.FilterQuickOption.NumberOfDaysNow ].includes(item.quickOption)) {
|
||||
value = (
|
||||
<div key="filter-value-date-days" className="item">
|
||||
|
@ -201,10 +204,10 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
|
|||
);
|
||||
onSubmit = (e: any) => { this.onSubmitDate(e); };
|
||||
};
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
default:
|
||||
default: {
|
||||
value = (
|
||||
<div className="item">
|
||||
<Input
|
||||
|
@ -212,13 +215,29 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
|
|||
value={item.value}
|
||||
placeholder={translate('commonValue')}
|
||||
onFocus={this.onFocusText}
|
||||
onKeyUp={(e: any, v: string) => { 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)}
|
||||
/>
|
||||
<Icon className="clear" onClick={this.onClear} />
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
if (Relation.isDictionary(item.relationKey)) {
|
||||
value = (
|
||||
<div className="item">
|
||||
<Select
|
||||
id={[ 'filter', 'dictionary', item.id ].join('-')}
|
||||
className="checkboxValue"
|
||||
arrowClassName="light"
|
||||
options={Relation.getDictionaryOptions(item.relationKey)}
|
||||
value={item.value}
|
||||
onChange={v => this.onChange('value', Number(v), true)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -141,7 +141,7 @@ const MenuViewLayout = observer(class MenuViewLayout extends React.Component<I.M
|
|||
save (withName?: boolean) {
|
||||
const { param } = this.props;
|
||||
const { data } = param;
|
||||
const { rootId, blockId, onSave, readonly, getView } = data;
|
||||
const { rootId, blockId, onSave, readonly } = data;
|
||||
const block = blockStore.getLeaf(rootId, blockId);
|
||||
|
||||
if (readonly || !block) {
|
||||
|
@ -172,6 +172,9 @@ const MenuViewLayout = observer(class MenuViewLayout extends React.Component<I.M
|
|||
this.param.name = this.getViewName();
|
||||
};
|
||||
|
||||
let view = data.view.get();
|
||||
view = Object.assign(view, this.param);
|
||||
|
||||
C.BlockDataviewViewUpdate(rootId, blockId, current.id, this.param, () => {
|
||||
if (clearGroups) {
|
||||
Dataview.groupUpdate(rootId, blockId, current.id, []);
|
||||
|
@ -389,6 +392,8 @@ const MenuViewLayout = observer(class MenuViewLayout extends React.Component<I.M
|
|||
};
|
||||
|
||||
getViewName (name?: string) {
|
||||
console.log(name, this.param.name);
|
||||
|
||||
return (name || this.param.name || Dataview.defaultViewName(this.param.type)).trim();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import * as React from 'react';
|
||||
import $ from 'jquery';
|
||||
import arrayMove from 'array-move';
|
||||
import { observable } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
|
||||
import { AutoSizer, CellMeasurer, InfiniteLoader, List as VList, CellMeasurerCache } from 'react-virtualized';
|
||||
import { Icon } from 'Component';
|
||||
import { I, C, UtilCommon, keyboard, Relation, analytics, UtilObject, translate, UtilMenu } from 'Lib';
|
||||
import { I, C, UtilCommon, keyboard, Relation, analytics, UtilObject, translate, UtilMenu, Dataview } from 'Lib';
|
||||
import { menuStore, dbStore, blockStore } from 'Store';
|
||||
import Constant from 'json/constant.json';
|
||||
|
||||
|
@ -217,35 +216,21 @@ const MenuViewList = observer(class MenuViewList extends React.Component<I.Menu>
|
|||
};
|
||||
|
||||
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<I.Menu>
|
|||
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,
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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); };
|
||||
|
|
|
@ -23,7 +23,15 @@ const MenuItemFilter = observer(class MenuItemFilter extends React.Component<Pro
|
|||
|
||||
render () {
|
||||
const { id, index, relation, condition, quickOption, subId, readonly, style, onOver, onClick, onRemove } = this.props;
|
||||
const conditionOptions = Relation.filterConditionsByType(relation.format);
|
||||
const isDictionary = Relation.isDictionary(relation.relationKey);
|
||||
|
||||
let conditionOptions = [];
|
||||
if (isDictionary) {
|
||||
conditionOptions = Relation.filterConditionsDictionary();
|
||||
} else {
|
||||
conditionOptions = Relation.filterConditionsByType(relation.format);
|
||||
};
|
||||
|
||||
const conditionOption: any = conditionOptions.find(it => 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<Pro
|
|||
};
|
||||
};
|
||||
|
||||
if (isDictionary) {
|
||||
const options = Relation.getDictionaryOptions(relation.relationKey);
|
||||
const option = options.find(it => it.id == v);
|
||||
|
||||
if (option) {
|
||||
v = option.name;
|
||||
};
|
||||
};
|
||||
|
||||
if ([ I.FilterCondition.None, I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(condition)) {
|
||||
v = null;
|
||||
};
|
||||
|
|
|
@ -226,12 +226,6 @@ const MenuOnboarding = observer(class MenuSelect extends React.Component<I.Menu,
|
|||
break;
|
||||
};
|
||||
|
||||
case 'dashboard': {
|
||||
close();
|
||||
UtilObject.openHome('route');
|
||||
break;
|
||||
};
|
||||
|
||||
case 'changeType':
|
||||
menuStore.open('typeSuggest', {
|
||||
element: `#${getId()}`,
|
||||
|
|
|
@ -95,7 +95,7 @@ const Page = observer(class Page extends React.Component<I.PageComponent> {
|
|||
} else {
|
||||
content = (
|
||||
<div className="pageFlex">
|
||||
<Sidebar {...this.props} />
|
||||
<Sidebar key="sidebar" {...this.props} />
|
||||
<div id="sidebarDummyLeft" className="sidebarDummy left" />
|
||||
{wrap}
|
||||
<div id="sidebarDummyRight" className="sidebarDummy right" />
|
||||
|
@ -155,8 +155,7 @@ const Page = observer(class Page extends React.Component<I.PageComponent> {
|
|||
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<I.PageComponent> {
|
|||
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<I.PageComponent> {
|
|||
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 () {
|
||||
|
|
|
@ -108,7 +108,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
|
|||
const { name, description, layout, snippet, coverType, coverId, coverX, coverY, coverScale } = item;
|
||||
|
||||
return (
|
||||
<div id={'item-' + item.id} className="selected">
|
||||
<div id={'item-' + item.id} className="item selected">
|
||||
<IconObject object={item} forceLetter={true} size={48} />
|
||||
<ObjectName object={item} />
|
||||
<ObjectDescription object={item} />
|
||||
|
@ -116,7 +116,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
|
|||
{coverId && coverType ? <Cover type={coverType} id={coverId} image={coverId} className={coverId} x={coverX} y={coverY} scale={coverScale} withScale={true} /> : ''}
|
||||
|
||||
<div className="buttons">
|
||||
<Button text={translate('popupNavigationOpen')} className="c36" onClick={(e: any) => { this.onConfirm(e, item); }} />
|
||||
<Button text={translate('popupNavigationOpen')} className="c36" onClick={e => this.onConfirm(e, item)} />
|
||||
{isPopup ? <Button text={translate('popupNavigationCancel')} className="c36" color="blank" onClick={() => { popupStore.close('page'); }} /> : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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),
|
||||
|
|
|
@ -174,6 +174,10 @@ const PopupSearch = observer(class PopupSearch extends React.Component<I.Popup,
|
|||
};
|
||||
|
||||
componentDidMount () {
|
||||
const { param } = this.props;
|
||||
const { data } = param;
|
||||
const { route } = data;
|
||||
|
||||
this._isMounted = true;
|
||||
this.n = -1;
|
||||
|
||||
|
@ -182,6 +186,8 @@ const PopupSearch = observer(class PopupSearch extends React.Component<I.Popup,
|
|||
this.resize();
|
||||
|
||||
focus.clear(true);
|
||||
|
||||
analytics.event('ScreenSearch', { route });
|
||||
};
|
||||
|
||||
componentDidUpdate () {
|
||||
|
|
|
@ -295,7 +295,6 @@ const SelectionProvider = observer(class SelectionProvider extends React.Compone
|
|||
|
||||
this.hide();
|
||||
this.setIsSelecting(false);
|
||||
|
||||
this.cache.clear();
|
||||
this.focused = '';
|
||||
this.range = null;
|
||||
|
@ -337,7 +336,11 @@ const SelectionProvider = observer(class SelectionProvider extends React.Compone
|
|||
};
|
||||
};
|
||||
|
||||
cacheRect (node: any) {
|
||||
cacheRect (node: any): { x: number; y: number; width: number; height: number; } {
|
||||
if (!node.id) {
|
||||
return { x: 0, y: 0, width: 0, height: 0 };
|
||||
};
|
||||
|
||||
let cached = this.cache.get(node.id);
|
||||
if (cached) {
|
||||
return cached;
|
||||
|
|
|
@ -83,7 +83,7 @@ const Graph = observer(class Graph extends React.Component<Props> {
|
|||
|
||||
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<Props> {
|
|||
.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<Props> {
|
|||
};
|
||||
|
||||
setRootId (id: string) {
|
||||
this.send('onSetRootId', { rootId: id });
|
||||
this.send('setRootId', { rootId: id });
|
||||
};
|
||||
|
||||
send (id: string, param: any, transfer?: any[]) {
|
||||
|
|
|
@ -125,7 +125,7 @@ class Navigation extends React.Component {
|
|||
};
|
||||
|
||||
onSearch () {
|
||||
keyboard.onSearchPopup();
|
||||
keyboard.onSearchPopup('Navigation');
|
||||
};
|
||||
|
||||
onProfile () {
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
@ -403,7 +403,7 @@ const WidgetIndex = observer(class WidgetIndex extends React.Component<Props> {
|
|||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,15 +5,9 @@ export default {
|
|||
category: translate('onboardingMainGraph'),
|
||||
items: [
|
||||
{
|
||||
description: `
|
||||
<p>${translate('onboardingMainGraph11')}</p>
|
||||
<p>${translate('onboardingMainGraph12')}</p>
|
||||
`,
|
||||
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: `
|
||||
<p>${translate('onboardingDashboard11')}</p>
|
||||
<p>${translate('onboardingDashboard12')}</p>
|
||||
<p>${translate('onboardingDashboard13')}</p>
|
||||
`,
|
||||
video: './img/help/onboarding/homepage.mp4',
|
||||
},
|
||||
{
|
||||
description: `
|
||||
<p>${translate('onboardingDashboard21')}</p>
|
||||
<p>${translate('onboardingDashboard22')}</p>
|
||||
<p>${translate('onboardingDashboard23')}</p>
|
||||
`,
|
||||
video: './img/help/onboarding/sets.mp4',
|
||||
},
|
||||
{
|
||||
description: `
|
||||
<p>${translate('onboardingDashboard31')}</p>
|
||||
<p>${translate('onboardingDashboard32')}</p>
|
||||
`,
|
||||
video: './img/help/onboarding/objects.mp4',
|
||||
},
|
||||
{
|
||||
description: `
|
||||
<p>${translate('onboardingDashboard41')}</p>
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -391,9 +391,7 @@ class Analytics {
|
|||
|
||||
popupMapper (params: any): string {
|
||||
const { id } = params;
|
||||
const map = {
|
||||
search: 'ScreenSearch',
|
||||
};
|
||||
const map = {};
|
||||
|
||||
return map[id] || '';
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 },
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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: '',
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue