1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00

Merge branch 'main' of github.com:anyproto/anytype-ts into feature/JS-6113-space-store-migration

This commit is contained in:
Andrew Simachev 2025-01-27 12:14:24 +01:00
commit c52b20340d
No known key found for this signature in database
GPG key ID: 1DFE44B21443F0EF
163 changed files with 2289 additions and 1560 deletions

View file

@ -21,7 +21,8 @@
body { font-family: 'Inter', Helvetica, Arial, sans-serif; font-size: 14px; line-height: 22px; background-color: #fff; color: #252525; }
.content { display: flex; align-items: center; justify-content: center; flex-direction: column; padding: 16px; height: 100%; }
.title { font-size: 18px; line-height: 26px; letter-spacing: -0.28px; font-weight: 700; margin: 0px 0px 24px 0px; text-align: center; }
.title { font-size: 18px; line-height: 26px; letter-spacing: -0.28px; font-weight: 700; margin: 0px 0px 4px 0px; text-align: center; }
.description { font-size: 14px; line-height: 22px; letter-spacing: -0.28px; font-weight: 400; margin: 0px 0px 24px 0px; text-align: center; }
#challenge { display: flex; align-items: center; justify-content: center; flex-direction: row; gap: 0px 8px; }
#challenge .number { background-color: #f2f2f2; border-radius: 12px; font-weight: 700; font-size: 36px; line-height: 40px; padding: 12px; }
@ -31,6 +32,7 @@
<body>
<div class="content">
<div id="title" class="title"></div>
<div id="description" class="description"></div>
<div id="challenge"></div>
</div>
<script type="text/javascript">
@ -38,6 +40,7 @@
const win = $(window);
const html = $('html')
const title = $('#title');
const description = $('#description');
const challengeEl = $('#challenge');
window.Electron.on('challenge', (e, data) => {
@ -57,6 +60,7 @@
contentType: 'application/json',
success: data => {
title.text(data.challengeTitle);
description.text(data.challengeDescription);
},
});
});

View file

@ -130,6 +130,9 @@
// Github Gist
if (processor == Processor.GithubGist) {
loadGithubGist(html);
} else
if (processor == Processor.Kroki) {
loadKroki(html);
} else {
if ((processor == Processor.Telegram) && !html.match(/<script/)) {
const post = html.replace(/^https:\/\/t.me\//, '');
@ -179,7 +182,7 @@
function resize () {
const height = useRootHeight ? root.height() : document.documentElement.scrollHeight;
window.parent.postMessage({ height, blockId }, '*');
window.parent.postMessage({ type: 'resize', height, blockId }, '*');
};
function insertHtml (html) {
@ -246,6 +249,26 @@
});
};
function loadKroki (html) {
if (!html) {
return;
};
$.ajax({
url: html,
dataType: 'text',
timeout: 1000,
success: (data) => {
root.html(data);
root.find('a').off('click').on('click', function (e) {
e.preventDefault();
window.parent.postMessage({ type: 'openUrl', url: $(this).attr('href') }, '*');
});
}
});
};
function getEnvironmentContent (processor) {
const libs = [];

View file

@ -10,6 +10,8 @@ const remote = require('@electron/remote/main');
const { installNativeMessagingHost } = require('./electron/js/lib/installNativeMessagingHost.js');
const binPath = fixPathForAsarUnpack(path.join(__dirname, 'dist', `anytypeHelper${is.windows ? '.exe' : ''}`));
const Store = require('electron-store');
const suffix = app.isPackaged ? '' : 'dev';
const store = new Store({ name: [ 'localStorage', suffix ].join('-') });
// Fix notifications app name
if (is.windows) {
@ -17,7 +19,7 @@ if (is.windows) {
};
storage.setDataPath(app.getPath('userData'));
Store.initRenderer();
//Store.initRenderer();
const Api = require('./electron/js/api.js');
const ConfigManager = require('./electron/js/config.js');
@ -53,6 +55,16 @@ powerMonitor.on('resume', () => {
Util.log('info', '[PowerMonitor] resume');
});
ipcMain.on('storeGet', (e, key) => {
e.returnValue = store.get(key);
});
ipcMain.on('storeSet', (e, key, value) => {
e.returnValue = store.set(key, value);
});
ipcMain.on('storeDelete', (e, key) => {
e.returnValue = store.delete(key);
});
let deeplinkingUrl = '';
let waitLibraryPromise = null;
let mainWindow = null;

View file

@ -217,6 +217,10 @@ class Api {
WindowManager.createChallenge(param);
};
hideChallenge (win, param) {
WindowManager.closeChallenge(param);
};
reload (win, route) {
win.route = route;
win.webContents.reload();

View file

@ -5,9 +5,6 @@ const os = require('os');
const path = require('path');
const mime = require('mime-types');
const tmpPath = () => app.getPath('temp');
const Store = require('electron-store');
const suffix = app.isPackaged ? '' : 'dev';
const store = new Store({ name: [ 'localStorage', suffix ].join('-') });
contextBridge.exposeInMainWorld('Electron', {
version: {
@ -19,9 +16,9 @@ contextBridge.exposeInMainWorld('Electron', {
platform: os.platform(),
arch: process.arch,
storeSet: (key, value) => store.set(key, value),
storeGet: key => store.get(key),
storeDelete: key => store.delete(key),
storeGet: key => ipcRenderer.sendSync('storeGet', key),
storeSet: (key, value) => ipcRenderer.sendSync('storeSet', key, value),
storeDelete: key => ipcRenderer.sendSync('storeDelete', key),
isPackaged: app.isPackaged,
userPath: () => app.getPath('userData'),

View file

@ -21,7 +21,6 @@ class WindowManager {
list = new Set();
create (options, param) {
const { route, isChild } = options;
const { hideMenuBar } = ConfigManager.config;
param = Object.assign({
@ -45,8 +44,7 @@ class WindowManager {
remote.enable(win.webContents);
win.isChild = isChild;
win.route = route;
win = Object.assign(win, options);
win.windowId = win.id;
this.list.add(win);
@ -144,33 +142,39 @@ class WindowManager {
createChallenge (options) {
const { screen } = require('electron');
const primaryDisplay = screen.getPrimaryDisplay();
const { width } = primaryDisplay.workAreaSize;
const { width, height } = primaryDisplay.workAreaSize;
const win = this.create({}, {
const win = this.create({ ...options, isChallenge: true }, {
backgroundColor: '',
width: 424,
height: 232,
x: Math.floor(width / 2 - 212),
y: 50,
y: Math.floor(height - 282),
titleBarStyle: 'hidden',
alwaysOnTop: true,
focusable: true,
skipTaskbar: true,
});
win.loadURL('file://' + path.join(Util.appPath, 'dist', 'challenge', `index.html`));
win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
win.loadURL('file://' + path.join(Util.appPath, 'dist', 'challenge', 'index.html'));
win.setMenu(null);
is.windows || is.linux ? win.showInactive() : win.show();
win.focus();
win.showInactive(); // show inactive to prevent focus loose from other app
win.webContents.once('did-finish-load', () => {
win.webContents.postMessage('challenge', options);
});
setTimeout(() => {
if (win && !win.isDestroyed()) {
setTimeout(() => this.closeChallenge(options), 30000);
return win;
};
closeChallenge (options) {
for (const win of this.list) {
if (win && win.isChallenge && (win.challenge == options.challenge) && !win.isDestroyed()) {
win.close();
};
}, 30000);
return win;
};
};
command (win, cmd, param) {

View file

@ -52,7 +52,8 @@
"https://cdnjs.cloudflare.com",
"https://*.bilibili.com",
"https://s1.hdslb.com",
"https://static.sketchfab.com"
"https://static.sketchfab.com",
"https://*.bstarstatic.com"
],
"font-src": [
@ -69,7 +70,8 @@
"https://*.fbcdn.net",
"https://static.cdninstagram.com",
"https://telegram.org",
"https://static.sketchfab.com"
"https://static.sketchfab.com",
"https://*.bstarstatic.com"
],
"connect-src": [
@ -121,7 +123,11 @@
"https://media.sketchfab.com",
"https://sentry.io",
"https://*.any.coop",
"https://*.amplitude.com"
"https://*.amplitude.com",
"https://kroki.io",
"https://*.vimeo.com",
"https://*.statsigapi.net",
"https://*.bstarstatic.com"
],
"script-src-elem": [
@ -155,7 +161,11 @@
"https://codepen.io",
"https://cdnjs.cloudflare.com",
"https://*.hdslb.com",
"https://static.sketchfab.com"
"https://static.sketchfab.com",
"https://*.codepenassets.com",
"https://*.bstarstatic.com",
"https://*.googletagmanager.com",
"https://*.facebook.net"
],
"frame-src": [
@ -171,6 +181,7 @@
"https://*.figma.com",
"https://*.github.com",
"https://*.bilibili.com",
"https://*.bilibili.tv",
"https://platform.twitter.com",
"https://*.openstreetmap.org",
"https://embed.reddit.com",

View file

@ -66,6 +66,8 @@ const Index = observer(class Index extends React.Component<I.PageComponent, Stat
login () {
const appKey = Storage.get('appKey');
console.log('appKey', appKey);
if (appKey) {
Util.authorize(appKey, () => {
const { serverPort, gatewayPort } = S.Extension;

View file

@ -1 +1 @@
0.38.7
0.39.0-rc08

16
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "anytype",
"version": "0.44.0",
"version": "0.44.11-alpha",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "anytype",
"version": "0.44.0",
"version": "0.44.11-alpha",
"hasInstallScript": true,
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {
@ -6526,9 +6526,9 @@
}
},
"node_modules/dom-iterator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dom-iterator/-/dom-iterator-1.0.0.tgz",
"integrity": "sha512-7dsMOQI07EMU98gQM8NSB3GsAiIeBYIPKpnxR3c9xOvdvBjChAcOM0iJ222I3p5xyiZO9e5oggkNaCusuTdYig==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/dom-iterator/-/dom-iterator-1.0.2.tgz",
"integrity": "sha512-BMelEjhy08OpoWF3v/jrPtx7PZCyP1VM9yiB7rJk19UVmt7zTN5rqoC0Jea+EyT0M6v/VokL0LxIlGLUOBJZ2g==",
"dependencies": {
"component-props": "1.1.1",
"component-xor": "0.0.4"
@ -18235,9 +18235,9 @@
}
},
"node_modules/systeminformation": {
"version": "5.23.5",
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.23.5.tgz",
"integrity": "sha512-PEpJwhRYxZgBCAlWZhWIgfMTjXLqfcaZ1pJsJn9snWNfBW/Z1YQg1mbIUSWrEV3ErAHF7l/OoVLQeaZDlPzkpA==",
"version": "5.25.11",
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.25.11.tgz",
"integrity": "sha512-jI01fn/t47rrLTQB0FTlMCC+5dYx8o0RRF+R4BPiUNsvg5OdY0s9DKMFmJGrx5SwMZQ4cag0Gl6v8oycso9b/g==",
"os": [
"darwin",
"linux",

View file

@ -1,6 +1,6 @@
{
"name": "anytype",
"version": "0.44.0",
"version": "0.44.11-alpha",
"description": "Anytype",
"main": "electron.js",
"scripts": {
@ -298,10 +298,22 @@
"from": "node_modules/@electron",
"to": "node_modules/@electron"
},
{
"from": "node_modules/ajv",
"to": "node_modules/ajv"
},
{
"from": "node_modules/ajv-formats",
"to": "node_modules/ajv-formats"
},
{
"from": "node_modules/async",
"to": "node_modules/async"
},
{
"from": "node_modules/atomically",
"to": "node_modules/atomically"
},
{
"from": "node_modules/balanced-match",
"to": "node_modules/balanced-match"
@ -318,14 +330,26 @@
"from": "node_modules/concat-map",
"to": "node_modules/concat-map"
},
{
"from": "node_modules/conf",
"to": "node_modules/conf"
},
{
"from": "node_modules/core-util-is",
"to": "node_modules/core-util-is"
},
{
"from": "node_modules/debounce-fn",
"to": "node_modules/debounce-fn"
},
{
"from": "node_modules/debug",
"to": "node_modules/debug"
},
{
"from": "node_modules/dot-prop",
"to": "node_modules/dot-prop"
},
{
"from": "node_modules/electron-dl",
"to": "node_modules/electron-dl"
@ -342,6 +366,10 @@
"from": "node_modules/electron-log",
"to": "node_modules/electron-log"
},
{
"from": "node_modules/electron-store",
"to": "node_modules/electron-store"
},
{
"from": "node_modules/electron-updater",
"to": "node_modules/electron-updater"
@ -354,6 +382,10 @@
"from": "node_modules/electron-window-state",
"to": "node_modules/electron-window-state"
},
{
"from": "node_modules/env-paths",
"to": "node_modules/env-paths"
},
{
"from": "node_modules/ext-list",
"to": "node_modules/ext-list"
@ -362,6 +394,18 @@
"from": "node_modules/ext-name",
"to": "node_modules/ext-name"
},
{
"from": "node_modules/fast-deep-equal",
"to": "node_modules/fast-deep-equal"
},
{
"from": "node_modules/fast-uri",
"to": "node_modules/fast-uri"
},
{
"from": "node_modules/find-up",
"to": "node_modules/find-up"
},
{
"from": "node_modules/fs-extra",
"to": "node_modules/fs-extra"
@ -398,6 +442,10 @@
"from": "node_modules/inherits",
"to": "node_modules/inherits"
},
{
"from": "node_modules/is-obj",
"to": "node_modules/is-obj"
},
{
"from": "node_modules/is-plain-obj",
"to": "node_modules/is-plain-obj"
@ -410,6 +458,10 @@
"from": "node_modules/js-yaml",
"to": "node_modules/js-yaml"
},
{
"from": "node_modules/json-schema-traverse",
"to": "node_modules/json-schema-traverse"
},
{
"from": "node_modules/jsonfile",
"to": "node_modules/jsonfile"
@ -422,6 +474,10 @@
"from": "node_modules/lazy-val",
"to": "node_modules/lazy-val"
},
{
"from": "node_modules/locate-path",
"to": "node_modules/locate-path"
},
{
"from": "node_modules/lockfile",
"to": "node_modules/lockfile"
@ -442,6 +498,10 @@
"from": "node_modules/mime-db",
"to": "node_modules/mime-db"
},
{
"from": "node_modules/mimic-fn",
"to": "node_modules/mimic-fn"
},
{
"from": "node_modules/minimatch",
"to": "node_modules/minimatch"
@ -466,6 +526,22 @@
"from": "node_modules/once",
"to": "node_modules/once"
},
{
"from": "node_modules/onetime",
"to": "node_modules/onetime"
},
{
"from": "node_modules/p-limit",
"to": "node_modules/p-limit"
},
{
"from": "node_modules/p-locate",
"to": "node_modules/p-locate"
},
{
"from": "node_modules/p-try",
"to": "node_modules/p-try"
},
{
"from": "node_modules/path-exists",
"to": "node_modules/path-exists"
@ -474,6 +550,10 @@
"from": "node_modules/path-is-absolute",
"to": "node_modules/path-is-absolute"
},
{
"from": "node_modules/pkg-up",
"to": "node_modules/pkg-up"
},
{
"from": "node_modules/pupa",
"to": "node_modules/pupa"

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="20" viewBox="0 0 21 20" fill="none">
<path d="M10.75 4L16.75 10L10.75 16" stroke="#B6B6B6" stroke-width="1.5" stroke-linecap="round"/>
<rect width="13" height="1.5" transform="matrix(1 0 0 -1 3.75 10.75)" fill="#B6B6B6"/>
</svg>

After

Width:  |  Height:  |  Size: 296 B

4
src/img/icon/info.svg Normal file
View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="none">
<circle cx="10" cy="10" r="9" fill="#EBEBEB"/>
<path d="M8.83736 12.0078H10.4929V11.8786C10.5028 10.8246 10.8459 10.3423 11.6562 9.84517C12.571 9.2983 13.1428 8.55256 13.1428 7.41406C13.1428 5.73367 11.8352 4.67969 9.93608 4.67969C8.19602 4.67969 6.78409 5.64418 6.73438 7.53338H8.50426C8.54901 6.59872 9.22514 6.15128 9.92614 6.15128C10.6868 6.15128 11.2983 6.65838 11.2983 7.43892C11.2983 8.13494 10.8359 8.61222 10.2344 8.99006C9.3544 9.53693 8.8473 10.0888 8.83736 11.8786V12.0078ZM9.70739 15.1101C10.294 15.1101 10.7962 14.6229 10.8011 14.0163C10.7962 13.4197 10.294 12.9325 9.70739 12.9325C9.10085 12.9325 8.60866 13.4197 8.61364 14.0163C8.60866 14.6229 9.10085 15.1101 9.70739 15.1101Z" fill="#949494"/>
</svg>

After

Width:  |  Height:  |  Size: 822 B

View file

@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.75049 7C2.33628 7 2.00049 7.33579 2.00049 7.75V14.5C2.00049 16.433 3.56749 18 5.50049 18H14.5C16.433 18 18 16.433 18 14.5V7.75C18 7.33579 17.6642 7 17.25 7C16.8358 7 16.5 7.33579 16.5 7.75V14.5C16.5 15.6046 15.6046 16.5 14.5 16.5H5.50049C4.39592 16.5 3.50049 15.6046 3.50049 14.5V7.75C3.50049 7.33579 3.1647 7 2.75049 7Z" fill="#B6B6B6"/>
<path d="M13.5 10L10 13.5L6.5 10" stroke="#B6B6B6" stroke-width="1.5" stroke-linecap="round"/>
<rect x="-0.375" y="-0.375" width="9.75" height="0.75" transform="matrix(0 -1 -1 0 10 11.75)" fill="#B6B6B6" stroke="#B6B6B6" stroke-width="0.75"/>
</svg>

After

Width:  |  Height:  |  Size: 737 B

View file

@ -1,11 +1,12 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="11.25" width="17" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="20" y="15.25" width="12" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="9" y="10" width="8" height="8" rx="2" fill="#E3E3E3"/>
<rect x="20" y="21.25" width="17" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="20" y="25.25" width="12" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="9" y="20" width="8" height="8" rx="2" fill="#E3E3E3"/>
<rect x="20" y="31.25" width="17" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="20" y="35.25" width="12" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="9" y="30" width="8" height="8" rx="2" fill="#E3E3E3"/>
<rect x="13.375" y="13.625" width="23.25" height="0.75" rx="0.375" stroke="#B6B6B6" stroke-width="0.75"/>
<path d="M9.5 14C9.5 13.7239 9.72386 13.5 10 13.5C10.2761 13.5 10.5 13.7239 10.5 14C10.5 14.2761 10.2761 14.5 10 14.5C9.72386 14.5 9.5 14.2761 9.5 14Z" stroke="#B6B6B6"/>
<path d="M9.5 19C9.5 18.7239 9.72386 18.5 10 18.5C10.2761 18.5 10.5 18.7239 10.5 19C10.5 19.2761 10.2761 19.5 10 19.5C9.72386 19.5 9.5 19.2761 9.5 19Z" stroke="#B6B6B6"/>
<path d="M13.5 19C13.5 18.8619 13.6119 18.75 13.75 18.75H30.25C30.3881 18.75 30.5 18.8619 30.5 19C30.5 19.1381 30.3881 19.25 30.25 19.25H13.75C13.6119 19.25 13.5 19.1381 13.5 19Z" stroke="#B6B6B6"/>
<rect x="13.375" y="23.625" width="23.25" height="0.75" rx="0.375" stroke="#B6B6B6" stroke-width="0.75"/>
<path d="M9.5 24C9.5 23.7239 9.72386 23.5 10 23.5C10.2761 23.5 10.5 23.7239 10.5 24C10.5 24.2761 10.2761 24.5 10 24.5C9.72386 24.5 9.5 24.2761 9.5 24Z" stroke="#B6B6B6"/>
<path d="M9.5 29C9.5 28.7239 9.72386 28.5 10 28.5C10.2761 28.5 10.5 28.7239 10.5 29C10.5 29.2761 10.2761 29.5 10 29.5C9.72386 29.5 9.5 29.2761 9.5 29Z" stroke="#B6B6B6"/>
<path d="M13.5 29C13.5 28.8619 13.6119 28.75 13.75 28.75H30.25C30.3881 28.75 30.5 28.8619 30.5 29C30.5 29.1381 30.3881 29.25 30.25 29.25H13.75C13.6119 29.25 13.5 29.1381 13.5 29Z" stroke="#B6B6B6"/>
<path d="M9.5 34C9.5 33.7239 9.72386 33.5 10 33.5C10.2761 33.5 10.5 33.7239 10.5 34C10.5 34.2761 10.2761 34.5 10 34.5C9.72386 34.5 9.5 34.2761 9.5 34Z" stroke="#B6B6B6"/>
<path d="M13.5 34C13.5 33.8619 13.6119 33.75 13.75 33.75H36.25C36.3881 33.75 36.5 33.8619 36.5 34C36.5 34.1381 36.3881 34.25 36.25 34.25H13.75C13.6119 34.25 13.5 34.1381 13.5 34Z" stroke="#B6B6B6"/>
</svg>

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

View file

@ -1,12 +1,11 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="13.375" y="13.625" width="23.25" height="0.75" rx="0.375" stroke="#B6B6B6" stroke-width="0.75"/>
<path d="M9.5 14C9.5 13.7239 9.72386 13.5 10 13.5C10.2761 13.5 10.5 13.7239 10.5 14C10.5 14.2761 10.2761 14.5 10 14.5C9.72386 14.5 9.5 14.2761 9.5 14Z" stroke="#B6B6B6"/>
<path d="M9.5 19C9.5 18.7239 9.72386 18.5 10 18.5C10.2761 18.5 10.5 18.7239 10.5 19C10.5 19.2761 10.2761 19.5 10 19.5C9.72386 19.5 9.5 19.2761 9.5 19Z" stroke="#B6B6B6"/>
<path d="M13.5 19C13.5 18.8619 13.6119 18.75 13.75 18.75H30.25C30.3881 18.75 30.5 18.8619 30.5 19C30.5 19.1381 30.3881 19.25 30.25 19.25H13.75C13.6119 19.25 13.5 19.1381 13.5 19Z" stroke="#B6B6B6"/>
<rect x="13.375" y="23.625" width="23.25" height="0.75" rx="0.375" stroke="#B6B6B6" stroke-width="0.75"/>
<path d="M9.5 24C9.5 23.7239 9.72386 23.5 10 23.5C10.2761 23.5 10.5 23.7239 10.5 24C10.5 24.2761 10.2761 24.5 10 24.5C9.72386 24.5 9.5 24.2761 9.5 24Z" stroke="#B6B6B6"/>
<path d="M9.5 29C9.5 28.7239 9.72386 28.5 10 28.5C10.2761 28.5 10.5 28.7239 10.5 29C10.5 29.2761 10.2761 29.5 10 29.5C9.72386 29.5 9.5 29.2761 9.5 29Z" stroke="#B6B6B6"/>
<path d="M13.5 29C13.5 28.8619 13.6119 28.75 13.75 28.75H30.25C30.3881 28.75 30.5 28.8619 30.5 29C30.5 29.1381 30.3881 29.25 30.25 29.25H13.75C13.6119 29.25 13.5 29.1381 13.5 29Z" stroke="#B6B6B6"/>
<path d="M9.5 34C9.5 33.7239 9.72386 33.5 10 33.5C10.2761 33.5 10.5 33.7239 10.5 34C10.5 34.2761 10.2761 34.5 10 34.5C9.72386 34.5 9.5 34.2761 9.5 34Z" stroke="#B6B6B6"/>
<path d="M13.5 34C13.5 33.8619 13.6119 33.75 13.75 33.75H36.25C36.3881 33.75 36.5 33.8619 36.5 34C36.5 34.1381 36.3881 34.25 36.25 34.25H13.75C13.6119 34.25 13.5 34.1381 13.5 34Z" stroke="#B6B6B6"/>
<rect x="20" y="11.25" width="17" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="20" y="15.25" width="12" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="9" y="10" width="8" height="8" rx="2" fill="#E3E3E3"/>
<rect x="20" y="21.25" width="17" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="20" y="25.25" width="12" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="9" y="20" width="8" height="8" rx="2" fill="#E3E3E3"/>
<rect x="20" y="31.25" width="17" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="20" y="35.25" width="12" height="1.5" rx="0.75" fill="#B6B6B6"/>
<rect x="9" y="30" width="8" height="8" rx="2" fill="#E3E3E3"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 739 B

Before After
Before After

View file

@ -0,0 +1,3 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.5 8.5L10.5 12.5L6.5 8.5" stroke="#B6B6B6" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 182 B

View file

@ -1,3 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.44444 16C4.96914 16 4.83333 15.6374 5.07407 15.3496C5.30864 15.0619 5.92593 14.4288 6.27161 13.8993C6.32099 13.8129 6.29012 13.7266 6.19753 13.6806C4.21605 12.6906 3 11.0734 3 9.23165C3 6.33669 6.11111 4 10 4C13.8889 4 17 6.33669 17 9.23165C17 12.0978 14.0494 14.4576 9.59877 14.4576C9.51852 14.4576 9.43827 14.4518 9.35802 14.446C9.27161 14.446 9.18518 14.4748 9.08025 14.5439C8.03086 15.246 6.18519 16 5.44444 16Z" fill="#252525"/>
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.43066 17.6943C5.16634 17.6943 4.99772 17.6077 4.9248 17.4346C4.85645 17.266 4.88835 17.0951 5.02051 16.9219C5.1071 16.8079 5.23014 16.6553 5.38965 16.4639C5.55371 16.277 5.72233 16.0719 5.89551 15.8486C6.06868 15.6253 6.21908 15.4089 6.34668 15.1992C6.37402 15.1491 6.37858 15.1012 6.36035 15.0557C6.34668 15.0055 6.31478 14.9668 6.26465 14.9395C5.53548 14.5475 4.9043 14.0804 4.37109 13.5381C3.84245 12.9912 3.43457 12.3896 3.14746 11.7334C2.86491 11.0771 2.72363 10.3844 2.72363 9.65527C2.72363 8.79395 2.92188 7.9873 3.31836 7.23535C3.7194 6.4834 4.27311 5.82487 4.97949 5.25977C5.69043 4.6901 6.5153 4.24577 7.4541 3.92676C8.3929 3.60319 9.40006 3.44141 10.4756 3.44141C11.5511 3.44141 12.5583 3.60319 13.4971 3.92676C14.4359 4.24577 15.2585 4.6901 15.9648 5.25977C16.6758 5.82487 17.2295 6.4834 17.626 7.23535C18.027 7.9873 18.2275 8.79395 18.2275 9.65527C18.2275 10.3343 18.1022 10.9837 17.8516 11.6035C17.6009 12.2233 17.2386 12.793 16.7646 13.3125C16.2907 13.8275 15.7165 14.2764 15.042 14.6592C14.3721 15.042 13.6156 15.3382 12.7725 15.5479C11.9294 15.7575 11.0156 15.8623 10.0312 15.8623C9.99023 15.8623 9.94694 15.86 9.90137 15.8555C9.85579 15.8555 9.81022 15.8532 9.76465 15.8486C9.71908 15.8486 9.67122 15.8577 9.62109 15.876C9.57096 15.8942 9.51628 15.9238 9.45703 15.9648C9.16536 16.1745 8.8304 16.3796 8.45215 16.5801C8.07845 16.7852 7.69792 16.972 7.31055 17.1406C6.92773 17.3092 6.56999 17.4437 6.2373 17.5439C5.90462 17.6442 5.63574 17.6943 5.43066 17.6943Z" fill="#252525"/>
</svg>

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Before After
Before After

View file

@ -1,11 +1,12 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="11.25" width="17" height="1.5" rx="0.75" fill="#737373"/>
<rect x="20" y="15.25" width="12" height="1.5" rx="0.75" fill="#737373"/>
<rect x="9" y="10" width="8" height="8" rx="2" fill="#313131"/>
<rect x="20" y="21.25" width="17" height="1.5" rx="0.75" fill="#737373"/>
<rect x="20" y="25.25" width="12" height="1.5" rx="0.75" fill="#737373"/>
<rect x="9" y="20" width="8" height="8" rx="2" fill="#313131"/>
<rect x="20" y="31.25" width="17" height="1.5" rx="0.75" fill="#737373"/>
<rect x="20" y="35.25" width="12" height="1.5" rx="0.75" fill="#737373"/>
<rect x="9" y="30" width="8" height="8" rx="2" fill="#313131"/>
<rect x="13.375" y="13.625" width="23.25" height="0.75" rx="0.375" stroke="#737373" stroke-width="0.75"/>
<path d="M9.5 14C9.5 13.7239 9.72386 13.5 10 13.5C10.2761 13.5 10.5 13.7239 10.5 14C10.5 14.2761 10.2761 14.5 10 14.5C9.72386 14.5 9.5 14.2761 9.5 14Z" stroke="#737373"/>
<path d="M9.5 19C9.5 18.7239 9.72386 18.5 10 18.5C10.2761 18.5 10.5 18.7239 10.5 19C10.5 19.2761 10.2761 19.5 10 19.5C9.72386 19.5 9.5 19.2761 9.5 19Z" stroke="#737373"/>
<path d="M13.5 19C13.5 18.8619 13.6119 18.75 13.75 18.75H30.25C30.3881 18.75 30.5 18.8619 30.5 19C30.5 19.1381 30.3881 19.25 30.25 19.25H13.75C13.6119 19.25 13.5 19.1381 13.5 19Z" stroke="#737373"/>
<rect x="13.375" y="23.625" width="23.25" height="0.75" rx="0.375" stroke="#737373" stroke-width="0.75"/>
<path d="M9.5 24C9.5 23.7239 9.72386 23.5 10 23.5C10.2761 23.5 10.5 23.7239 10.5 24C10.5 24.2761 10.2761 24.5 10 24.5C9.72386 24.5 9.5 24.2761 9.5 24Z" stroke="#737373"/>
<path d="M9.5 29C9.5 28.7239 9.72386 28.5 10 28.5C10.2761 28.5 10.5 28.7239 10.5 29C10.5 29.2761 10.2761 29.5 10 29.5C9.72386 29.5 9.5 29.2761 9.5 29Z" stroke="#737373"/>
<path d="M13.5 29C13.5 28.8619 13.6119 28.75 13.75 28.75H30.25C30.3881 28.75 30.5 28.8619 30.5 29C30.5 29.1381 30.3881 29.25 30.25 29.25H13.75C13.6119 29.25 13.5 29.1381 13.5 29Z" stroke="#737373"/>
<path d="M9.5 34C9.5 33.7239 9.72386 33.5 10 33.5C10.2761 33.5 10.5 33.7239 10.5 34C10.5 34.2761 10.2761 34.5 10 34.5C9.72386 34.5 9.5 34.2761 9.5 34Z" stroke="#737373"/>
<path d="M13.5 34C13.5 33.8619 13.6119 33.75 13.75 33.75H36.25C36.3881 33.75 36.5 33.8619 36.5 34C36.5 34.1381 36.3881 34.25 36.25 34.25H13.75C13.6119 34.25 13.5 34.1381 13.5 34Z" stroke="#737373"/>
</svg>

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Before After
Before After

View file

@ -1,12 +1,11 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="13.375" y="13.625" width="23.25" height="0.75" rx="0.375" stroke="#737373" stroke-width="0.75"/>
<path d="M9.5 14C9.5 13.7239 9.72386 13.5 10 13.5C10.2761 13.5 10.5 13.7239 10.5 14C10.5 14.2761 10.2761 14.5 10 14.5C9.72386 14.5 9.5 14.2761 9.5 14Z" stroke="#737373"/>
<path d="M9.5 19C9.5 18.7239 9.72386 18.5 10 18.5C10.2761 18.5 10.5 18.7239 10.5 19C10.5 19.2761 10.2761 19.5 10 19.5C9.72386 19.5 9.5 19.2761 9.5 19Z" stroke="#737373"/>
<path d="M13.5 19C13.5 18.8619 13.6119 18.75 13.75 18.75H30.25C30.3881 18.75 30.5 18.8619 30.5 19C30.5 19.1381 30.3881 19.25 30.25 19.25H13.75C13.6119 19.25 13.5 19.1381 13.5 19Z" stroke="#737373"/>
<rect x="13.375" y="23.625" width="23.25" height="0.75" rx="0.375" stroke="#737373" stroke-width="0.75"/>
<path d="M9.5 24C9.5 23.7239 9.72386 23.5 10 23.5C10.2761 23.5 10.5 23.7239 10.5 24C10.5 24.2761 10.2761 24.5 10 24.5C9.72386 24.5 9.5 24.2761 9.5 24Z" stroke="#737373"/>
<path d="M9.5 29C9.5 28.7239 9.72386 28.5 10 28.5C10.2761 28.5 10.5 28.7239 10.5 29C10.5 29.2761 10.2761 29.5 10 29.5C9.72386 29.5 9.5 29.2761 9.5 29Z" stroke="#737373"/>
<path d="M13.5 29C13.5 28.8619 13.6119 28.75 13.75 28.75H30.25C30.3881 28.75 30.5 28.8619 30.5 29C30.5 29.1381 30.3881 29.25 30.25 29.25H13.75C13.6119 29.25 13.5 29.1381 13.5 29Z" stroke="#737373"/>
<path d="M9.5 34C9.5 33.7239 9.72386 33.5 10 33.5C10.2761 33.5 10.5 33.7239 10.5 34C10.5 34.2761 10.2761 34.5 10 34.5C9.72386 34.5 9.5 34.2761 9.5 34Z" stroke="#737373"/>
<path d="M13.5 34C13.5 33.8619 13.6119 33.75 13.75 33.75H36.25C36.3881 33.75 36.5 33.8619 36.5 34C36.5 34.1381 36.3881 34.25 36.25 34.25H13.75C13.6119 34.25 13.5 34.1381 13.5 34Z" stroke="#737373"/>
<rect x="20" y="11.25" width="17" height="1.5" rx="0.75" fill="#737373"/>
<rect x="20" y="15.25" width="12" height="1.5" rx="0.75" fill="#737373"/>
<rect x="9" y="10" width="8" height="8" rx="2" fill="#313131"/>
<rect x="20" y="21.25" width="17" height="1.5" rx="0.75" fill="#737373"/>
<rect x="20" y="25.25" width="12" height="1.5" rx="0.75" fill="#737373"/>
<rect x="9" y="20" width="8" height="8" rx="2" fill="#313131"/>
<rect x="20" y="31.25" width="17" height="1.5" rx="0.75" fill="#737373"/>
<rect x="20" y="35.25" width="12" height="1.5" rx="0.75" fill="#737373"/>
<rect x="9" y="30" width="8" height="8" rx="2" fill="#313131"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 739 B

Before After
Before After

View file

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 18C16.2091 18 18 16.2091 18 14V6C18 3.79086 16.2091 2 14 2H6C3.79086 2 2 3.79086 2 6L2 14C2 16.2091 3.79086 18 6 18H14ZM9.5 14C9.5 14.2761 9.72386 14.5 10 14.5C10.2761 14.5 10.5 14.2761 10.5 14L10.5 7.11342L12.6678 9.04037C12.8742 9.22383 13.1902 9.20524 13.3737 8.99885C13.5572 8.79246 13.5386 8.47642 13.3322 8.29296L10.3322 5.6263L10 5.33102L9.66782 5.6263L6.66782 8.29296C6.46143 8.47642 6.44284 8.79246 6.6263 8.99885C6.80975 9.20524 7.12579 9.22383 7.33218 9.04037L9.5 7.11342L9.5 14Z" fill="#f8f8f8"/>
</svg>

After

Width:  |  Height:  |  Size: 665 B

View file

@ -12,7 +12,7 @@ export default {
textColor: [ 'grey', 'yellow', 'orange', 'red', 'pink', 'purple', 'blue', 'ice', 'teal', 'lime' ],
namespace: { 0: '.any' },
allowedSchemes: [ 'https?', 'mailto', 'tel' ],
allowedSchemes: [ 'http', 'https', 'mailto', 'tel' ],
count: {
icon: 10,

View file

@ -2,6 +2,7 @@ export default {
Code: {
ANYTYPE_NEEDS_UPGRADE: 10,
NO_ACCOUNTS_FOUND: 101,
SPACE_IS_DELETED: 103,
FAILED_TO_FIND_ACCOUNT_INFO: 104,
ANOTHER_ANYTYPE_PROCESS_IS_RUNNING: 108,
ACCOUNT_IS_DELETED: 109,

View file

@ -54,7 +54,8 @@ export default {
'select',
'searchObject',
'dataviewObjectValues',
'dataviewObjectList'
'dataviewObjectList',
'blockAlign',
],
layout: [ 'blockAlign' ],
latex: [ 'previewLatex' ],
@ -65,5 +66,6 @@ export default {
widget: [ 'searchObject', 'select' ],
dataviewTemplate: [ 'previewObject' ],
table: [ 'select2', 'blockColor', 'blockBackground' ],
dataviewContext: [ 'typeSuggest', 'searchObject' ]
};
dataviewContext: [ 'typeSuggest', 'searchObject' ],
dataviewNew: [ 'searchObject', 'typeSuggest', 'dataviewTemplateList' ]
};

View file

@ -123,6 +123,7 @@
"commonRedo": "Redo",
"commonBlank": "Blank",
"commonSetDefault": "Set as default",
"commonTemplate": "Template",
"commonTemplates": "Templates",
"commonSkip": "Skip",
"commonCreateNew": "Create new",
@ -177,6 +178,12 @@
"commonNotFound": "Not found",
"commonCalculate": "Calculate",
"commonRelations": "Relations",
"commonSelectType": "Select Type",
"commonPin": "Pin on top",
"commonUnpin": "Unpin",
"commonOpenType": "Open Type",
"commonManage": "Manage",
"commonSize": "Size",
"pluralDay": "day|days",
"pluralObject": "Object|Objects",
@ -776,7 +783,6 @@
"popupSettingsSpacesListSpace": "Space",
"popupSettingsSpacesCancelRequest": "Cancel request",
"popupSettingsSpacesListAccess": "Access",
"popupSettingsSpacesListSize": "Size",
"popupSettingsSpacesListNetwork": "Network",
"popupSettingsSpacesListDevice": "Device",
@ -792,6 +798,9 @@
"popupSettingsDataManagementDeleteText": "Once you request your vault to be deleted, you have 30 days to cancel this request. After 30 days, your encrypted vault data is permanently removed from the backup node, you won't be able to sign into Anytype on new devices.",
"popupSettingsDataManagementDeleteButton": "Delete vault",
"popupSettingsDataManagementDataPublishTitle": "My Sites",
"popupSettingsDataManagementDataPublishDate": "Published date",
"popupSettingsSpaceIndexTitle": "Space Settings",
"popupSettingsSpaceIndexDescriptionPlaceholder": "Add a few words about the space...",
"popupSettingsSpaceIndexSpaceTypePersonalTooltipTitle": "End-to-end encryption (E2EE)",
@ -897,7 +906,6 @@
"popupSettingsMembershipPerGenericMany": "per %s %s",
"popupSettingsMembershipLearnMore": "Learn more",
"popupSettingsMembershipCurrent": "Current",
"popupSettingsMembershipManage": "Manage",
"popupSettingsMembershipValidUntil": "Valid until %s",
"popupSettingsMembershipForeverFree": "Forever free",
"popupSettingsMembershipPending": "Pending...",
@ -1065,6 +1073,7 @@
"popupConfirmDuplicateSpace": "You are already a member of this space",
"popupConfirmInviteError": "The link you have tried to use does not seem to work",
"popupConfirmSpaceDeleted": "The space you try to access has been deleted",
"popupConfirmWelcomeTitle": "Welcome to your Space",
"popupConfirmWelcomeText": "Your <b>Space</b> is an encrypted, local-first container.<br/><b>Spaces</b> can be shared and co-created with others.<br/>Each space contains a <b>Graph of objects</b>.",
@ -1090,7 +1099,7 @@
"popupConfirmActionReconcileText": "This operation will clean up the incorrectly occupied space in the remote file storage. Are you sure?",
"popupConfirmOpenExternalLinkTitle": "Are you sure?",
"popupConfirmOpenExternalLinkText": "You are trying to open url that is potentially harmful. Are you sure you want to proceed?",
"popupConfirmOpenExternalLinkText": "You are trying to open url that is potentially harmful. Are you sure you want to proceed?<br/>Url: %s",
"popupConfirmChatDeleteMessageTitle": "Delete this message?",
"popupConfirmChatDeleteMessageText": "It cannot be restored after confirmation",
@ -1513,6 +1522,8 @@
"menuDataviewTemplateSetDefaultForView": "Default for this view",
"menuDataviewTemplateEdit": "Edit template",
"menuDataviewExistingObject": "Existing object",
"menuGraphSettingsTitles": "Titles",
"menuGraphSettingsArrows": "Arrows",
"menuGraphSettingsIcons": "Icons",
@ -1575,15 +1586,6 @@
"menuPreviewLatexExample": "Example: %s",
"menuSelectEmpty": "No options found",
"menuQuickCaptureSearchObjectTypes": "Search object types...",
"menuQuickCaptureGroups": "Lists",
"menuQuickCapturePinned": "Pinned",
"menuQuickCaptureTooltipSearch": "Search types",
"menuQuickCaptureTooltipClipboard": "Create object from clipboard",
"menuQuickCaptureOpenType": "Open type",
"menuQuickCapturePin": "Pin on top",
"menuQuickCaptureUnpin": "Unpin",
"syncButtonNameError1": "Storage limit reached",
"syncButtonNameError2": "Incompatible version",
"syncButtonNameError3": "No access",
@ -1624,8 +1626,15 @@
"menuSyncStatusEmpty": "There are no objects to show",
"menuPublishTitle": "Publish to web",
"menuPublishLabel": "Join Space Button",
"menuPublishButton": "Publish",
"menuPublishInfoTooltip": "Published object will be uploaded to our publishing server and will be accessible via the URL as a static, unencrypted HTML page. Linked objects will not be published.<br/>Currently, not all blocks are supported for publishing, such as sets, collections, and relations.",
"menuPublishLabelJoin": "Join Space Button",
"menuPublishButtonPublish": "Publish",
"menuPublishButtonUnpublish": "Unpublish",
"menuPublishButtonUpdate": "Update",
"menuPublishButtonView": "View in Browser",
"menuPublishButtonOpen": "Open Object",
"menuPublishButtonCopy": "Copy Web Link",
"menuPublishLabelOffline": "No internet connection",
"previewEdit": "Edit Link",
@ -1791,6 +1800,7 @@
"widgetEmptyLabel": "There are no Objects here",
"widgetEmptyLabelCreate": "There are no Objects here,<br/>create the first one",
"widgetShowAll": "See all Objects",
"widgetItemClipboard": "Create from clipboard",
"phrasePlaceholder": "Please enter your Key",
@ -2135,6 +2145,8 @@
"errorSpaceMakeShareable103": "Oops! The request failed. Please check your Internet connection and try again.",
"errorSpaceMakeShareable104": "Limit reached for this space. Please upgrade your membership or contact support for assistance.",
"errorPublishingCreate103": "Looks like some files are over 100 MB. Please remove or slim them down and try again.",
"errorIncorrectEmail": "Incorrect E-mail",
"origin0": "Empty",
@ -2146,6 +2158,7 @@
"origin6": "Use case",
"origin7": "Library installed",
"origin8": "Bookmark",
"origin9": "API",
"emojiCategoryPeople": "Smileys & People",
"emojiCategoryNature": "Animals & Nature",
@ -2227,7 +2240,8 @@
"spaceStatus9": "Joining",
"spaceStatus10": "Removing",
"challengeTitle": "Please enter the following numbers in the extension",
"challengeTitle": "Grant Limited Access",
"challengeDescription": "This extension requires a 4-digit code for limited access to your account. Proceed only if you trust the extension.",
"webclipperEmptySelection": "Selection is empty",
"paymentMethod0": "None",

View file

@ -23,7 +23,9 @@ export default {
invite: 'https://invite.any.coop/%s#%s',
share: 'https://join.anytype.io/',
notionFAQ: 'https://doc.anytype.io/anytype-docs/basics/space/import-export#notion-import-faq',
publish: '%s.coop',
publishDomain: '%s.org',
publish: 'https://any.coop/%s/',
api: '127.0.0.1:31009',
survey: {
register: 'https://community.anytype.io/survey0',
@ -33,4 +35,4 @@ export default {
shared: 'https://community.anytype.io/survey4',
multiplayer: 'https://community.anytype.io/survey5'
}
};
};

View file

@ -16,7 +16,13 @@
display: flex; border: 1px solid var(--color-shape-secondary); transition: border-color $transitionCommon;
position: relative; border-radius: 8px; overflow: hidden; box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05);
}
.inner::after {
content: ''; position: absolute; left: 0px; top: 0px; border-radius: inherit; width: 100%; height: 100%;
background: rgba(0,0,0,0.03); transition: $transitionAllCommon; pointer-events: none; opacity: 0; z-index: 1;
}
.inner:hover { border-color: var(--color-shape-primary); }
.inner:hover::after { opacity: 1; }
.inner.bgColor { border: 0px; }
.inner {

View file

@ -38,6 +38,7 @@
.editableWrap {
.editable, .placeholder { padding: 16px; }
}
.editableWrap.isRtl { text-align: right; }
.attachments { padding: 0px 8px; max-height: 360px; overflow-x: hidden; overflow-y: auto; max-width: unset; }
.attachments {

View file

@ -39,7 +39,7 @@
.cellContent { cursor: default; }
.cellContent {
.iconObject { margin-right: 8px; vertical-align: top; flex-shrink: 0; cursor: default; }
.iconObject { flex-shrink: 0; cursor: default; }
.icon.clear { display: none; }
.name { display: inline-block; vertical-align: top; user-select: text !important; }

View file

@ -101,6 +101,12 @@
.input.name { text-indent: 0px; padding: 0px; height: unset; }
}
}
.card::after {
content: ''; position: absolute; left: 0px; top: 0px; border-radius: inherit; width: 100%; height: 100%;
background: rgba(0,0,0,0.03); transition: $transitionAllCommon; pointer-events: none; opacity: 0; z-index: 1;
}
.card:hover::after { opacity: 1; }
.card.withCover {
.cardContent > .inner { padding-top: 12px; }

View file

@ -27,7 +27,7 @@
.selectionTarget { height: 100%; }
.selectionTarget.isSelectionSelected::after { border-radius: 8px; }
}
.card:hover { border-color: var(--color-shape-secondary); background: var(--color-shape-highlight-light); }
.card:hover { border-color: var(--color-shape-secondary); }
.card:hover {
.icon.checkbox { opacity: 1; }
}

View file

@ -26,6 +26,9 @@
}
.cellHead, .cellFoot {
&.align1 { text-align: center; }
&.align2 { text-align: right; }
.cellContent { height: 36px !important; overflow: visible !important; }
.flex { padding: 9px 14px; gap: 0px 6px; align-items: center; height: 100%; }
.iconObject { width: 20px; height: 20px; margin: 0px; vertical-align: top; flex-shrink: 0; display: none; }
@ -39,6 +42,10 @@
.resize { width: 20px; height: calc(100% - 2px); position: absolute; right: 0px; top: 1px; cursor: col-resize; z-index: 10; }
}
.cellHead {
.name { user-select: none !important; }
}
.cellHead.small { text-align: center; }
.cellHead.small {
.flex { display: inline-block; }
@ -110,6 +117,7 @@
}
.cell.isName, .cellContent.isName { cursor: default; }
.cellContent.isName { display: flex; flex-direction: row; align-items: center; gap: 0px 6px; }
.cell.isName.canEdit:hover {
.name { width: calc(100% - 40px) !important; }
@ -123,13 +131,31 @@
}
};
.cell.c-object, .cell.c-file { padding-right: 0px; }
.cell.c-object, .cell.c-file {
:not(.align1, .align2) { padding-right: 0px; }
&.align2 { padding-left: 0px; }
}
.cellContent.c-object, .cellContent.c-select, .cellContent.c-file {
.wrap { height: 100%; overflow: hidden; white-space: nowrap; }
}
.cell.c-checkbox {
&.align1 .cellContent { justify-content: center; }
&.align2 .cellContent { justify-content: flex-end; }
}
.cell { display: inline-block; height: 48px; padding: 14px; vertical-align: top; position: relative; word-break: break-word; }
.cell.cellKeyHover { background-color: var(--color-shape-highlight-light); }
.cell {
&.align1 { text-align: center; }
&.align1 {
.over { justify-content: center; }
}
&.align2 { text-align: right; }
&.align2 {
.over { justify-content: flex-end; }
}
}
.cell.isEditing {
.cellContent { height: 100% !important; min-width: 300px; padding: 14px; border-radius: 4px; }

View file

@ -138,6 +138,11 @@
.block.blockLink.card {
.linkCard { box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05); border-radius: 8px; }
.linkCard {
.side::after {
content: ''; position: absolute; left: 0px; top: 0px; border-radius: inherit; width: 100%; height: 100%;
background: rgba(0,0,0,0.03); transition: $transitionAllCommon; pointer-events: none; opacity: 0; z-index: 1;
}
.side.left { padding: 16px; border: 1px solid var(--color-shape-secondary); border-radius: 8px; flex-direction: column; justify-content: center; }
.side.right { border-radius: 0px 8px 8px 0px; }
@ -160,7 +165,8 @@
.block.blockLink.card:hover {
.linkCard {
.side.left, .side.right { border-color: var(--color-shape-primary); }
.side { border-color: var(--color-shape-primary); }
.side::after { opacity: 1; }
}
}

View file

@ -68,7 +68,6 @@
}
}
.block.blockMedia > .wrapContent { border-radius: 8px; box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05); }
.block.blockMedia.isAudio > .wrapContent { border: 1px solid var(--color-shape-secondary); }
.block.blockMedia.isAudio > .wrapContent > .selectionTarget > .dropTarget > .focusable > .wrap { width: 100%; padding: 12px 12px 7px 14px; }

View file

@ -60,6 +60,8 @@ input, textarea, select { font-family: 'Inter'; }
.onboardingDimmer { content: ''; position: fixed; left: 0px; top: 0px; width: 100%; height: 100%; background: rgba(0,0,0,0.4); -webkit-app-region: no-drag; z-index: 999; pointer-events: none; }
.ReactVirtualized__List { overscroll-behavior: none; }
html.platformWindows {
body { overflow-y: overlay; }
}
@ -106,7 +108,7 @@ html.platformWindows, html.platformLinux {
::-webkit-input-placeholder { color: var(--color-text-tertiary) !important; }
.isBlurred { filter: blur(7px); }
.animationWord { display: inline-block; }
.isRtl { direction: rtl; text-align: right; }
.isRtl { direction: rtl; }
.isOnboardingHidden { visibility: hidden; }
.fileWrap { position: relative; overflow: hidden; }

View file

@ -94,12 +94,13 @@
.icon { width: 20px; height: 20px; margin-top: -4px; }
.icon.help { background-image: url('~img/icon/help.svg'); }
.full, .c70, .half { margin: 16px 0px; border-radius: 8px; display: block; }
.c50, .c60, .c70, .half, .full, .screen { margin: 16px auto; border-radius: 8px; display: block; }
.full { width: 100%; }
.c70 { width: 70%; margin: 16px auto; }
.half { width: 50%; }
.screen { margin: 16px auto; display: block; box-shadow: 0px 0px 25px rgba(0,0,0,0.2); }
.full, .c100 { width: 100%; }
.half, .c50 { width: 50%; }
.c60 { width: 60%; }
.c70 { width: 70%; }
.screen { box-shadow: 0px 0px 25px rgba(0,0,0,0.2); }
img.mention { margin-left: -18px; }
}

View file

@ -5,7 +5,9 @@
background-position: center center; transition: $transitionAllCommon; position: relative;
}
.icon.withBackground { width: 28px !important; height: 28px !important; background-size: 20px !important; border-radius: 6px; }
.icon.withBackground:hover, .icon.withBackground.hover { background-color: var(--color-shape-highlight-medium) !important; };
.icon.withBackground {
&:hover, &.hover { background-color: var(--color-shape-highlight-medium) !important; }
};
.arrow { background-position: center center; transition: $transitionAllCommon; background-repeat: no-repeat; background-size: 100% 100%; }

View file

@ -1,6 +1,6 @@
@import "~scss/_mixins";
#tooltipContainer { position: fixed; left: 0px; top: 0px; z-index: 1000; pointer-events: none; }
#tooltipContainer { position: fixed; left: 0px; top: 0px; z-index: 1002; pointer-events: none; }
.tooltip {
position: absolute; border-radius: 4px; background: #373632; padding: 3px 7px; text-transform: none;

View file

@ -18,4 +18,12 @@ html.debug {
.blockLast { background: rgba(0,0,255,0.1); }
.isHidden { background-color: rgba(255,192,203,0.3) !important; }
.menus {
.menu.vertical {
.icon.delete, .icon.more {
&:not(.withBackground) { background: red; }
}
}
}
}

View file

@ -7,7 +7,10 @@
@include text-common; cursor: default; -webkit-app-region: no-drag;
}
.button > .loaderWrapper { position: absolute; z-index: 1; width: 100%; height: 100%; }
.button > .loaderWrapper {
position: absolute !important; ; z-index: 1; width: 100% !important; ; height: 100% !important; ; border-radius: inherit !important;
background: none !important;
}
.button.isLoading {
.txt, .icon { display: none; }
}

View file

@ -1,8 +1,9 @@
@import "~scss/_mixins";
.pin { display: flex; flex-direction:row; align-items: center; gap: 0px 8px; }
.pin {
.input {
width: 40px; height: 40px; margin-right: 8px; padding: 0px; text-align: center; vertical-align: top; font-size: var(--font-size-header3);
width: 40px; height: 40px; padding: 0px; text-align: center; vertical-align: top; font-size: var(--font-size-header3);
border: 1px solid var(--color-shape-primary); border-radius: 2px;
}
.input.isFocused { box-shadow: 0px 0px 0px 1px var(--color-system-accent-100) inset; border-color: var(--color-system-accent-100); }

View file

@ -16,7 +16,7 @@
}
.icon.sortArrow { width: 20px; height: 20px; margin: 0px; background-image: url('~img/icon/sortArrow.svg'); }
.icon.sortArrow.c1 { transform: rotateZ(180deg); }
.icon.sortArrow.c0 { transform: rotateZ(180deg); }
}
.row { border-bottom: 1px solid var(--color-shape-secondary); }

View file

@ -95,6 +95,7 @@
.icon.delete, .icon.more { opacity: 1; }
}
.item.withMore.hover, .item.withMore:hover {
.clickable { padding-right: 28px; }
.caption { opacity: 0; }
}
@ -111,8 +112,8 @@
.icon.dnd { width: 20px; height: 20px; background-image: url('~img/icon/dnd.svg'); margin: 0px; vertical-align: top; cursor: grab; }
.icon.plus { margin-right: 6px; background-image: url('~img/icon/plus/menu0.svg'); }
.icon.delete, .icon.more {
width: 24px; height: 24px; background-size: 20px; position: absolute; right: 10px; top: 50%;
margin: -12px 0px 0px 0px; border-radius: 4px; opacity: 0; z-index: 1;
width: 24px !important; height: 24px !important; background-size: 20px; position: absolute; right: 10px; top: 50%; margin: -12px 0px 0px 0px;
border-radius: 4px; opacity: 0; z-index: 1;
}
.icon.delete { background-image: url('~img/icon/menu/delete.svg'); }
.icon.delete:hover, .icon.more:hover { background-color: var(--color-shape-highlight-medium); }
@ -268,7 +269,6 @@ html.platformWindows {
@import "./smile";
@import "./type";
@import "./widget";
@import "./quickCapture";
@import "./syncStatus";
@import "./graph";
@import "./participant";

View file

@ -21,6 +21,7 @@
.icon.mediaVideo { background-image: url('~img/icon/menu/action/block/media/video0.svg'); }
.icon.existing { background-image: url('~img/icon/menu/action/block/existing0.svg'); }
.icon.existingObject { background-image: url('~img/arrow/existing.svg'); }
.icon.linkTo { background-image: url('~img/icon/menu/action/block/linkto0.svg'); }
.icon.unlink { background-image: url('~img/icon/menu/action/block/unlink0.svg'); }
.icon.bookmark { background-image: url('~img/icon/menu/action/block/bookmark0.svg'); }
@ -89,6 +90,7 @@
.icon.editRelation { background-image: url('~img/icon/header/relation.svg'); }
.icon.time { background-image: url('~img/icon/menu/action/time0.svg'); }
.icon.collection { background-image: url('~img/icon/menu/action/collection0.svg'); }
.icon.import { background-image: url('~img/icon/menu/action/import0.svg'); }
.icon.coverChange { background-image: url('~img/icon/cover/change.svg'); }
.icon.coverPosition { background-image: url('~img/icon/cover/position.svg'); }

View file

@ -4,19 +4,31 @@
.menu.menuPublish { width: var(--menu-width-large); }
.menu.menuPublish {
.content { padding: 16px; display: flex; flex-direction: column; gap: 8px 0px; overflow: visible; max-height: unset; }
.title { padding: 0px; @include text-paragraph; font-weight: 600; margin: 0px 0px 8px 0px; color: var(--color-text-primary); }
.menuHeader { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.title { padding: 0px; @include text-paragraph; font-weight: 600; margin: 0px; color: var(--color-text-primary); }
.icon.info { width: 20px; height: 20px; background: url('~img/icon/info.svg'); }
.input { padding: 7px 9px; height: auto; border-radius: 7px; border: 1px solid var(--color-shape-secondary); }
.input.isReadonly { background: rgba(0, 0, 0, 0.03); }
.input.isFocused { box-shadow: 0px 0px 0px 1px var(--color-system-accent-50); border-color: var(--color-system-accent-50); }
.label.small { @include text-small; @include text-overflow-nw; color: var(--color-text-secondary); }
.label.small { @include text-small; color: var(--color-text-secondary); @include text-overflow-nw; }
.flex { padding: 3px 0px; align-items: center; gap: 0px 16px; justify-content: space-between; }
.flex {
.value { display: flex; flex-direction: row; align-items: center; justify-content: flex-end; flex-shrink: 0; }
}
.buttons { display: flex; flex-direction: row; align-items: center; gap: 0px 8px; justify-content: space-evenly; height: 36px; }
.buttons {
.button { flex-grow: 1; width: 100%; }
.loaderWrapper { position: relative; height: 36px; }
.label { color: var(--color-text-secondary); }
}
.error { margin: 0px; }
.outer {
position: absolute; left: 0px; bottom: 0px; transform: translateY(calc(100% + 8px)); width: 100%; box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.2);
border-radius: 8px; overflow: hidden; background: var(--color-bg-primary);
@ -40,4 +52,4 @@
.name { flex-grow: 1; }
}
}
}
}

View file

@ -1,56 +0,0 @@
@import "~scss/_mixins";
.menus {
.menu.menuQuickCapture { box-shadow: none; background: none; position: fixed; }
.menu.menuQuickCapture {
.wrap { display: flex; flex-direction: column; width: 100%; }
.wrap.isDragging {
.item.hover:before { display: none; }
}
.filter { @include text-paragraph; padding: 0px 16px; }
.filter {
.icon.search { margin-right: 3px; }
.inner { height: 54px; }
.line { margin: 0px -16px !important; }
}
.section { height: auto; padding: 0px; border: 0px; }
.section > .name { @include text-small; color: var(--color-text-secondary); padding: 4px 0px; margin: 0px 0px 4px 0px; width: 100%; flex-shrink: 0; }
.items { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.item {
position: relative; display: flex; flex-wrap: nowrap; height: 48px; align-items: center; gap: 0px 8px; padding: 0px 14px;
background: var(--color-bg-primary); border: 1px solid var(--color-shape-highlight-medium); border-radius: 10px; overflow: hidden;
box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.07); transition: $transitionAllCommon; max-width: 200px; font-weight: 500;
}
.item.isDragging { z-index: 1; width: auto; }
.item {
.icon { margin-right: 0; flex-shrink: 0; }
.iconObject { flex-shrink: 0; }
.name { @include text-overflow-nw; width: 100%; }
}
.item.withIcon {
.name { width: calc(100% - 20px); }
}
.item.hover:before {
content: ''; position: absolute; z-index: 0; width: 100%; height: 100%; left: 0px; top: 0px; background: var(--color-shape-highlight-light);
}
.item.clipboard { opacity: 0.5; }
.item.clipboard.active { opacity: 1; }
}
.menu.menuQuickCapture.isExpanded {
width: 600px; box-shadow: 0px 6px 24px 0px rgba(0, 0, 0, 0.20); background: var(--color-bg-primary); padding: 0px; border-radius: 12px;
}
.menu.menuQuickCapture.isExpanded {
.wrap { height: 312px; }
.sections { overflow-x: hidden; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px 0px; }
.items { gap: 8px; justify-content: flex-start; }
.item { box-shadow: none; }
.item.isDefault { border-color: var(--color-system-accent-100); box-shadow: 0px 0px 0px 1px var(--color-system-accent-100) inset !important; }
}
}

View file

@ -12,5 +12,10 @@
.name { @include text-overflow-nw; width: calc(100% - 26px); }
}
.label { color: var(--color-control-active); @include text-common; padding: 0px 16px; }
.bottom { padding: 8px 0px; position: relative; }
.bottom::before {
content: ''; position: absolute; top: 0px; left: 14px; height: 1px; width: calc(100% - 28px); background: var(--color-shape-secondary);
}
}
}

View file

@ -1,7 +1,7 @@
@import "~scss/_mixins";
.menus {
.menu.menuWidget { width: unset; }
.menu.menuWidget { width: unset; min-width: var(--menu-width-common); }
.menu.menuWidget {
.section::after { display: none; }
.section:last-child::before { content: ''; display: block; height: 1px; margin: 0px 14px 8px; background-color: var(--color-shape-secondary); }
@ -13,7 +13,7 @@
.options { display: flex; gap: 0px 8px; padding: 0px 14px; margin-bottom: 4px; }
.options {
.option { display: flex; align-items: center; justify-content: center; width: 48px; height: 32px; border-radius: 8px; border: 1px solid var(--color-shape-tertiary); }
.option.withIcon { height: 48px; }
.option.icon { height: 48px; }
.option {
.icon { width: 48px; height: 48px; flex-shrink: 0; }
.icon.widget-0 { background-image: url('~img/icon/menu/widget/link.svg'); }

View file

@ -1,9 +1,8 @@
@import "~scss/_mixins";
.pageMainArchive {
.wrapper { width: calc(100% - 96px); margin: 0px auto; padding: 150px 0px 0px 0px; user-select: none; }
.wrapper { width: calc(100% - 96px); margin: 0px auto; padding: 52px 0px 0px 0px; user-select: none; }
.wrapper {
.body { height: 100%; display: flex; flex-direction: column; }
.titleWrapper { display: flex; flex-direction: row; align-items: center; gap: 0px 10px; margin: 0px 0px 46px 0px; }

View file

@ -24,6 +24,7 @@
}
.emptySearch { height: 238px; }
.button { flex-shrink: 0; width: 100%; }
.buttons { display: flex; flex-direction: row-reverse; gap: 0px 8px; justify-content: space-evenly; }
.button { width: 100%; }
}
}

View file

@ -233,6 +233,9 @@
.sectionContent {
> .item { padding: 16px; border-bottom: 1px solid var(--color-shape-secondary); }
> .item:last-child { border-bottom: 0; }
> .item.red {
.title { color: var(--color-red); }
}
> .item {
.sides { display: flex; justify-content: space-between; gap: 0px 16px; }
@ -347,7 +350,7 @@
.qrWrap { width: 130px; overflow: hidden; }
}
> .side.right.tabDataManagement {
> .side.right.tabDataIndex {
.description {
.label { display: inline; }
.label.extend { color: var(--color-red); }
@ -380,7 +383,8 @@
}
}
> .side.right.tabSpaceList {
> .side.right.tabSpaceList,
> .side.right.tabDataPublish {
.title { margin-bottom: 32px !important; }
.items {
@ -388,29 +392,35 @@
.row.isHead {
@include text-small; color: var(--color-text-secondary); font-weight: 400; border-color: var(--color-shape-secondary); border-style: solid;
border-top-width: 1px; border-bottom-width: 1px;
padding: 9px 0px;
}
.row.isHead {
.col { height: 36px; line-height: 36px; }
.col { height: 18px; line-height: 18px; }
}
.row { border-bottom: 1px solid var(--color-shape-secondary); padding: 12px 8px 12px 0px; }
.row { border-bottom: 1px solid var(--color-shape-secondary); padding: 11px 0px; }
.col.colSpace { display: flex; flex-wrap: nowrap; align-items: center; gap: 0px 12px; }
.col.colSpace {
.col.colObject { display: flex; flex-wrap: nowrap; align-items: center; gap: 0px 12px; }
.col.colObject {
.iconObject { flex-shrink: 0; }
.info { width: calc(100% - 52px); }
.info {
.name { @include text-overflow-nw; }
}
.name { @include text-overflow-nw; }
.creator { display: flex; flex-wrap: nowrap; align-items: center; gap: 0px 6px; @include text-small; color: var(--color-text-secondary); }
}
.col.colDate { @include text-overflow-nw; }
.icon.more { background-image: url('~img/icon/menu/action/more0.svg'); }
.icon.active { background-color: var(--color-shape-highlight-medium); }
}
}
> .side.right.tabDataPublish {
.items {
.col.colObject { gap: 0px 8px; }
}
}
> .side.right.tabSpaceStorageManager { padding: 0px !important; }
> .side.right.tabSpaceStorageManager {
> .wrap { height: 100%; display: flex; flex-direction: column; }

View file

@ -37,6 +37,14 @@
.loaderWrapper { border: 0px; }
}
/* BlockLink */
/*
.block.blockLink.card {
.side::after { background: rgba(255,255,255,0.03); }
}
*/
/* BlockDataview */
.block.blockDataview {
@ -101,9 +109,12 @@
.cell.cellKeyHover { background-color: rgba(223, 221, 208, 0.04); }
}
.viewContent.viewGallery {
.card:hover { background: rgba(166, 166, 166, 0.04); }
/*
.viewContent.viewGallery,
.viewContent.viewBoard {
.card::after { background: rgba(255,255,255,0.03); }
}
*/
.viewContent.viewBoard {
.cardContent { background: var(--color-bg-secondary); }
@ -178,6 +189,7 @@
.block.blockBookmark {
.loaderWrapper { border: 0px; }
.inner::after { background: rgba(255,255,255,0.03); }
}
/* BlockTable */

View file

@ -307,7 +307,7 @@ html.themeDark {
/* Sidebar */
.sidebar { background-color: var(--color-bg-secondary); box-shadow: 0px 4px 16px rgba(0,0,0,0.2); }
.sidebar { box-shadow: 0px 4px 16px rgba(0,0,0,0.2); }
.sidebar.fixed { box-shadow: 0px 0px rgba(0,0,0,0); }
.sidebar {
.icon.back { background-image: url('#{$themePath}/icon/widget/back.svg'); }

View file

@ -274,11 +274,6 @@
}
}
/* QuickCapture */
.menu.menuQuickCapture { background: none; box-shadow: none; }
.menu.menuQuickCapture.isExpanded { background: var(--color-bg-secondary); box-shadow: 0px 4px 16px rgb(0 0 0 / 20%), 0px 0px 0px 1px #393933 inset; }
/* SyncStatus */
.menu.menuSyncStatus {
@ -307,16 +302,27 @@
/* Widget */
.menu.menuWidget {
.options {
.option {
.icon.widget-0 { background-image: url('#{$themePath}/icon/menu/widget/link.svg'); }
.icon.widget-1 { background-image: url('#{$themePath}/icon/menu/widget/tree.svg'); }
.icon.widget-2 { background-image: url('#{$themePath}/icon/menu/widget/list.svg'); }
.icon.widget-3 { background-image: url('#{$themePath}/icon/menu/widget/compact.svg'); }
.icon.widget-4 { background-image: url('#{$themePath}/icon/menu/widget/view.svg'); }
}
}
}
.menu.menuWidget {
.options {
.option {
.icon.widget-0 { background-image: url('#{$themePath}/icon/menu/widget/link.svg'); }
.icon.widget-1 { background-image: url('#{$themePath}/icon/menu/widget/tree.svg'); }
.icon.widget-2 { background-image: url('#{$themePath}/icon/menu/widget/list.svg'); }
.icon.widget-3 { background-image: url('#{$themePath}/icon/menu/widget/compact.svg'); }
.icon.widget-4 { background-image: url('#{$themePath}/icon/menu/widget/view.svg'); }
}
}
}
/* Publish */
.menu.menuPublish {
.input.isReadonly { background: rgba(255, 255, 255, 0.03); }
.outer {
.icon.space { background-image: url('#{$themePath}/icon/widget/button/member.svg'); }
.icon.export { background-image: url('#{$themePath}/icon/widget/button/export.svg'); }
}
}
}

View file

@ -19,6 +19,18 @@
.side.right {
.cnt { background-color: var(--color-shape-secondary); color: var(--color-text-primary); }
}
.buttons {
.item {
.icon.member { background-image: url('#{$themePath}/icon/widget/button/member.svg'); }
.icon.all { background-image: url('#{$themePath}/icon/widget/button/all.svg'); }
.icon.chat { background-image: url('#{$themePath}/icon/widget/button/chat.svg'); }
.side.right {
.icon.more:hover, .icon.more.hover { background-image: url('#{$themePath}/icon/menu/action/more1.svg'); opacity: 1; }
}
}
}
}
}
@ -64,20 +76,6 @@
}
}
.widget.widgetButtons {
.body {
.item {
.icon.member { background-image: url('#{$themePath}/icon/widget/button/member.svg'); }
.icon.all { background-image: url('#{$themePath}/icon/widget/button/all.svg'); }
.icon.chat { background-image: url('#{$themePath}/icon/widget/button/chat.svg'); }
.side.right {
.icon.more:hover, .icon.more.hover { background-image: url('#{$themePath}/icon/menu/action/more1.svg'); opacity: 1; }
}
}
}
}
.button.widget {
.icon.bin { background-image: url('#{$themePath}/icon/widget/button/bin.svg'); }
}

View file

@ -18,28 +18,33 @@
.side.right { flex-shrink: 0; display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 0px 4px; }
.side.right {
.cnt {
@include text-very-small; background-color: var(--color-control-active); color: var(--color-control-bg); border-radius: 50%; min-width: 18px;
text-align: center; font-weight: 500; height: 18px; line-height: 18px; display: none; padding: 0px 2px; flex-shrink: 0;
}
.icon { width: 24px; height: 24px; flex-shrink: 0; }
.icon { width: 24px !important; height: 24px !important; flex-shrink: 0; }
.icon.search { background-image: url('~img/icon/widget/button/search.svg'); }
.icon.plus { background-image: url('~img/icon/widget/button/plus.svg'); }
.icon.arrow { background-image: url('~img/icon/widget/button/arrow.svg'); }
}
}
.buttons {
.item { padding: 4px 8px; display: flex; align-items: center; justify-content: space-between; position: relative; }
.item {
padding: 3px 8px; display: flex; align-items: center; justify-content: space-between; position: relative; background: var(--color-bg-primary);
border-radius: 6px;
}
.item::before {
content: ""; position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; background: var(--color-shape-highlight-medium); z-index: 1; pointer-events: none;
border-radius: 6px; opacity: 0;
border-radius: inherit; opacity: 0;
}
.item:hover::before, .item.hover::before { opacity: 1; }
.item {
.side { display: flex; flex-direction: row; align-items: center; }
.side.left { gap: 0px 6px; }
.side.right {
.cnt {
@include text-very-small; background-color: var(--color-control-active); color: var(--color-control-bg); border-radius: 50%; min-width: 18px;
text-align: center; font-weight: 500; height: 18px; line-height: 18px; display: none; padding: 0px 2px; flex-shrink: 0;
}
}
.name { display: flex; gap: 0px 8px; @include text-overflow-nw; }
@ -47,8 +52,6 @@
.icon.member { background-image: url('~img/icon/widget/button/member.svg'); }
.icon.all { background-image: url('~img/icon/widget/button/all.svg'); }
.icon.chat { background-image: url('~img/icon/widget/button/chat.svg'); }
.cnt { color: var(--color-text-secondary); }
}
.item:hover {
.side.right {
@ -59,7 +62,7 @@
}
.body.withCnt {
.sides {
.buttons {
.side.left { width: calc(100% - 30px); }
.side.right {
.cnt { display: block; }

View file

@ -21,7 +21,7 @@
}
}
.widget.widgetView.isPreview { padding: 0px; }
.widget.widgetView.isPreview { padding: 0px; height: 100%; }
.widget.widgetView.isPreview {
.head { margin: 0px; padding-bottom: 16px; }
.innerWrap { padding: 0px; }

View file

@ -139,7 +139,7 @@ class RoutePage extends React.Component<RouteComponentProps> {
<ListPopup key="listPopup" {...this.props} />
<ListMenu key="listMenu" {...this.props} />
<Sidebar key="sidebar" {...this.props} />
<Sidebar ref={ref => S.Common.refSet('sidebarLeft', ref)} key="sidebar" {...this.props} />
<Page {...this.props} isPopup={false} />
</DragProvider>
</SelectionProvider>

View file

@ -353,9 +353,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
this.editingId = '';
this.marks = [];
this.range = { from: 0, to: 0 };
this.refEditable.setValue('');
this.refEditable.placeholderCheck();
this.updateValue('');
});
};
@ -394,8 +392,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
let adjustMarks = false;
if (value !== parsed.text) {
this.refEditable.setValue(Mark.toHtml(parsed.text, this.marks));
this.refEditable.setRange(this.range);
this.updateValue(parsed.text);
};
if (canOpenMenuMention) {
@ -457,7 +454,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
const value = this.getTextValue();
const checkRtl = U.Common.checkRtl(value);
$(this.refEditable?.node).toggleClass('isRtl', checkRtl);
$(this.refEditable?.getNode()).toggleClass('isRtl', checkRtl);
};
onPaste (e: any) {
@ -483,10 +480,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
};
this.range = { from: to, to: to + text.length };
this.refEditable.setValue(Mark.toHtml(value, this.marks));
this.refEditable.setRange(this.range);
this.refEditable.placeholderCheck();
this.renderMarkup();
this.updateMarkup(value, this.range.from, this.range.to);
if (list.length) {
U.Common.saveClipboardFiles(list, {}, data => {
@ -495,7 +489,6 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
};
this.checkUrls();
this.onInput();
this.updateCounter();
};
@ -1037,14 +1030,18 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
updateMarkup (value: string, from: number, to: number) {
this.range = { from, to };
this.refEditable.setValue(Mark.toHtml(value, this.marks));
this.refEditable.setRange({ from, to });
this.refEditable.placeholderCheck();
this.updateValue(value);
this.renderMarkup();
this.checkSendButton();
};
updateValue (value: string) {
this.refEditable.setValue(Mark.toHtml(value, this.marks));
this.refEditable.setRange(this.range);
this.refEditable.placeholderCheck();
this.onInput();
};
renderMarkup () {
const { rootId, renderLinks, renderMentions, renderObjects, renderEmoji } = this.props;
const node = this.refEditable.getNode();
@ -1108,4 +1105,4 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
});
export default ChatForm;
export default ChatForm;

View file

@ -811,7 +811,7 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
let menuContext = null;
S.Menu.open('dataviewTemplateList', {
S.Menu.open('dataviewNew', {
...menuParam,
offsetY: 10,
noAnimation: true,
@ -829,15 +829,21 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
data: {
rootId,
blockId: block.id,
subId: this.getSubId(),
hasSources,
getView: this.getView,
withTypeSelect: this.isAllowedDefaultType(),
typeId,
templateId: this.getDefaultTemplateId(),
route,
isAllowedObject: this.isAllowedObject(),
isCollection,
onTypeChange: (id) => {
if (id != this.getTypeId()) {
Dataview.viewUpdate(rootId, block.id, view.id, { defaultTypeId: id, defaultTemplateId: J.Constant.templateId.blank });
const newType = S.Record.getTypeById(id);
const newTemplateId = newType?.defaultTemplateId || J.Constant.templateId.blank;
Dataview.viewUpdate(rootId, block.id, view.id, { defaultTypeId: id, defaultTemplateId: newTemplateId });
analytics.event('DefaultTypeChange', { route });
};
},
@ -1212,7 +1218,7 @@ const BlockDataview = observer(class BlockDataview extends React.Component<Props
return [];
};
const keys = S.Record.getObjectRelationKeys(rootId, block.id);
const keys = S.Record.getDataviewRelationKeys(rootId, block.id);
return view.getVisibleRelations().filter(it => keys.includes(it.relationKey));
};

View file

@ -388,12 +388,17 @@ const ViewGrid = observer(class ViewGrid extends React.Component<I.ViewComponent
onCellAdd (e: any) {
const { rootId, block, readonly, loadData, getView, isInline, isCollection } = this.props;
const blockEl = `#block-${block.id}`;
const cellLast = $(`${blockEl} .cellHead.last`);
const rowHead = $(`${blockEl} #rowHead`);
const isFixed = rowHead.hasClass('fixed');
const headEl = isFixed ? `#rowHeadClone` : `#rowHead`;
const element = `${blockEl} ${headEl} #cell-add`;
const cellLast = $(`${blockEl} ${headEl} .cellHead.last`);
S.Menu.open('dataviewRelationList', {
element: `${blockEl} #cell-add`,
element,
horizontal: I.MenuDirection.Center,
offsetY: 10,
className: isFixed ? 'fixed' : '',
onOpen: () => cellLast.addClass('hover'),
onClose: () => cellLast.removeClass('hover'),
data: {
@ -427,14 +432,17 @@ const ViewGrid = observer(class ViewGrid extends React.Component<I.ViewComponent
keyboard.disableSelection(false);
};
loadMoreRows ({ startIndex, stopIndex }) {
loadMoreRows () {
const { rootId, block, loadData, getView, getLimit } = this.props;
const subId = S.Record.getSubId(rootId, block.id);
let { offset } = S.Record.getMeta(subId, '');
const view = getView();
const limit = getLimit();
let { offset } = S.Record.getMeta(subId, '');
return new Promise((resolve, reject) => {
offset += getLimit();
offset += limit;
loadData(view.id, offset, false, resolve);
S.Record.metaSet(subId, '', { offset });
});

View file

@ -12,6 +12,7 @@ interface Props {
className?: string;
recordId?: string;
recordIdx?: number;
getView?(): I.View;
getRecord?(id: string): any;
getIdPrefix?(): string;
onRef?(ref: any, id: string): void;
@ -31,21 +32,31 @@ const BodyCell = observer(class BodyCell extends React.Component<Props> {
};
render () {
const { rootId, block, className, relationKey, readonly, recordId, getRecord, onRef, onCellClick, onCellChange, getIdPrefix, canCellEdit } = this.props;
const {
rootId, block, className, relationKey, readonly, recordId, getView, getRecord, onRef, onCellClick, onCellChange,
getIdPrefix, canCellEdit,
} = this.props;
const record = getRecord(recordId);
const relation: any = S.Record.getRelationByKey(relationKey) || {};
const cn = [ 'cell', `cell-key-${relationKey}`, Relation.className(relation.format), (!readonly ? 'canEdit' : '') ];
const view = getView();
const viewRelation = view?.getRelation(relationKey);
const cn = [ 'cell', `cell-key-${relationKey}`, Relation.className(relation.format), `align${viewRelation?.align}` ];
const idPrefix = getIdPrefix();
const id = Relation.cellId(idPrefix, relationKey, record.id);
const width = Relation.width(this.props.width, relation.format);
const size = J.Size.dataview.cell;
const subId = S.Record.getSubId(rootId, block.id);
const canEdit = canCellEdit(relation, record);
const isName = relationKey == 'name';
if (relationKey == 'name') {
if (isName) {
cn.push('isName');
};
if (!readonly) {
cn.push('canEdit');
};
if (width <= size.icon) {
cn.push('small');
};
@ -55,7 +66,7 @@ const BodyCell = observer(class BodyCell extends React.Component<Props> {
};
let iconEdit = null;
if ((relationKey == 'name') && !U.Object.isNoteLayout(record.layout) && canEdit) {
if (isName && !U.Object.isNoteLayout(record.layout) && canEdit) {
iconEdit = <Icon className="edit" onClick={this.onEdit} />;
};

View file

@ -65,14 +65,16 @@ const BodyRow = observer(class BodyRow extends React.Component<Props> {
if (isCollection && !isInline) {
content = (
<React.Fragment>
{!readonly ? <Icon
className="drag"
draggable={true}
onClick={e => onSelectToggle(e, record.id)}
onDragStart={e => onDragRecordStart(e, record.id)}
onMouseEnter={() => keyboard.setSelectionClearDisabled(true)}
onMouseLeave={() => keyboard.setSelectionClearDisabled(false)}
/> : ''}
{!readonly ? (
<Icon
className="drag"
draggable={true}
onClick={e => onSelectToggle(e, record.id)}
onDragStart={e => onDragRecordStart(e, record.id)}
onMouseEnter={() => keyboard.setSelectionClearDisabled(true)}
onMouseLeave={() => keyboard.setSelectionClearDisabled(false)}
/>
) : ''}
<DropTarget {...this.props} rootId={rootId} id={record.id} dropType={I.DropType.Record}>
{content}
</DropTarget>

View file

@ -1,7 +1,7 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import { SortableElement } from 'react-sortable-hoc';
import { I, S, keyboard, Relation, Dataview } from 'Lib';
import { I, S, J, keyboard, Relation, Dataview } from 'Lib';
import Handle from './handle';
interface Props extends I.ViewComponent, I.ViewRelation {
@ -22,15 +22,17 @@ const HeadCell = observer(class HeadCell extends React.Component<Props> {
};
render () {
const { rootId, block, relationKey, index, onResizeStart, readonly } = this.props;
const { rootId, block, relationKey, index, onResizeStart, getView, readonly } = this.props;
const relation = S.Record.getRelationByKey(relationKey);
if (!relation) {
return;
return null;
};
const view = getView();
const viewRelation = view?.getRelation(relationKey);
const allowed = !readonly && S.Block.checkFlags(rootId, block.id, [ I.RestrictionDataview.View ]);
const cn = [ 'cellHead', `cell-key-${relationKey}`, Relation.className(relation.format) ];
const cn = [ 'cellHead', `cell-key-${relationKey}`, Relation.className(relation.format), `align${viewRelation?.align}` ];
if (allowed) {
cn.push('canDrag');
@ -95,6 +97,7 @@ const HeadCell = observer(class HeadCell extends React.Component<Props> {
onOpen: () => obj.addClass('active'),
onClose: () => obj.removeClass('active'),
className: isFixed ? 'fixed' : '',
subIds: J.Menu.relationEdit,
data: {
...this.props,
blockId: block.id,

View file

@ -686,16 +686,24 @@ const BlockEmbed = observer(class BlockEmbed extends React.Component<I.BlockComp
iw.postMessage(data, '*');
if (allowIframeResize) {
win.off(`message.${block.id}`).on(`message.${block.id}`, e => {
const oe = e.originalEvent as any;
const { height, blockId } = oe.data;
win.off(`message.${block.id}`).on(`message.${block.id}`, e => {
const oe = e.originalEvent as any;
const { type, height, blockId, url } = oe.data;
if (blockId == block.id) {
iframe.css({ height: Math.max(80, height) });
switch (type) {
case 'resize': {
if (allowIframeResize && (blockId == block.id)) {
iframe.css({ height: Math.max(80, height) });
};
break;
};
});
};
case 'openUrl': {
Action.openUrl(url);
break;
};
};
});
};
if (!iframe.length) {
@ -752,7 +760,7 @@ const BlockEmbed = observer(class BlockEmbed extends React.Component<I.BlockComp
};
case I.EmbedProcessor.Mermaid: {
ReactDOM.render(<MediaMermaid chart={this.text} />, value.get(0));
ReactDOM.render(<MediaMermaid id={`block-${block.id}-mermaid`} chart={this.text} />, value.get(0));
break;
};

View file

@ -237,7 +237,7 @@ const BlockImage = observer(class BlockImage extends React.Component<I.BlockComp
const { rootId, block } = this.props;
const blocks = S.Block.getBlocks(rootId, (it: I.Block) => it.isFileImage() || it.isFileVideo());
const idx = blocks.findIndex(it => it.id == block.id);
const targetId = block.getTargetObjectId();
const gallery = [];
blocks.forEach(it => {
@ -268,7 +268,7 @@ const BlockImage = observer(class BlockImage extends React.Component<I.BlockComp
S.Popup.open('preview', {
data: {
initialIdx: idx,
initialIdx: gallery.findIndex(it => it.object.id == targetId),
gallery,
},
});

View file

@ -315,7 +315,7 @@ const BlockText = observer(class BlockText extends React.Component<Props> {
const reg = /(^|[^\d<\$]+)?\$((?:[^$<]|\.)*?)\$([^\d>\$]+|$)/gi;
const regCode = new RegExp(`^${code}|${code}$`, 'i');
if (!/\$((?:[^$<]|\.)*?)\$/.test(value)) {
if (!/\$[^\$]+\$/.test(value)) {
return;
};
@ -675,7 +675,7 @@ const BlockText = observer(class BlockText extends React.Component<Props> {
const { rootId, block, onMenuAdd, isInsideTable, onKeyUp } = this.props;
const { filter } = S.Common;
const { id, content } = block;
const { id, content, fields } = block;
const range = this.getRange();
const langCodes = Object.keys(Prism.languages).join('|');
const langKey = '```(' + langCodes + ')?';
@ -712,8 +712,13 @@ const BlockText = observer(class BlockText extends React.Component<Props> {
const menuOpenMention = S.Menu.isOpen('blockMention');
const oneSymbolBefore = range ? value[range.from - 1] : '';
const twoSymbolBefore = range ? value[range.from - 2] : '';
const isRtl = U.Common.checkRtl(value);
keyboard.setRtl(U.Common.checkRtl(value));
keyboard.setRtl(isRtl);
if (isRtl) {
U.Data.setRtl(rootId, block.id);
};
if (range) {
isAllowedMenu = isAllowedMenu && (!range.from || (range.from == 1) || [ ' ', '\n', '(', '[', '"', '\'' ].includes(twoSymbolBefore));

View file

@ -21,7 +21,12 @@ const BlockType = observer(class BlockType extends React.Component<I.BlockCompon
};
render (): any {
const { block } = this.props;
const { block, readonly } = this.props;
if (readonly) {
return null;
};
const items = this.getItems();
const cn = [ 'wrap', 'focusable', 'c' + block.id ];

View file

@ -249,11 +249,8 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
return;
};
this.containerScrollTop = Storage.getScroll('editor', rootId, isPopup);
this.focusInit();
U.Common.getScrollContainer(isPopup).scrollTop(this.containerScrollTop);
if (onOpen) {
onOpen();
};
@ -262,7 +259,12 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
this.refControls.forceUpdate();
};
window.setTimeout(() => this.resizePage(), 15);
this.resizePage(() => {
this.containerScrollTop = Storage.getScroll('editor', rootId, isPopup);
if (this.containerScrollTop) {
U.Common.getScrollContainer(isPopup).scrollTop(this.containerScrollTop);
};
});
});
};
@ -352,7 +354,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
to = storage.range.to;
};
if (!block) {
if (!block || !block.isText()) {
if (U.Object.isNoteLayout(root.layout)) {
block = S.Block.getFirstBlock(rootId, -1, it => it.isFocusable());
} else {
@ -370,8 +372,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
focus.set(block.id, { from, to });
focus.apply();
window.setTimeout(() => focus.scroll(isPopup, block.id), 10);
focus.scroll(isPopup, block.id);
};
unbind () {
@ -402,7 +403,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
win.on(`keydown.${ns}`, e => this.onKeyDownEditor(e));
win.on(`paste.${ns}`, (e: any) => {
if (!keyboard.isFocused) {
this.onPasteEvent(e, {});
this.onPasteEvent(e, this.props);
};
});
@ -595,6 +596,11 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
ret = true;
});
// Paste
keyboard.shortcut(`${cmd}+v`, e, (pressed: string) => {
ret = true;
});
// Undo
keyboard.shortcut(`${cmd}+z`, e, () => {
if (!readonly) {
@ -980,7 +986,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
});
keyboard.shortcut('arrowleft, arrowright', e, (pressed: string) => {
this.onArrowHorizontal(e, pressed, range, length, props);
this.onArrowHorizontal(e, text, pressed, range, length, props);
});
// Enter
@ -997,7 +1003,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
const isShift = pressed.match('shift') ? true : false;
if (isInsideTable) {
this.onArrowHorizontal(e, pressed, { from: length, to: length }, length, props);
this.onArrowHorizontal(e, text, pressed, { from: length, to: length }, length, props);
} else {
this.onTabBlock(e, range, isShift);
};
@ -1595,13 +1601,14 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
};
};
onArrowHorizontal (e: any, pressed: string, range: I.TextRange, length: number, props: any) {
onArrowHorizontal (e: any, text: string, pressed: string, range: I.TextRange, length: number, props: any) {
const { focused } = focus.state;
const { rootId } = this.props;
const { isInsideTable } = props;
const block = S.Block.getLeaf(rootId, focused);
const withTab = pressed.match(Key.tab);
const dir = pressed.match([ Key.left, Key.shift ].join('|')) ? -1 : 1;
const isRtl = U.Common.checkRtl(text);
const dir = (pressed.match([ Key.left, Key.shift ].join('|')) ? -1 : 1) * (isRtl ? -1 : 1);
if (!block) {
return;
@ -2195,6 +2202,10 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
S.Block.toggle(rootId, message.blockId, true);
};
if (keyboard.isRtl) {
U.Data.setRtl(rootId, message.blockId);
};
analytics.event('CreateBlock', { middleTime: message.middleTime, type: I.BlockType.Text, style });
});
};
@ -2287,7 +2298,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
};
};
resizePage () {
resizePage (callBack?: () => void) {
const { isLoading } = this.state;
if (isLoading || !this._isMounted) {
@ -2331,6 +2342,10 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
if (cover.length) {
cover.css({ top: hh });
};
if (callBack) {
callBack();
};
});
};

View file

@ -96,7 +96,7 @@ const Input = forwardRef<InputRef, Props>(({
const isFocused = useRef(false);
const rangeRef = useRef<I.TextRange | null>(null);
const cn = [ 'input', `input-${inputType}`, className ];
if (readonly) {
cn.push('isReadonly');
};
@ -247,8 +247,6 @@ const Input = forwardRef<InputRef, Props>(({
return rect;
};
useEffect(() => setValue(initialValue), []);
useEffect(() => {
if (maskOptions && inputRef.current) {
new Inputmask(maskOptions.mask, maskOptions).mask($(inputRef.current).get(0));

View file

@ -157,7 +157,7 @@ const Phrase = forwardRef<PhraseRefProps, Props>(({
};
const onToggleHandler = () => {
const pin = Storage.getPin();
const { pin } = S.Common;
const onSuccess = () => {
setIsHidden(!isHidden);

View file

@ -23,6 +23,7 @@ interface SelectRefProps {
getValue: () => any;
setValue: (v: any) => void;
setOptions: (options: I.Option[]) => void;
show: (e: MouseEvent) => void;
};
const Select = forwardRef<SelectRefProps, Props>(({
@ -198,6 +199,7 @@ const Select = forwardRef<SelectRefProps, Props>(({
getValue: () => getValue(val),
setValue: setValueHandler,
setOptions: (options: I.Option[]) => setOptions(options),
show,
}));
return (

View file

@ -1,7 +1,7 @@
import React, { forwardRef, useState, useEffect, useImperativeHandle } from 'react';
import { observer } from 'mobx-react';
import { Button, Icon, IconObject, ObjectName, Label } from 'Component';
import { I, S, U, J, keyboard, translate } from 'Lib';
import { I, S, U, J, keyboard, translate, analytics } from 'Lib';
import HeaderBanner from 'Component/page/elements/head/banner';
const HeaderMainObject = observer(forwardRef<{}, I.HeaderComponent>((props, ref) => {
@ -16,7 +16,7 @@ const HeaderMainObject = observer(forwardRef<{}, I.HeaderComponent>((props, ref)
const isLocked = root ? root.isLocked() : false;
const isTypeOrRelation = U.Object.isTypeOrRelationLayout(object.layout);
const isDate = U.Object.isDateLayout(object.layout);
const showShare = !isTypeOrRelation && !isDate && config.experimental && !isDeleted;
const showShare = S.Block.isAllowed(object.restrictions, [ I.RestrictionObject.Publish ], true) && config.experimental && !isDeleted;
const showRelations = !isTypeOrRelation && !isDate && !isDeleted;
const showMenu = !isTypeOrRelation && !isDeleted;
const cmd = keyboard.cmdSymbol();
@ -94,6 +94,8 @@ const HeaderMainObject = observer(forwardRef<{}, I.HeaderComponent>((props, ref)
rootId,
}
});
analytics.event('ClickShareObject', { objectType: object.type });
};
const onRelationHandler = () => {
@ -174,4 +176,4 @@ const HeaderMainObject = observer(forwardRef<{}, I.HeaderComponent>((props, ref)
}));
export default HeaderMainObject;
export default HeaderMainObject;

View file

@ -1,4 +1,4 @@
import React, { forwardRef, useImperativeHandle, useEffect } from 'react';
import React, { forwardRef, useImperativeHandle, useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { I, C, S, U, J, Relation, translate, keyboard, analytics } from 'Lib';
import { Icon, IconObject, Pager, ObjectName, Cell, SelectionTarget } from 'Component';
@ -40,8 +40,8 @@ const ListObject = observer(forwardRef<ListObjectRefProps, Props>(({
route = '',
}, ref) => {
const [ sortId, setSortId ] = React.useState('');
const [ sortType, setSortType ] = React.useState(I.SortType.Asc);
const [ sortId, setSortId ] = useState('');
const [ sortType, setSortType ] = useState(I.SortType.Asc);
const { offset, total } = S.Record.getMeta(subId, '');
const { dateFormat } = S.Common;

View file

@ -26,6 +26,7 @@ interface Props {
interface ListManagerRefProps {
getSelected(): string[];
setSelection(ids: string[]): void;
setSelectedRange(start: number, end: number): void;
selectionClear(): void;
};
@ -48,7 +49,6 @@ const ListManager = observer(forwardRef<ListManagerRefProps, Props>(({
onAfterLoad
}, ref) => {
const nodeRef = useRef(null);
const filterWrapperRef = useRef(null);
const filterRef = useRef(null);
const listRef = useRef(null);
@ -144,18 +144,17 @@ const ListManager = observer(forwardRef<ListManagerRefProps, Props>(({
const load = () => {
const filter = getFilterValue();
const fl = [].concat(filters || []);
const sl = [].concat(sorts || []);
const fl = [ ...filters ];
if (filter) {
filters.push({ relationKey: 'name', condition: I.FilterCondition.Like, value: filter });
fl.push({ relationKey: 'name', condition: I.FilterCondition.Like, value: filter });
};
setIsLoading(true);
U.Data.searchSubscribe({
subId,
sorts: sl,
sorts,
filters: fl,
ignoreArchived,
ignoreHidden,
@ -400,6 +399,7 @@ const ListManager = observer(forwardRef<ListManagerRefProps, Props>(({
useImperativeHandle(ref, () => ({
getSelected: () => selected,
setSelection,
setSelectedRange,
selectionClear,
}));

View file

@ -53,7 +53,7 @@ class MenuBlockHAlign extends React.Component<I.Menu> {
const { data } = param;
const { rootId } = data;
const blockIds = data.blockIds || [];
const restricted = [];
const restricted = [].concat(data.restricted || []);
for (const id of blockIds) {
const block = S.Block.getLeaf(rootId, id);
@ -69,7 +69,7 @@ class MenuBlockHAlign extends React.Component<I.Menu> {
};
};
return U.Menu.getHAlign(restricted);
return U.Menu.prepareForSelect(U.Menu.getHAlign(restricted));
};
onOver (e: any, item: any) {
@ -79,12 +79,12 @@ class MenuBlockHAlign extends React.Component<I.Menu> {
};
onClick (e: any, item: any) {
const { param } = this.props;
const { param, close } = this.props;
const { data } = param;
const { onSelect } = data;
this.props.close();
onSelect(item.id);
close();
onSelect(Number(item.id));
};
};

View file

@ -113,7 +113,7 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
/>
</div>
<div className="buttons">
<Icon className="delete" onClick={e => this.onDelete(e, element)} />
<Icon className="delete withBackground" onClick={e => this.onDelete(e, element)} />
</div>
</div>
);
@ -149,7 +149,7 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
{type?.name}
</div>
<div className="buttons">
<Icon className="delete" onClick={e => this.onDelete(e, element)} />
<Icon className="delete withBackground" onClick={e => this.onDelete(e, element)} />
</div>
</div>
);

View file

@ -0,0 +1,268 @@
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import $ from 'jquery';
import { observer } from 'mobx-react';
import { I, S, U, J, analytics, keyboard, translate, Action } from 'Lib';
import { MenuItemVertical } from 'Component';
const MenuNew = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
const { param, setActive, setHover, onKeyDown, getId, getSize, position } = props;
const { data } = param;
const {
rootId, subId, blockId, typeId, templateId, route, hasSources, getView, onTypeChange, onSetDefault, onSelect, isCollection, withTypeSelect,
isAllowedObject,
} = data;
const n = useRef(-1);
const [ template, setTemplate ] = useState(null);
const rebind = () => {
unbind();
$(window).on('keydown.menu', e => onKeyDown(e));
window.setTimeout(() => setActive(), 15);
};
const unbind = () => {
$(window).off('keydown.menu');
};
const loadTemplate = () => {
U.Object.getById(templateId, {}, (object: any) => {
setTemplate(object ? object : null);
});
};
const getSections = () => {
const type = S.Record.getTypeById(typeId);
const templateName = template ? template.name : translate('commonBlank');
const itemsAdd: any[] = [
{ id: 'new', icon: 'add', name: translate('commonNew') },
];
const itemsSettings: any[] = [
{ id: 'template', name: translate('commonTemplate'), arrow: true, caption: templateName },
];
if (isAllowedObject && isCollection) {
itemsAdd.push({ id: 'existing', icon: 'existingObject', name: translate('menuDataviewExistingObject'), arrow: true });
};
if (withTypeSelect) {
itemsSettings.unshift({ id: 'type', name: translate('commonDefaultType'), arrow: true, caption: type.name });
};
let sections: any[] = [
{ id: 'add', name: '', children: itemsAdd },
{ id: 'settings', name: translate('commonSettings'), children: itemsSettings },
].filter(it => it);
sections = sections.map((s: any) => {
s.children = s.children.filter(it => it);
return s;
}).filter(s => !!s.children.length);
return sections;
};
const getItems = () => {
const sections = getSections();
let items: any[] = [];
for (const section of sections) {
items = items.concat(section.children);
};
return items;
};
const onOver = (e: React.MouseEvent, item: any) => {
if (!item.arrow) {
S.Menu.closeAll(J.Menu.dataviewNew);
return;
};
const allowedLayouts = U.Object.getPageLayouts().concat(U.Object.getSetLayouts());
const menuParam: I.MenuParam = {
element: `#${getId()} #item-${item.id}`,
offsetX: getSize().width,
vertical: I.MenuDirection.Center,
isSub: true,
className: param.className,
classNameWrap: param.classNameWrap,
data: {
rootId,
blockId,
hasSources,
getView,
typeId,
templateId,
route,
},
};
let menuId = '';
switch (item.id) {
case 'existing': {
menuId = 'searchObject';
menuParam.data = Object.assign(menuParam.data, {
filters: [
{ relationKey: 'layout', condition: I.FilterCondition.NotIn, value: U.Object.getSystemLayouts() },
{ relationKey: 'isReadonly', condition: I.FilterCondition.NotEqual, value: true },
],
onSelect: (el: any) => {
Action.addToCollection(rootId, [ el.id ]);
},
skipIds: [ ...S.Record.getRecordIds(subId, ''), rootId ],
});
break;
};
case 'type': {
menuId = 'typeSuggest';
menuParam.data = Object.assign(menuParam.data, {
filter: '',
filters: [
{ relationKey: 'recommendedLayout', condition: I.FilterCondition.In, value: allowedLayouts },
{ relationKey: 'uniqueKey', condition: I.FilterCondition.NotEqual, value: J.Constant.typeKey.template },
],
skipIds: [ typeId ],
onClick: type => {
data.typeId = type.id;
data.templateId = type.defaultTemplateId || J.Constant.templateId.blank;
loadTemplate();
if (onTypeChange) {
onTypeChange(type.id);
};
},
});
break;
};
case 'template': {
const update = (item) => {
data.templateId = item.id;
loadTemplate();
};
menuId = 'dataviewTemplateList';
menuParam.data = Object.assign(menuParam.data, {
onSetDefault: (item) => {
update(item);
if (onSetDefault) {
onSetDefault(item);
};
},
onSelect: (item) => {
update(item);
if (onSelect) {
onSelect(item);
};
},
});
break;
};
};
if (menuId && !S.Menu.isOpen(menuId, item.id)) {
S.Menu.closeAll(J.Menu.dataviewNew, () => {
S.Menu.open(menuId, menuParam);
});
};
};
const onClick = (e: React.MouseEvent, item: any) => {
if (item.arrow) {
return;
};
switch (item.id) {
case 'new': {
if (onSelect) {
onSelect(template ? template : { id: J.Constant.templateId.blank });
};
break;
};
};
};
const onMouseEnter = (e: React.MouseEvent, item: any) => {
if (!keyboard.isMouseDisabled) {
setActive(item, false);
onOver(e, item);
};
};
const onMouseLeave = (e: React.MouseEvent, item: any) => {
if (!keyboard.isMouseDisabled) {
setHover(null, false);
};
};
const resize = () => {
$(`#${getId()} .content`).css({ height: 'auto' });
position();
};
const sections = getSections();
const Section = (item: any) => (
<div id={'section-' + item.id} className="section">
{item.name ? <div className="name">{item.name}</div> : ''}
<div className="items">
{item.children.map((action: any, i: number) => (
<MenuItemVertical
key={i}
{...action}
icon={action.icon}
onMouseEnter={e => onMouseEnter(e, action)}
onMouseLeave={e => onMouseLeave(e, action)}
onClick={e => onClick(e, action)}
/>
))}
</div>
</div>
);
useEffect(() => {
rebind();
loadTemplate();
window.setTimeout(() => resize(), 5);
return () => {
unbind();
S.Menu.closeAll(J.Menu.dataviewNew);
};
}, []);
useImperativeHandle(ref, () => ({
rebind,
unbind,
loadTemplate,
getSections,
getItems,
getIndex: () => n.current,
setIndex: (i: number) => n.current = i,
onOver,
onClick,
onMouseEnter,
onMouseLeave,
resize,
Section,
}), []);
return (
<>
{sections.map((item: any, i: number) => (
<Section key={i} index={i} {...item} />
))}
</>
);
}));
export default MenuNew;

View file

@ -55,7 +55,7 @@ const MenuObjectValues = observer(class MenuObjectValues extends React.Component
<IconObject object={item} />
<ObjectName object={item} />
</span>
{canEdit ? <Icon className="delete" onClick={e => this.onRemove(e, item)} /> : ''}
{canEdit ? <Icon className="delete withBackground" onClick={e => this.onRemove(e, item)} /> : ''}
</div>
);
});

View file

@ -212,12 +212,20 @@ const MenuRelationEdit = observer(class MenuRelationEdit extends React.Component
const { param } = this.props;
const { data } = param;
const { rootId, blockId, extendedOptions, readonly, noUnlink } = data;
const object = S.Detail.get(rootId, rootId);
const relation = this.getRelation();
if (!relation) {
return [];
};
const viewRelation = this.getViewRelation();
const object = S.Detail.get(rootId, rootId);
const isFile = relation && (relation.format == I.RelationType.File);
const isName = relation && (relation.relationKey == 'name');
const canFilter = !isFile;
const canSort = !isFile;
const canHide = relation && (relation.relationKey != 'name');
const canHide = !isName;
const canAlign = !isName;
const canCalculate = relation;
let unlinkText = translate('commonUnlink');
@ -267,19 +275,19 @@ const MenuRelationEdit = observer(class MenuRelationEdit extends React.Component
},
{
children: [
canAlign ? { id: 'align', icon: U.Data.alignHIcon(viewRelation?.align), name: translate('commonAlign'), arrow: true } : null,
canCalculate ? { id: 'calculate', icon: 'relation c-number', name: translate('commonCalculate'), arrow: true } : null,
]
},
]);
};
sections = sections.filter((s: any) => {
sections = sections.map(s => {
s.children = s.children.filter(c => c);
return s.children.length > 0;
return s;
});
sections = sections.filter(s => s.children.length);
return sections;
};
@ -306,16 +314,18 @@ const MenuRelationEdit = observer(class MenuRelationEdit extends React.Component
return;
};
const { getId, getSize, param } = this.props;
const { getId, getSize, param, close } = this.props;
const { classNameWrap, data } = param;
const { rootId } = data;
const relation = this.getRelation();
const object = S.Detail.get(rootId, rootId);
if (!relation) {
return;
};
const viewRelation = this.getViewRelation();
const object = S.Detail.get(rootId, rootId);
let menuContext = null;
let menuId = '';
@ -331,6 +341,20 @@ const MenuRelationEdit = observer(class MenuRelationEdit extends React.Component
};
switch (item.id) {
case 'align': {
menuId = 'blockAlign';
menuParam.data = Object.assign(menuParam.data, {
value: viewRelation?.align,
restricted: [ I.BlockHAlign.Justify ],
onSelect: (align: I.BlockHAlign) => {
this.saveViewRelation('align', align);
close();
}
});
break;
};
case 'calculate': {
const save = (id: any) => {
id = Number(id) || 0;

View file

@ -80,8 +80,8 @@ const MenuSort = observer(class MenuSort extends React.Component<I.Menu> {
</div>
{!isReadonly ? (
<div className="buttons">
<Icon className="more" onClick={e => this.onMore(e, item)} />
<Icon className="delete" onClick={e => this.onRemove(e, item)} />
<Icon className="more withBackground" onClick={e => this.onMore(e, item)} />
<Icon className="delete withBackground" onClick={e => this.onRemove(e, item)} />
</div>
) : ''}
</div>

View file

@ -33,7 +33,7 @@ const MenuSource = observer(class MenuSource extends React.Component<I.Menu> {
<div className="value">{item.value}</div>
</div>
<div className="buttons">
{canDelete ? <Icon className="delete" onClick={e => this.onRemove(e, item)} /> : ''}
{canDelete ? <Icon className="delete withBackground" onClick={e => this.onRemove(e, item)} /> : ''}
</div>
</form>
);

View file

@ -1,6 +1,6 @@
import * as React from 'react';
import $ from 'jquery';
import { Icon, Title, PreviewObject, IconObject } from 'Component';
import { Icon, PreviewObject } from 'Component';
import { I, C, S, U, J, translate, keyboard, sidebar } from 'Lib';
import { observer } from 'mobx-react';
@ -14,14 +14,12 @@ const MenuTemplateList = observer(class MenuTemplateList extends React.Component
node: any = null;
n = 0;
typeId = '';
constructor (props: I.Menu) {
super(props);
this.onClick = this.onClick.bind(this);
this.onMore = this.onMore.bind(this);
this.onType = this.onType.bind(this);
this.setCurrent = this.setCurrent.bind(this);
this.getTemplateId = this.getTemplateId.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
@ -31,11 +29,10 @@ const MenuTemplateList = observer(class MenuTemplateList extends React.Component
render () {
const { param, setHover } = this.props;
const { data } = param;
const { withTypeSelect, noTitle, typeId } = data;
const { typeId } = data;
const previewSize = data.previewSize || I.PreviewSize.Small;
const templateId = this.getTemplateId();
const items = this.getItems();
const type = S.Record.getTypeById(typeId);
const isAllowed = U.Object.isAllowedTemplate(typeId);
const ItemBlank = (item: any) => {
@ -105,18 +102,6 @@ const MenuTemplateList = observer(class MenuTemplateList extends React.Component
return (
<div ref={node => this.node = node}>
{withTypeSelect ? (
<div id="defaultType" className="select big defaultTypeSelect" onClick={this.onType}>
<div className="item">
<IconObject object={type} size={18} />
<div className="name">{type?.name || translate('commonObjectType')}</div>
</div>
<Icon className="arrow black" />
</div>
) : ''}
{!noTitle ? <Title text={translate('commonTemplates')} /> : ''}
<div className="items">
{items.map((item: any, i: number) => (
<Item key={i} {...item} />
@ -320,36 +305,6 @@ const MenuTemplateList = observer(class MenuTemplateList extends React.Component
};
};
onType () {
const { getId, param } = this.props;
const { data } = param;
const { onTypeChange } = data;
const allowedLayouts = U.Object.getPageLayouts().concat(U.Object.getSetLayouts());
S.Menu.open('typeSuggest', {
element: `#${getId()} #defaultType`,
horizontal: I.MenuDirection.Right,
data: {
rebind: this.rebind,
filter: '',
filters: [
{ relationKey: 'recommendedLayout', condition: I.FilterCondition.In, value: allowedLayouts },
{ relationKey: 'uniqueKey', condition: I.FilterCondition.NotEqual, value: J.Constant.typeKey.template },
],
onClick: type => {
data.typeId = type.id;
data.templateId = type.defaultTemplateId || J.Constant.templateId.blank;
this.load();
if (onTypeChange) {
onTypeChange(type.id);
};
},
}
});
};
beforePosition () {
const { param, getId } = this.props;
const { data } = param;

View file

@ -3,7 +3,7 @@ import $ from 'jquery';
import raf from 'raf';
import { observer } from 'mobx-react';
import { Editable } from 'Component';
import { I, J, keyboard, translate } from 'Lib';
import { I, J, U } from 'Lib';
const MenuText = observer(class MenuText extends React.Component<I.Menu> {
@ -44,7 +44,7 @@ const MenuText = observer(class MenuText extends React.Component<I.Menu> {
const length = value.length;
if (this.node) {
this.node.setValue(value);
this.node.setValue(U.Common.htmlSpecialChars(value));
this.node.setRange({ from: length, to: length });
};

View file

@ -53,7 +53,7 @@ const MenuViewList = observer(class MenuViewList extends React.Component<I.Menu>
<div className="name">{item.name}</div>
</div>
<div className="buttons">
<Icon className="more" onClick={e => this.onViewContext(e, item)} />
<Icon className="more withBackground" onClick={e => this.onViewContext(e, item)} />
</div>
</div>
));

View file

@ -70,8 +70,7 @@ import MenuDataviewContext from './dataview/context';
import MenuDataviewCreateBookmark from './dataview/create/bookmark';
import MenuDataviewTemplateContext from './dataview/template/context';
import MenuDataviewTemplateList from './dataview/template/list';
import MenuQuickCapture from './quickCapture';
import MenuDataviewNew from './dataview/new';
import MenuSyncStatus from './syncStatus';
import MenuSyncStatusInfo from './syncStatus/info';
@ -150,8 +149,7 @@ const Components: any = {
dataviewCreateBookmark: MenuDataviewCreateBookmark,
dataviewTemplateContext: MenuDataviewTemplateContext,
dataviewTemplateList: MenuDataviewTemplateList,
quickCapture: MenuQuickCapture,
dataviewNew: MenuDataviewNew,
syncStatus: MenuSyncStatus,
syncStatusInfo: MenuSyncStatusInfo,

View file

@ -169,8 +169,8 @@ const MenuItemFilter = observer(class MenuItemFilter extends React.Component<Pro
{!readonly ? (
<div className="buttons">
<Icon className="more" onClick={onClick} />
<Icon className="delete" onClick={onRemove} />
<Icon className="more withBackground" onClick={onClick} />
<Icon className="delete withBackground" onClick={onRemove} />
</div>
) : ''}
</div>

View file

@ -155,7 +155,7 @@ class MenuItemVertical extends React.Component<I.MenuItem> {
) : (
<div className="caption">{caption}</div>
)}
{withMore ? <Icon className="more" onMouseDown={onMore} /> : ''}
{withMore ? <Icon className="more withBackground" onMouseDown={onMore} /> : ''}
</React.Fragment>
);
};
@ -164,7 +164,8 @@ class MenuItemVertical extends React.Component<I.MenuItem> {
<React.Fragment>
<div
className="clickable"
onMouseDown={hasClick ? undefined : onClick}
onClick={hasClick ? undefined : onClick}
onContextMenu={!hasClick && withMore ? onMore : undefined}
>
{iconMainElement}
{nameElement}
@ -180,9 +181,10 @@ class MenuItemVertical extends React.Component<I.MenuItem> {
ref={node => this.node = node}
id={`item-${id}`}
className={cn.join(' ')}
onMouseDown={hasClick ? onClick : undefined}
onClick={hasClick ? onClick : undefined}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onMouseLeave={onMouseLeave}
onContextMenu={hasClick && withMore ? onMore : undefined}
style={style}
>
{content}

View file

@ -1,58 +1,215 @@
import React, { forwardRef, useRef, useState } from 'react';
import { Title, Input, Label, Switch, Button, Icon, Loader } from 'Component';
import { J, U, I, S, Action, translate } from 'Lib';
import React, { forwardRef, useRef, useState, useEffect } from 'react';
import { observer } from 'mobx-react';
import { Title, Input, Label, Switch, Button, Icon, Error, Loader } from 'Component';
import { C, U, I, S, Action, translate, analytics, Preview } from 'Lib';
import $ from 'jquery';
const MenuPublish = forwardRef<I.MenuRef, I.Menu>((props, ref) => {
const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
const { param, close } = props;
const { data } = param;
const { rootId } = data;
const { isOnline } = S.Common;
const inputRef = useRef(null);
const publishRef = useRef(null);
const unpublishRef = useRef(null);
const joinRef = useRef(null);
const space = U.Space.getSpaceview();
const object = S.Detail.get(rootId, rootId, []);
const [ isLoading, setIsLoading ] = useState(false);
const participant = U.Space.getMyParticipant();
const domain = U.Common.sprintf(J.Url.publish, participant.resolvedName);
const [ slug, setSlug ] = useState(U.Common.slug(object.name));
const [ status, setStatus ] = useState(null);
const [ isStatusLoading, setIsStatusLoading ] = useState(false);
const [ isStatusLoaded, setIsStatusLoaded ] = useState(false);
const [ error, setError ] = useState('');
const domain = U.Space.getPublishDomain();
const url = U.Space.getPublishUrl(slug);
const items = [
(!space.isPersonal ? {
id: 'space', name: translate('popupSettingsSpaceIndexShareShareTitle'), onClick: () => {
S.Popup.open('settings', { data: { page: 'spaceShare', isSpace: true }, className: 'isSpace' });
(!space.isPersonal ?
{
id: 'space',
name: translate('popupSettingsSpaceIndexShareShareTitle'),
onClick: () => {
S.Popup.open('settings', {
data: {
page: 'spaceShare',
isSpace: true,
route: analytics.route.share,
},
className: 'isSpace'
});
close();
analytics.event('ClickShareObjectShareSpace', { objectType: object.type });
},
} : null),
{
id: 'export', name: translate('popupExportTitle'), onClick: () => {
id: 'export',
name: translate('popupExportTitle'),
onClick: () => {
S.Popup.open('export', { data: { objectIds: [ rootId ], allowHtml: true } });
close();
analytics.event('ClickShareObjectShareExport', { objectType: object.type });
},
},
].filter(it => it);
const onPublish = () => {
setIsLoading(true);
Action.publish(rootId, inputRef.current.getValue(), () => setIsLoading(false));
const onPublish = (isUpdate?: boolean) => {
const analyticsName = isUpdate ? 'ShareObjectUpdate' : 'ShareObjectPublish';
publishRef.current.setLoading(true);
C.PublishingCreate(S.Common.space, rootId, slug, joinRef.current?.getValue(), (message: any) => {
publishRef.current.setLoading(false);
if (message.error.code) {
setError(message.error.description);
return;
};
if (message.url) {
Action.openUrl(message.url);
close();
analytics.event(analyticsName, { objectType: object.type });
};
});
analytics.event(`Click${analyticsName}`, { objectType: object.type });
};
const onUnpublish = () => {
unpublishRef.current.setLoading(true);
C.PublishingRemove(S.Common.space, rootId, (message: any) => {
unpublishRef.current.setLoading(false);
if (message.error.code) {
setError(message.error.description);
return;
};
close();
analytics.event('ShareObjectUnpublish', { objectType: object.type });
});
analytics.event('ClickShareObjectUnpublish', { objectType: object.type });
};
const onJoinSwitch = (v: boolean) => {
analytics.event('JoinSpaceButtonToPublish', { objectType: object.type, type: v });
};
const loadStatus = () => {
setIsStatusLoading(true);
C.PublishingGetStatus(space.targetSpaceId, rootId, message => {
setIsStatusLoading(false);
if (message.error.code) {
setError(message.error.description);
return;
};
setIsStatusLoaded(true);
const { state } = message;
if (state) {
setStatus(state);
setSlug(state.uri);
inputRef.current.setValue(state.uri);
};
});
};
const showInfo = (e: React.MouseEvent) => {
Preview.tooltipShow({
text: translate('menuPublishInfoTooltip'),
className: 'big',
element: $(e.currentTarget),
typeY: I.MenuDirection.Bottom,
typeX: I.MenuDirection.Left,
delay: 0,
});
analytics.event('ShowShareObjectHelp', { objectType: object.type });
};
const setSlugHander = v => setSlug(U.Common.slug(v));
const onUrlClick = () => Action.openUrl(url);
let buttons = [];
if (isStatusLoaded && isOnline) {
if (status === null) {
buttons.push({ text: translate('menuPublishButtonPublish'), ref: publishRef, onClick: onPublish });
} else {
buttons = buttons.concat([
{ text: translate('menuPublishButtonUnpublish'), color: 'blank', ref: unpublishRef, onClick: onUnpublish },
{ text: translate('menuPublishButtonUpdate'), ref: publishRef, onClick: () => onPublish(true) },
]);
};
};
useEffect(() => {
setSlugHander(object.name);
if (isOnline) {
loadStatus();
};
return () => {
Preview.tooltipHide(true);
};
}, []);
useEffect(() => {
if (isOnline) {
loadStatus();
};
}, [ isOnline ]);
return (
<>
{isLoading ? <Loader /> : ''}
<Title text={translate('menuPublishTitle')} />
<div className="menuHeader">
<Title text={translate('menuPublishTitle')} />
<Icon className="info" onClick={showInfo} />
</div>
<Input value={domain} readonly={true} />
<Input
ref={inputRef}
value={U.Common.slug(object.name)}
value={slug}
focusOnMount={true}
onChange={(e, v) => setSlugHander(v)}
maxLength={300}
/>
<Label className="small" text="https:/any.copp/kjshdfkjahsjdkhAJDH*78/rem-koolhaas-architects" />
<Label className="small" text={url} onClick={onUrlClick} />
<div className="flex">
<Label text={translate('menuPublishLabel')} />
<div className="value">
<Switch />
{space.isShared ? (
<div className="flex">
<Label text={translate('menuPublishLabelJoin')} />
<div className="value">
<Switch ref={joinRef} value={true} onChange={(e, v) => onJoinSwitch(v)} />
</div>
</div>
) : ''}
<div className="buttons">
{isOnline ? (
<>
{isStatusLoading ? <Loader /> : (
<>
{buttons.map((item, i) => <Button key={i} {...item} className="c36" />)}
</>
)}
</>
) : <Label text={translate('menuPublishLabelOffline')} />}
</div>
<Button text={translate('menuPublishButton')} className="c36" onClick={onPublish} />
<Error text={error} />
<div className="outer">
{items.map((item, index) => (
@ -66,6 +223,6 @@ const MenuPublish = forwardRef<I.MenuRef, I.Menu>((props, ref) => {
</>
);
});
}));
export default MenuPublish;

View file

@ -1,677 +0,0 @@
import * as React from 'react';
import $ from 'jquery';
import arrayMove from 'array-move';
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { IconObject, ObjectName, Icon, Filter } from 'Component';
import { I, C, S, U, J, analytics, keyboard, translate, Action, Storage, Preview, sidebar } from 'Lib';
interface State {
isExpanded: boolean;
};
const LIMIT_PINNED = 5;
enum SystemIds {
Add = 'add',
Search = 'search',
Clipboard = 'clipboard',
};
class MenuQuickCapture extends React.Component<I.Menu, State> {
n = 0;
node: any = null;
_isMounted = false;
filter = '';
refFilter: any = null;
timeoutFilter = 0;
intervalClipboard = 0;
items: any[] = [];
clipboardItems: any[] = [];
offset = 0;
state = {
isExpanded: false,
};
constructor (props: I.Menu) {
super(props);
this.onFilterChange = this.onFilterChange.bind(this);
this.onSortStart = this.onSortStart.bind(this);
this.onSortEnd = this.onSortEnd.bind(this);
};
render () {
const { isExpanded } = this.state;
const { getId } = this.props;
const sections = this.getSections();
const { type } = S.Common;
const Items = SortableContainer(({ items }) => (
<div className="items">
{items.map((item, i) => (
<SortableItem key={i} {...item} index={i} />
))}
</div>
));
const Section = section => (
<div id={`section-${section.id}`} className="section">
{section.name ? <div className="name">{section.name}</div> : ''}
{section.id == 'pinned' ? (
<Items
items={section.children}
axis="xy"
lockToContainerEdges={true}
transitionDuration={150}
distance={10}
onSortStart={this.onSortStart}
onSortEnd={this.onSortEnd}
helperClass="isDragging"
helperContainer={() => $(`#${getId()} #section-${section.id} .items`).get(0)}
/>
) : (
<div className="items">
{section.children.map((item, i) => (
<Item key={i} {...item} />
))}
</div>
)}
</div>
);
const SortableItem = SortableElement(item => (<Item {...item} />));
const Item = (item: any) => {
const cn = [ 'item' ];
let icon = null;
let name = null;
if (item.itemId == type) {
cn.push('isDefault');
};
if (item.className) {
cn.push(item.className);
};
if ([ SystemIds.Search, SystemIds.Add, SystemIds.Clipboard ].includes(item.itemId)) {
icon = <Icon className={item.itemId} />;
} else {
icon = <IconObject object={item} />;
};
if (![ SystemIds.Search, SystemIds.Clipboard ].includes(item.itemId)) {
name = <ObjectName object={item} />;
};
return (
<div
id={`item-${item.id}`}
className={cn.join(' ')}
onClick={e => this.onClick(e, item)}
onContextMenu={e => this.onContextMenu(e, item)}
onMouseEnter={e => this.onOver(e, item)}
onMouseLeave={e => this.onOut(e, item)}
>
{icon}
{name}
</div>
);
};
return (
<div ref={node => this.node = node} className="wrap">
{isExpanded ? (
<Filter
ref={ref => this.refFilter = ref}
icon="search"
onIconClick={() => this.refFilter.focus()}
placeholder={translate('menuQuickCaptureSearchObjectTypes')}
value={this.filter}
onChange={this.onFilterChange}
focusOnMount={true}
/>
) : ''}
<div className="sections scrollWrap">
{sections.map((section: any, i: number) => (
<Section key={i} {...section} />
))}
</div>
</div>
);
};
componentDidMount () {
const { param } = this.props;
const { data } = param;
const { isExpanded } = data;
this._isMounted = true;
this.load(true);
this.rebind();
const check = async () => {
const items = await this.getClipboardData();
const needUpdate = this.clipboardItems.length != items.length;
this.clipboardItems = items;
if (needUpdate) {
this.forceUpdate();
};
};
check();
this.intervalClipboard = window.setInterval(check, 2000);
if (isExpanded) {
this.onExpand();
};
};
componentDidUpdate () {
const filter = this.refFilter?.getValue();
if (this.filter != filter) {
this.filter = filter;
this.n = 0;
this.offset = 0;
this.load(true);
return;
};
this.props.position();
this.rebind();
};
componentWillUnmount () {
this._isMounted = false;
this.unbind();
window.clearInterval(this.intervalClipboard);
};
rebind () {
const { getId, close, setActive } = this.props;
this.unbind();
$(window).on('keydown.menu', e => this.onKeyDown(e));
window.setTimeout(() => setActive(), 15);
};
unbind () {
$(window).off('keydown.menu');
$(`#${this.props.getId()}`).off(`mouseleave`);
};
load (clear: boolean, callBack?: (message: any) => void) {
const filter = String(this.filter || '');
const layouts = U.Object.getPageLayouts().concat(U.Object.getSetLayouts());
const filters: any[] = [
{ relationKey: 'layout', condition: I.FilterCondition.In, value: I.ObjectLayout.Type },
{ relationKey: 'recommendedLayout', condition: I.FilterCondition.In, value: layouts },
{ relationKey: 'uniqueKey', condition: I.FilterCondition.NotEqual, value: J.Constant.typeKey.template },
];
const sorts = [
{ relationKey: 'lastUsedDate', type: I.SortType.Desc },
{ relationKey: 'name', type: I.SortType.Asc },
];
const param = {
filters,
sorts,
keys: U.Data.typeRelationKeys(),
fullText: filter,
offset: this.offset,
};
if (clear) {
this.items = [];
};
this.loadRequest(param, () => {
this.loadRequest({ ...param, spaceId: J.Constant.storeSpaceId }, (message: any) => {
if (!this._isMounted) {
return;
};
if (callBack) {
callBack(message);
};
this.forceUpdate();
});
});
};
loadRequest (param: any, callBack?: (message: any) => void) {
U.Data.search(param, (message: any) => {
this.items = this.items.concat(message.records || []);
if (callBack) {
callBack(message);
};
});
};
getSections () {
const { isExpanded } = this.state;
const { space, type } = S.Common;
const pinnedIds = Storage.getPinnedTypes();
const hasClipboard = this.clipboardItems && this.clipboardItems.length;
const cmd = keyboard.cmdSymbol();
let sections: any[] = [];
let items: any[] = [];
if (isExpanded) {
const items = U.Common.objectCopy(this.items || []).map(it => ({ ...it, object: it }));
const library = items.filter(it => (it.spaceId == space)).map((it, i) => {
if (isExpanded && (it.id == type)) {
it.tooltip = translate('commonDefaultType');
};
return it;
});
const pinned = items.filter(it => pinnedIds.includes(it.id)).sort((c1: any, c2: any) => U.Data.sortByPinnedTypes(c1, c2, pinnedIds));
const librarySources = library.map(it => it.sourceObject);
const groups = library.filter(it => U.Object.isInSetLayouts(it.recommendedLayout) && !pinnedIds.includes(it.id));
const objects = library.filter(it => !U.Object.isInSetLayouts(it.recommendedLayout) && !pinnedIds.includes(it.id));
if (this.filter) {
objects.push({
id: SystemIds.Add,
name: U.Common.sprintf(translate('menuTypeSuggestCreateType'), this.filter),
});
};
sections = sections.concat([
{ id: 'groups', name: translate('menuQuickCaptureGroups'), children: groups },
{ id: 'objects', name: translate('commonObjects'), children: objects },
]);
if (pinned.length) {
sections.unshift({ id: 'pinned', name: translate('menuQuickCapturePinned'), children: pinned });
};
if (this.filter) {
sections.push({
id: 'store', name: translate('commonAnytypeLibrary'),
children: items.filter(it => (it.spaceId == J.Constant.storeSpaceId) && !librarySources.includes(it.id)),
});
};
} else {
const pinned = pinnedIds.map(id => S.Record.getTypeById(id)).filter(it => it).slice(0, LIMIT_PINNED);
items = U.Data.getObjectTypesForNewObject().filter(it => !pinnedIds.includes(it.id));
items = items.slice(0, LIMIT_PINNED - pinned.length);
items.push(S.Record.getSetType());
items.push(S.Record.getCollectionType());
items = [].concat(pinned, items);
items = items.filter(it => it);
items = items.map((it, i) => {
it.tooltip = translate('commonNewObject');
it.caption = String(i + 1);
return it;
});
items.unshift({
id: SystemIds.Search,
icon: 'search',
name: '',
tooltip: translate('menuQuickCaptureTooltipSearch'),
caption: '0',
});
items.push({
id: SystemIds.Clipboard,
icon: 'clipboard',
name: '',
tooltip: translate('menuQuickCaptureTooltipClipboard'),
caption: `${cmd} + V`,
className: [ 'clipboard', (hasClipboard ? 'active' : '') ].join(' '),
});
sections.push({ id: 'collapsed', children: items });
};
return U.Menu.sectionsMap(sections.filter((section: any) => {
section.children = section.children.filter(it => it);
return section.children.length > 0;
}));
};
getItems () {
const sections = this.getSections();
let items: any[] = [];
sections.forEach((section: any, i: number) => {
if (section.name && section) {
items.push({ id: section.id, name: section.name, isSection: true });
};
items = items.concat(section.children);
});
return items;
};
onFilterChange (v: string) {
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => this.forceUpdate(), J.Constant.delay.keyboard);
};
onKeyDown (e: any) {
const { isExpanded } = this.state;
const { setHover, onKeyDown } = this.props;
const items = this.getItems();
const length = items.length;
const cmd = keyboard.cmdKey();
keyboard.disableMouse(true);
let ret = false;
keyboard.shortcut('arrowup, arrowleft, arrowdown, arrowright, tab', e, (pressed: string) => {
e.preventDefault();
const dir = [ 'arrowup', 'arrowleft' ].includes(pressed) ? -1 : 1;
this.n += dir;
if (this.n < 0) {
this.n = length - 1;
};
if (this.n > length - 1) {
this.n = 0;
};
setHover(items[this.n], true);
ret = true;
});
if (!isExpanded) {
keyboard.shortcut('0, 1, 2, 3, 4, 5, 6, 7, 8, 9', e, (pressed: string) => {
e.preventDefault();
const n = Number(pressed) || 0;
if (items[n]) {
this.onClick(e, items[n]);
};
ret = true;
});
};
keyboard.shortcut(`${cmd}+v`, e, () => {
e.preventDefault();
this.onPaste();
ret = true;
});
if (!ret) {
onKeyDown(e);
};
};
onClick (e: any, item: any) {
if (item.itemId == SystemIds.Clipboard) {
this.onPaste();
return;
};
if (item.itemId == SystemIds.Search) {
this.onExpand();
analytics.event('ScreenObjectTypeSearch');
return;
};
const { close } = this.props;
const cb = (created?: any) => {
const { isExpanded } = this.state;
const type = created || item;
if (isExpanded && this.filter.length) {
analytics.event('TypeSearchResult');
};
let flags: I.ObjectFlag[] = [];
if (!U.Object.isInSetLayouts(type.recommendedLayout)) {
flags = flags.concat([ I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
};
C.ObjectCreate({ layout: type.recommendedLayout }, flags, item.defaultTemplateId, type.uniqueKey, S.Common.space, (message: any) => {
if (message.error.code || !message.details) {
return;
};
const object = message.details;
U.Object.openAuto(object);
U.Object.setLastUsedDate(object.id, U.Date.now());
analytics.createObject(object.type, object.layout, '', message.middleTime);
analytics.event('SelectObjectType', { objectType: object.type });
});
};
if (item.itemId == SystemIds.Add) {
C.ObjectCreateObjectType({ name: this.filter }, [], S.Common.space, (message: any) => {
if (!message.error.code) {
cb(message.details);
analytics.event('CreateType');
};
});
} else {
if (item.isInstalled) {
cb();
} else {
Action.install({ ...item, id: item.itemId }, true, message => cb(message.details));
};
};
close();
};
onContextMenu (e: any, item: any) {
e.preventDefault();
e.stopPropagation();
if (!this.state.isExpanded) {
return;
};
if ([ SystemIds.Add, SystemIds.Search, SystemIds.Clipboard ].includes(item.itemId)) {
return;
};
const { getId, param } = this.props;
const { className, classNameWrap } = param;
const type = S.Record.getTypeById(item.itemId);
const isPinned = Storage.getPinnedTypes().includes(item.itemId);
const canPin = type.isInstalled;
const canDefault = type.isInstalled && !U.Object.isInSetLayouts(item.recommendedLayout) && (type.id != S.Common.type);
const canDelete = type.isInstalled && S.Block.isAllowed(item.restrictions, [ I.RestrictionObject.Delete ]);
const route = '';
let options: any[] = [
canPin ? { id: 'pin', name: (isPinned ? translate('menuQuickCaptureUnpin') : translate('menuQuickCapturePin')) } : null,
canDefault ? { id: 'default', name: translate('commonSetDefault') } : null,
{ id: 'open', name: translate('menuQuickCaptureOpenType') },
];
if (canDelete) {
options = options.concat([
{ isDiv: true },
{ id: 'remove', name: translate('commonDelete'), color: 'red' },
]);
};
S.Menu.open('select', {
element: `#${getId()} #item-${item.id}`,
vertical: I.MenuDirection.Top,
offsetY: -4,
className,
classNameWrap,
data: {
options,
onSelect: (event: any, element: any) => {
switch (element.id) {
case 'open': {
U.Object.openAuto({ ...item, id: item.itemId });
break;
};
case 'pin': {
isPinned ? Storage.removePinnedType(item.itemId) : Storage.addPinnedType(item.itemId);
analytics.event(isPinned ? 'UnpinObjectType' : 'PinObjectType', { objectType: item.uniqueKey, route });
this.forceUpdate();
break;
};
case 'default': {
S.Common.typeSet(item.uniqueKey);
analytics.event('DefaultTypeChange', { objectType: item.uniqueKey, route });
this.forceUpdate();
break;
};
case 'remove': {
if (S.Block.isAllowed(item.restrictions, [ I.RestrictionObject.Delete ])) {
Action.uninstall({ ...item, id: item.itemId }, true, route);
};
break;
};
};
}
}
});
};
onExpand () {
$(`#${this.props.getId()}`).addClass('isExpanded');
this.setState({ isExpanded: true });
};
onOver (e: any, item: any) {
if (keyboard.isMouseDisabled) {
return;
};
this.props.setActive(item);
if (item.tooltip) {
const node = $(this.node);
const element = node.find(`#item-${item.id}`);
const t = Preview.tooltipCaption(item.tooltip, item.caption);
Preview.tooltipShow({ text: t, element });
};
};
onOut (e: any, item: any) {
Preview.tooltipHide();
};
onSortStart () {
keyboard.disableSelection(true);
$(this.node).addClass('isDragging');
$('body').addClass('grab');
};
onSortEnd (result: any) {
const { oldIndex, newIndex } = result;
const pinned = Storage.getPinnedTypes();
Storage.setPinnedTypes(arrayMove(pinned, oldIndex, newIndex));
this.forceUpdate();
keyboard.disableSelection(false);
$('body').removeClass('grab');
};
async onPaste () {
const type = S.Record.getTypeById(S.Common.type);
const data = await this.getClipboardData();
data.forEach(async item => {
let text = '';
let html = '';
if (item.types.includes('text/plain')) {
const textBlob = await item.getType('text/plain');
if (textBlob) {
text = await textBlob.text();
};
};
if (item.types.includes('text/html')) {
const htmlBlob = await item.getType('text/html');
if (htmlBlob) {
html = await htmlBlob.text();
};
};
if (!text && !html) {
return;
};
const url = U.Common.matchUrl(text);
if (url) {
C.ObjectCreateBookmark({ source: url }, S.Common.space, (message: any) => {
U.Object.openAuto(message.details);
});
} else {
C.ObjectCreate({}, [], type?.defaultTemplateId, type?.uniqueKey, S.Common.space, (message: any) => {
if (message.error.code) {
return;
};
const object = message.details;
C.BlockPaste (object.id, '', { from: 0, to: 0 }, [], false, { html, text }, '', () => {
U.Object.openAuto(object);
});
analytics.createObject(object.type, object.layout, analytics.route.clipboard, message.middleTime);
});
};
});
};
async getClipboardData () {
let ret = [];
try { ret = await navigator.clipboard.read(); } catch (e) { /**/ };
return ret;
};
beforePosition () {
const { getId } = this.props;
const obj = $(`#${getId()}`);
const { ww } = U.Common.getWindowDimensions();
const sw = sidebar.getDummyWidth();
obj.css({ width: '' });
obj.find('.item').each((i: number, item: any) => {
item = $(item);
item.toggleClass('withIcon', !!item.find('.iconObject').length);
});
obj.css({ width: Math.min(ww - J.Size.menuBorder * 2 - sw, Math.ceil(obj.outerWidth())) });
};
};
export default MenuQuickCapture;

View file

@ -108,8 +108,6 @@ const MenuRelationSuggest = observer(class MenuRelationSuggest extends React.Com
/>
) : ''}
{isLoading ? <Loader /> : ''}
{!items.length && !isLoading ? (
<EmptySearch readonly={!canWrite} filter={filter} />
) : ''}
@ -159,7 +157,7 @@ const MenuRelationSuggest = observer(class MenuRelationSuggest extends React.Com
componentDidUpdate () {
const { param } = this.props;
const { data } = param;
const { filter } = data;
const filter = String(data.filter || '');
const items = this.getItems();
if (filter != this.filter) {
@ -326,10 +324,12 @@ const MenuRelationSuggest = observer(class MenuRelationSuggest extends React.Com
};
onFilterChange (v: string) {
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => {
this.props.param.data.filter = this.refFilter.getValue();
}, J.Constant.delay.keyboard);
if (v != this.filter) {
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => {
this.props.param.data.filter = this.refFilter.getValue();
}, J.Constant.delay.keyboard);
};
};
onMouseEnter (e: any, item: any) {
@ -494,7 +494,6 @@ const MenuRelationSuggest = observer(class MenuRelationSuggest extends React.Com
};
resize () {
const { isLoading } = this.state;
const { getId, position, param } = this.props;
const { data } = param;
const { noFilter } = data;
@ -503,7 +502,7 @@ const MenuRelationSuggest = observer(class MenuRelationSuggest extends React.Com
let height = 16 + (noFilter ? 0 : 42);
if (!items.length) {
height = isLoading ? height + 40 : 160;
height = 160;
} else {
height = items.reduce((res: number, current: any) => res + this.getRowHeight(current), height);
};

View file

@ -130,8 +130,6 @@ const MenuSearchObject = observer(class MenuSearchObject extends React.Component
/>
) : ''}
{isLoading ? <Loader /> : ''}
{!items.length && !isLoading ? (
<EmptySearch filter={filter} />
) : ''}
@ -459,7 +457,7 @@ const MenuSearchObject = observer(class MenuSearchObject extends React.Component
addParam.onClick(details);
close();
} else {
const flags = [ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate ];
const flags = [ I.ObjectFlag.SelectTemplate ];
U.Object.create('', '', details, I.BlockPosition.Bottom, '', flags, route || analytics.route.search, (message: any) => {
process(message.details, true);
@ -476,16 +474,18 @@ const MenuSearchObject = observer(class MenuSearchObject extends React.Component
const { data } = param;
const { onFilterChange } = data;
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => {
const filter = this.refFilter.getValue();
if (v != this.filter) {
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => {
const filter = this.refFilter.getValue();
this.props.param.data.filter = filter;
data.filter = filter;
if (onFilterChange) {
onFilterChange(filter);
};
}, J.Constant.delay.keyboard);
if (onFilterChange) {
onFilterChange(filter);
};
}, J.Constant.delay.keyboard);
};
};
getRowHeight (item: any) {
@ -508,13 +508,12 @@ const MenuSearchObject = observer(class MenuSearchObject extends React.Component
const { getId, position, param } = this.props;
const { data } = param;
const { noFilter } = data;
const { isLoading } = this.state;
const items = this.getItems().slice(0, LIMIT);
const obj = $(`#${getId()} .content`);
let height = 16 + (noFilter ? 0 : 42);
if (!items.length) {
height = isLoading ? height + 40 : 160;
height = 160;
} else {
height = items.reduce((res: number, current: any) => res + this.getRowHeight(current), height);
};

View file

@ -83,7 +83,7 @@ const MenuSyncStatus = observer(class MenuSyncStatus extends React.Component<I.M
</div>
<div className="side right">
<Icon className={icon} />
<Icon className="more" onClick={e => this.onContextMenu(e, item)} />
<Icon className="more withBackground" onClick={e => this.onContextMenu(e, item)} />
</div>
</div>
);
@ -92,8 +92,6 @@ const MenuSyncStatus = observer(class MenuSyncStatus extends React.Component<I.M
const rowRenderer = ({ index, key, style, parent }) => {
const item = items[index];
console.log(item);
let content = null;
if (item.isSection) {
content = (

View file

@ -3,7 +3,7 @@ import $ from 'jquery';
import { observer } from 'mobx-react';
import { AutoSizer, CellMeasurer, InfiniteLoader, List, CellMeasurerCache } from 'react-virtualized';
import { Filter, Icon, MenuItemVertical, Loader, EmptySearch } from 'Component';
import { I, C, S, U, J, analytics, keyboard, Action, translate } from 'Lib';
import { I, C, S, U, J, analytics, keyboard, Action, translate, Storage } from 'Lib';
interface State {
isLoading: boolean;
@ -11,7 +11,7 @@ interface State {
const HEIGHT_ITEM = 28;
const HEIGHT_DIV = 16;
const LIMIT = 20;
const LIMIT = 15;
const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I.Menu, State> {
@ -40,11 +40,12 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
render () {
const { isLoading } = this.state;
const { param } = this.props;
const { param, setHover } = this.props;
const { data } = param;
const { filter, noFilter } = data;
const items = this.getItems();
const canWrite = U.Space.canMyParticipantWrite();
const buttons = data.buttons || [];
if (!this.cache) {
return null;
@ -76,6 +77,7 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
style={param.style}
onMouseEnter={e => this.onMouseEnter(e, item)}
onClick={e => this.onClick(e, item)}
withMore={!!item.onMore}
/>
);
};
@ -106,8 +108,6 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
/>
) : ''}
{isLoading ? <Loader /> : ''}
{!items.length && !isLoading ? (
<EmptySearch readonly={!canWrite} filter={filter} />
) : ''}
@ -141,6 +141,19 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
</InfiniteLoader>
</div>
) : ''}
{buttons.length ? (
<div className="bottom">
{buttons.map((item, i) => (
<MenuItemVertical
key={item.id}
{...item}
onMouseEnter={e => setHover(item)}
onClick={e => this.onClick(e, item)}
/>
))}
</div>
) : ''}
</div>
);
};
@ -148,21 +161,29 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
componentDidMount () {
this._isMounted = true;
const { param } = this.props;
const { data } = param;
const { noStore } = data;
if (noStore) {
this.n = 0;
};
this.rebind();
this.resize();
this.load(true);
this.forceUpdate();
};
componentDidUpdate () {
const { param } = this.props;
const { data } = param;
const { filter } = data;
const { noStore } = data;
const filter = String(data.filter || '');
const items = this.getItems();
if (filter != this.filter) {
this.filter = filter;
this.n = -1;
this.n = noStore ? 0 : 1;
this.offset = 0;
this.load(true);
return;
@ -174,8 +195,8 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
keyMapper: i => (items[i] || {}).id,
});
this.rebind();
this.resize();
this.props.setActive();
};
componentWillUnmount () {
@ -189,7 +210,7 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
rebind () {
this.unbind();
$(window).on('keydown.menu', e => this.props.onKeyDown(e));
$(window).on('keydown.menu', e => this.onKeyDown(e));
window.setTimeout(() => this.props.setActive(), 15);
};
@ -197,7 +218,7 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
$(window).off('keydown.menu');
};
loadMoreRows ({ startIndex, stopIndex }) {
loadMoreRows () {
return new Promise((resolve, reject) => {
this.offset += J.Constant.limit.menuRecords;
this.load(false, resolve);
@ -276,8 +297,12 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
const { space } = S.Common;
const { param } = this.props;
const { data } = param;
const { filter } = data;
const { filter, noStore } = data;
const pinned = Storage.getPinnedTypes();
const items = U.Common.objectCopy(this.items || []).map(it => ({ ...it, object: it }));
items.sort((c1, c2) => U.Data.sortByPinnedTypes(c1, c2, pinned));
const library = items.filter(it => (it.spaceId == space));
const librarySources = library.map(it => it.sourceObject);
const canWrite = U.Space.canMyParticipantWrite();
@ -297,14 +322,22 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
} else {
sections = sections.concat([
{
children: [
id: 'store', children: [
{ id: 'store', icon: 'store', name: translate('commonAnytypeLibrary'), arrow: true }
]
]
},
]);
};
};
if (noStore) {
sections = sections.map(it => {
it.name = '';
return it;
});
sections = sections.filter(it => it.id != 'store');
};
sections = sections.filter((section: any) => {
section.children = section.children.filter(it => it);
return section.children.length > 0;
@ -314,7 +347,11 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
};
getItems () {
const { param } = this.props;
const { data } = param;
const { onMore } = data;
const sections = this.getSections();
let items: any[] = [];
sections.forEach((section: any, i: number) => {
@ -329,14 +366,23 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
};
});
if (onMore) {
items = items.map((item: any) => {
item.onMore = e => onMore(e, this, item);
return item;
});
};
return items;
};
onFilterChange (v: string) {
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => {
this.props.param.data.filter = this.refFilter.getValue();
}, J.Constant.delay.keyboard);
if (v != this.filter) {
window.clearTimeout(this.timeoutFilter);
this.timeoutFilter = window.setTimeout(() => {
this.props.param.data.filter = this.refFilter.getValue();
}, J.Constant.delay.keyboard);
};
};
onMouseEnter (e: any, item: any) {
@ -435,9 +481,8 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
if (onClick) {
onClick(S.Detail.mapper(item));
};
U.Object.setLastUsedDate(item.id, U.Date.now());
};
const setLast = item => U.Object.setLastUsedDate(item.id, U.Date.now());
if (item.id == 'add') {
C.ObjectCreateObjectType({ name: filter }, [], S.Common.space, (message: any) => {
@ -446,15 +491,45 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
analytics.event('CreateType');
};
});
} else
if (item.onClick) {
item.onClick(e);
} else {
if (item.isInstalled || noInstall) {
cb(item);
setLast(item);
} else {
Action.install(item, true, message => cb(message.details));
Action.install(item, true, message => {
cb(message.details);
setLast(message.details);
});
};
};
};
onKeyDown (e: any) {
const { onKeyDown, param } = this.props;
const { data } = param;
const buttons = data.buttons || [];
const cmd = keyboard.cmdKey();
const clipboard = buttons.find(it => it.id == 'clipboard');
let ret = false;
if (clipboard && clipboard.onClick) {
keyboard.shortcut(`${cmd}+v`, e, () => {
e.preventDefault();
clipboard.onClick();
ret = true;
});
};
if (!ret) {
onKeyDown(e);
};
};
getRowHeight (item: any) {
return item.isDiv ? HEIGHT_DIV : HEIGHT_ITEM;
};
@ -464,20 +539,23 @@ const MenuTypeSuggest = observer(class MenuTypeSuggest extends React.Component<I
};
resize () {
const { isLoading } = this.state;
const { getId, position, param } = this.props;
const { data } = param;
const { noFilter } = data;
const buttons = data.buttons || [];
const items = this.getItems();
const obj = $(`#${getId()} .content`);
const offset = 16 + (noFilter ? 0 : 42);
const buttonHeight = buttons.reduce((res: number, current: any) => res + this.getRowHeight(current), 16)
let height = 16 + (noFilter ? 0 : 42);
let height = offset + buttonHeight;
if (!items.length) {
height = isLoading ? height + 40 : 160;
height = 160;
} else {
height = items.reduce((res: number, current: any) => res + this.getRowHeight(current), height);
};
height = Math.min(height, 376);
height = Math.min(height, offset + buttonHeight + HEIGHT_ITEM * LIMIT);
obj.css({ height });
position();

View file

@ -45,16 +45,19 @@ const MenuWidget = observer(class MenuWidget extends React.Component<I.Menu> {
{item.options ? (
<div className="options">
{item.options.map((option, i) => {
const withIcon = option.icon;
const cn = [
'option',
item.value == option.id ? 'active' : '',
withIcon ? 'withIcon' : '',
];
const cn = [ 'option' ];
if (item.value == option.id) {
cn.push('active');
};
if (option.icon) {
cn.push('icon');
};
return (
<div className={cn.join(' ')} key={i} onClick={e => this.onOptionClick(e, option, item)}>
{withIcon ? <Icon className={option.icon} /> : option.name}
{option.icon ? <Icon className={option.icon} tooltip={option.name} tooltipY={I.MenuDirection.Top} /> : option.name}
</div>
);
})}
@ -250,6 +253,7 @@ const MenuWidget = observer(class MenuWidget extends React.Component<I.Menu> {
});
break;
};
case 'limit': {
this.limit = Number(option.id);
this.checkState();
@ -277,12 +281,13 @@ const MenuWidget = observer(class MenuWidget extends React.Component<I.Menu> {
const { param, close } = this.props;
const { data } = param;
const { blockId, setEditing, target } = data;
const { blockId, target } = data;
switch (item.itemId) {
case 'remove':
switch (item.id) {
case 'remove': {
Action.removeWidget(blockId, target);
break;
};
};
close();

View file

@ -6,6 +6,7 @@ import { observer } from 'mobx-react';
const PageAuthPinCheck = observer(forwardRef<{}, I.PageComponent>(() => {
const pinRef = useRef(null);
const { pin } = S.Common;
const [ error, setError ] = useState('');
const unbind = () => {
@ -46,7 +47,7 @@ const PageAuthPinCheck = observer(forwardRef<{}, I.PageComponent>(() => {
<Title text={translate('authPinCheckTitle')} />
<Pin
ref={pinRef}
expectedPin={Storage.getPin()}
expectedPin={pin}
onSuccess={onSuccess}
onError={onError}
/>

View file

@ -193,6 +193,7 @@ const Page = observer(class Page extends React.Component<I.PageComponent> {
init () {
const { account } = S.Auth;
const { pin } = S.Common;
const { isPopup } = this.props;
const match = this.getMatch();
const { page, action } = this.getMatchParams();
@ -200,7 +201,6 @@ const Page = observer(class Page extends React.Component<I.PageComponent> {
const isAuth = this.isAuth();
const isMain = this.isMain();
const isPinCheck = this.isAuthPinCheck();
const pin = Storage.getPin();
const win = $(window);
const path = [ page, action ].join('/');
const Component = Components[path];

View file

@ -1,7 +1,7 @@
import React, { forwardRef, useRef, useState, useImperativeHandle } from 'react';
import $ from 'jquery';
import { observer } from 'mobx-react';
import { Title, Footer, Icon, ListManager } from 'Component';
import { Title, Footer, Icon, ListManager, Header } from 'Component';
import { I, U, J, translate, Action, analytics } from 'Lib';
const PageMainArchive = observer(forwardRef<I.PageRef, I.PageComponent>((props, ref) => {
@ -70,30 +70,34 @@ const PageMainArchive = observer(forwardRef<I.PageRef, I.PageComponent>((props,
}));
return (
<div ref={nodeRef} className="wrapper">
<div className="body">
<div className="titleWrapper">
<Icon className="archive" />
<Title text={translate('commonBin')} />
</div>
<>
<Header {...props} component="mainEmpty" />
<ListManager
ref={managerRef}
subId={J.Constant.subId.archive}
filters={filters}
sorts={sorts}
rowLength={getRowLength()}
ignoreArchived={false}
buttons={buttons}
iconSize={48}
resize={resize}
textEmpty={translate('pageMainArchiveEmpty')}
isReadonly={!U.Space.canMyParticipantWrite()}
/>
<div ref={nodeRef} className="wrapper">
<div className="body">
<div className="titleWrapper">
<Icon className="archive" />
<Title text={translate('commonBin')} />
</div>
<ListManager
ref={managerRef}
subId={J.Constant.subId.archive}
filters={filters}
sorts={sorts}
rowLength={getRowLength()}
ignoreArchived={false}
buttons={buttons}
iconSize={48}
resize={resize}
textEmpty={translate('pageMainArchiveEmpty')}
isReadonly={!U.Space.canMyParticipantWrite()}
/>
</div>
</div>
<Footer component="mainObject" />
</div>
<Footer {...props} component="mainObject" />
</>
);
}));

View file

@ -1,6 +1,6 @@
import React, { forwardRef, useRef, useState, useImperativeHandle, useEffect } from 'react';
import { Loader, Title, Error, Frame, Button, Footer } from 'Component';
import { I, C, S, U, translate } from 'Lib';
import { I, C, S, U, J, translate } from 'Lib';
interface PageMainInviteRefProps {
resize: () => void;
@ -35,12 +35,25 @@ const PageMainInvite = forwardRef<PageMainInviteRefProps, I.PageComponent>((prop
const space = U.Space.getSpaceviewBySpaceId(message.spaceId);
if (message.error.code) {
let icon = '';
let title = '';
let text = '';
if (message.error.code == J.Error.Code.SPACE_IS_DELETED) {
icon = 'error';
title = translate('popupConfirmSpaceDeleted');
} else {
icon = 'sad';
title = translate('popupInviteRequestTitle');
text = translate('popupConfirmInviteError');
};
S.Popup.open('confirm', {
data: {
icon: 'sad',
icon,
bgColor: 'red',
title: translate('popupInviteRequestTitle'),
text: translate('popupConfirmInviteError'),
title,
text,
textConfirm: translate('commonOkay'),
canCancel: false,
},
@ -117,4 +130,4 @@ const PageMainInvite = forwardRef<PageMainInviteRefProps, I.PageComponent>((prop
});
export default PageMainInvite;
export default PageMainInvite;

View file

@ -6,7 +6,7 @@ import { AutoSizer, CellMeasurer, InfiniteLoader, List, CellMeasurerCache } from
import { Button, Cover, Loader, IconObject, Header, Footer, ObjectName, ObjectDescription } from 'Component';
import { I, C, S, U, keyboard, focus, translate } from 'Lib';
import Item from 'Component/sidebar/object/item';
import Item from 'Component/sidebar/page/object/item';
interface State {
loading: boolean;
@ -42,6 +42,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
focus = false;
select = false;
refHeader: any = null;
refList = { [ Panel.Left ]: null, [ Panel.Right ]: null };
constructor (props: I.PageComponent) {
super (props);
@ -152,7 +153,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
<AutoSizer className="scrollArea">
{({ width, height }) => (
<List
ref={registerChild}
ref={ref => this.refList[Panel.Left] = ref}
width={width + 20}
height={height - 35}
deferredMeasurmentCache={this.cacheIn}
@ -164,7 +165,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
}}
onRowsRendered={onRowsRendered}
overscanRowCount={10}
scrollToAlignment="start"
scrollToAlignment="center"
/>
)}
</AutoSizer>
@ -191,7 +192,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
<AutoSizer className="scrollArea">
{({ width, height }) => (
<List
ref={registerChild}
ref={ref => this.refList[Panel.Right] = ref}
width={width + 20}
height={height - 35}
deferredMeasurmentCache={this.cacheOut}
@ -203,7 +204,7 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
}}
onRowsRendered={onRowsRendered}
overscanRowCount={10}
scrollToAlignment="start"
scrollToAlignment="center"
/>
)}
</AutoSizer>
@ -312,7 +313,9 @@ const PageMainNavigation = observer(class PageMainNavigation extends React.Compo
if (this.n > l - 1) {
this.n = 0;
};
this.setActive();
this.refList[this.panel]?.scrollToRow(this.n);
window.setTimeout(() => this.setActive(), 0);
});
keyboard.shortcut('arrowleft, arrowright', e, (pressed: string) => {

Some files were not shown because too many files have changed in this diff Show more