@seafile/sdoc-editor 0.5.79 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basic-sdk/extension/plugins/link/plugin.js +1 -1
- package/dist/basic-sdk/extension/plugins/seatable-tables/formatter/creator-formatter.js +124 -0
- package/dist/basic-sdk/extension/plugins/seatable-tables/formatter/index.js +241 -0
- package/dist/basic-sdk/extension/plugins/seatable-tables/op-menu/index.css +16 -0
- package/dist/basic-sdk/extension/plugins/seatable-tables/op-menu/index.js +17 -0
- package/dist/basic-sdk/extension/plugins/seatable-tables/render-element/index.css +1 -0
- package/dist/basic-sdk/extension/plugins/seatable-tables/render-element/record-item.js +8 -2
- package/dist/basic-sdk/extension/plugins/seatable-tables/render-element/record-list.js +4 -4
- package/dist/basic-sdk/extension/plugins/seatable-tables/render-element/seatable-table.js +78 -17
- package/dist/basic-sdk/extension/plugins/seatable-tables/setting/index.css +1 -0
- package/dist/basic-sdk/extension/plugins/seatable-tables/setting/index.js +6 -0
- package/dist/basic-sdk/extension/plugins/table/helpers.js +1 -0
- package/dist/basic-sdk/extension/toolbar/insert-element-toolbar/index.js +8 -8
- package/dist/basic-sdk/extension/toolbar/side-toolbar/index.js +2 -2
- package/dist/pages/document-plugin-editor.js +2 -2
- package/package.json +2 -1
- package/public/media/dtable-font.css +10 -8
- package/public/media/sdoc-editor-font/iconfont.eot +0 -0
- package/public/media/sdoc-editor-font/iconfont.svg +2 -0
- package/public/media/sdoc-editor-font/iconfont.ttf +0 -0
- package/public/media/sdoc-editor-font/iconfont.woff +0 -0
- package/public/media/sdoc-editor-font/iconfont.woff2 +0 -0
- package/public/media/sdoc-editor-font.css +10 -6
|
@@ -83,7 +83,7 @@ const withLink = editor => {
|
|
|
83
83
|
});
|
|
84
84
|
} else {
|
|
85
85
|
const [firstSelectedNode, ...restNodes] = getSelectedElems(newEditor);
|
|
86
|
-
if (!firstSelectedNode || restNodes) return; // If select more than one node or not select any node, return
|
|
86
|
+
if (!firstSelectedNode || restNodes.length) return; // If select more than one node or not select any node, return
|
|
87
87
|
const isSelectTextNodes = firstSelectedNode.children.some(node => Text.isText(node));
|
|
88
88
|
if (!isSelectTextNodes) return;
|
|
89
89
|
const selectContent = window.getSelection().toString();
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
+
import React, { Component } from 'react';
|
|
3
|
+
import { CreatorFormatter } from 'dtable-ui-component';
|
|
4
|
+
import context from '@/context';
|
|
5
|
+
import { isValidEmail } from '@/utils/common-utils';
|
|
6
|
+
class DtableCreatorFormatter extends Component {
|
|
7
|
+
constructor(_props) {
|
|
8
|
+
super(_props);
|
|
9
|
+
_defineProperty(this, "calculateCollaboratorData", props => {
|
|
10
|
+
const {
|
|
11
|
+
value
|
|
12
|
+
} = props;
|
|
13
|
+
this.getCollaborator(value);
|
|
14
|
+
});
|
|
15
|
+
_defineProperty(this, "getCollaborator", value => {
|
|
16
|
+
if (!value) {
|
|
17
|
+
this.setState({
|
|
18
|
+
isDataLoaded: true,
|
|
19
|
+
collaborator: null
|
|
20
|
+
});
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this.setState({
|
|
24
|
+
isDataLoaded: false,
|
|
25
|
+
collaborator: null
|
|
26
|
+
});
|
|
27
|
+
const {
|
|
28
|
+
collaborators
|
|
29
|
+
} = this.props;
|
|
30
|
+
let collaborator = Array.isArray(collaborators) && collaborators.find(c => c && c.username === value);
|
|
31
|
+
if (collaborator) {
|
|
32
|
+
this.setState({
|
|
33
|
+
isDataLoaded: true,
|
|
34
|
+
collaborator: collaborator
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const mediaUrl = context.getSetting('mediaUrl');
|
|
39
|
+
const defaultAvatarUrl = "".concat(mediaUrl, "/avatars/default.png");
|
|
40
|
+
if (value === 'anonymous') {
|
|
41
|
+
collaborator = {
|
|
42
|
+
name: 'anonymous',
|
|
43
|
+
avatar_url: defaultAvatarUrl
|
|
44
|
+
};
|
|
45
|
+
this.setState({
|
|
46
|
+
isDataLoaded: true,
|
|
47
|
+
collaborator
|
|
48
|
+
});
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
let dtableCollaborators = window.app.collaboratorsCache;
|
|
52
|
+
collaborator = dtableCollaborators[value];
|
|
53
|
+
if (collaborator) {
|
|
54
|
+
this.setState({
|
|
55
|
+
isDataLoaded: true,
|
|
56
|
+
collaborator
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!isValidEmail(value)) {
|
|
61
|
+
collaborator = {
|
|
62
|
+
name: value,
|
|
63
|
+
avatar_url: defaultAvatarUrl
|
|
64
|
+
};
|
|
65
|
+
dtableCollaborators[value] = collaborator;
|
|
66
|
+
this.setState({
|
|
67
|
+
isDataLoaded: true,
|
|
68
|
+
collaborator: collaborator
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
context.getUserCommonInfo(value).then(res => {
|
|
73
|
+
collaborator = res.data;
|
|
74
|
+
dtableCollaborators[value] = collaborator;
|
|
75
|
+
this.setState({
|
|
76
|
+
isDataLoaded: true,
|
|
77
|
+
collaborator: collaborator
|
|
78
|
+
});
|
|
79
|
+
}).catch(() => {
|
|
80
|
+
let mediaUrl = context.getSetting('mediaUrl');
|
|
81
|
+
let defaultAvatarUrl = "".concat(mediaUrl, "/avatars/default.png");
|
|
82
|
+
collaborator = {
|
|
83
|
+
name: value,
|
|
84
|
+
avatar_url: defaultAvatarUrl
|
|
85
|
+
};
|
|
86
|
+
dtableCollaborators[value] = collaborator;
|
|
87
|
+
this.setState({
|
|
88
|
+
isDataLoaded: true,
|
|
89
|
+
collaborator: collaborator
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
this.state = {
|
|
94
|
+
isDataLoaded: false,
|
|
95
|
+
collaborator: null
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
componentDidMount() {
|
|
99
|
+
this.calculateCollaboratorData(this.props);
|
|
100
|
+
}
|
|
101
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
102
|
+
this.calculateCollaboratorData(nextProps);
|
|
103
|
+
}
|
|
104
|
+
render() {
|
|
105
|
+
const {
|
|
106
|
+
isDataLoaded,
|
|
107
|
+
collaborator
|
|
108
|
+
} = this.state;
|
|
109
|
+
const {
|
|
110
|
+
value,
|
|
111
|
+
containerClassName
|
|
112
|
+
} = this.props;
|
|
113
|
+
if (!value || !collaborator) return this.props.renderEmptyFormatter();
|
|
114
|
+
if (isDataLoaded) {
|
|
115
|
+
return /*#__PURE__*/React.createElement(CreatorFormatter, {
|
|
116
|
+
collaborators: [collaborator],
|
|
117
|
+
value: value,
|
|
118
|
+
containerClassName: containerClassName
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return this.props.renderEmptyFormatter();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export default DtableCreatorFormatter;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
2
|
+
import React, { Fragment } from 'react';
|
|
3
|
+
import { TextFormatter, NumberFormatter, CheckboxFormatter, DateFormatter, SingleSelectFormatter, MultipleSelectFormatter, CollaboratorFormatter, ImageFormatter, FileFormatter, SimpleLongTextFormatter, GeolocationFormatter, FormulaFormatter, CTimeFormatter, MTimeFormatter, AutoNumberFormatter, UrlFormatter, EmailFormatter, DurationFormatter, RateFormatter, ButtonFormatter, CreatorFormatter } from 'dtable-ui-component';
|
|
4
|
+
import { CellType, SELECT_OPTION_COLORS } from 'dtable-utils';
|
|
5
|
+
class CellFormatter extends React.Component {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
_defineProperty(this, "renderEmptyFormatter", () => {
|
|
9
|
+
const {
|
|
10
|
+
components
|
|
11
|
+
} = this.props;
|
|
12
|
+
const {
|
|
13
|
+
emptyComponent
|
|
14
|
+
} = components || {};
|
|
15
|
+
return emptyComponent || null;
|
|
16
|
+
});
|
|
17
|
+
_defineProperty(this, "getSelectColumnOptions", column => {
|
|
18
|
+
if (!column || !column.data || !Array.isArray(column.data.options)) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return column.data.options;
|
|
22
|
+
});
|
|
23
|
+
_defineProperty(this, "renderFormatter", () => {
|
|
24
|
+
let {
|
|
25
|
+
column,
|
|
26
|
+
cellValue,
|
|
27
|
+
collaborators,
|
|
28
|
+
isSample
|
|
29
|
+
} = this.props;
|
|
30
|
+
const {
|
|
31
|
+
type: columnType
|
|
32
|
+
} = column || {};
|
|
33
|
+
const containerClassName = "document-".concat(columnType, "-formatter");
|
|
34
|
+
switch (columnType) {
|
|
35
|
+
case CellType.TEXT:
|
|
36
|
+
{
|
|
37
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
38
|
+
return /*#__PURE__*/React.createElement(TextFormatter, {
|
|
39
|
+
value: cellValue,
|
|
40
|
+
containerClassName: containerClassName
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
case CellType.COLLABORATOR:
|
|
44
|
+
{
|
|
45
|
+
// TODO
|
|
46
|
+
if (!Array.isArray(cellValue) || cellValue.length === 0) return this.renderEmptyFormatter();
|
|
47
|
+
cellValue = cellValue.filter(item => item);
|
|
48
|
+
if (cellValue.length === 0) return this.renderEmptyFormatter();
|
|
49
|
+
return /*#__PURE__*/React.createElement(CollaboratorFormatter, {
|
|
50
|
+
value: cellValue,
|
|
51
|
+
collaborators: collaborators,
|
|
52
|
+
containerClassName: containerClassName
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
case CellType.LONG_TEXT:
|
|
56
|
+
{
|
|
57
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
58
|
+
return /*#__PURE__*/React.createElement(SimpleLongTextFormatter, {
|
|
59
|
+
value: cellValue,
|
|
60
|
+
containerClassName: containerClassName
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
case CellType.IMAGE:
|
|
64
|
+
{
|
|
65
|
+
if (!cellValue || Array.isArray(cellValue) && cellValue.length === 0) return this.renderEmptyFormatter();
|
|
66
|
+
return /*#__PURE__*/React.createElement(ImageFormatter, {
|
|
67
|
+
value: cellValue,
|
|
68
|
+
isSample: isSample,
|
|
69
|
+
containerClassName: containerClassName
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
case CellType.FILE:
|
|
73
|
+
{
|
|
74
|
+
if (!cellValue || Array.isArray(cellValue) && cellValue.length === 0) return this.renderEmptyFormatter();
|
|
75
|
+
return /*#__PURE__*/React.createElement(FileFormatter, {
|
|
76
|
+
value: cellValue,
|
|
77
|
+
isSample: isSample,
|
|
78
|
+
containerClassName: containerClassName
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
case CellType.GEOLOCATION:
|
|
82
|
+
{
|
|
83
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
84
|
+
return /*#__PURE__*/React.createElement(GeolocationFormatter, {
|
|
85
|
+
value: cellValue,
|
|
86
|
+
containerClassName: containerClassName
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
case CellType.NUMBER:
|
|
90
|
+
{
|
|
91
|
+
if (!cellValue && cellValue !== 0) return this.renderEmptyFormatter();
|
|
92
|
+
return /*#__PURE__*/React.createElement(NumberFormatter, {
|
|
93
|
+
value: cellValue,
|
|
94
|
+
data: column.data,
|
|
95
|
+
containerClassName: containerClassName
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
case CellType.DATE:
|
|
99
|
+
{
|
|
100
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
101
|
+
return /*#__PURE__*/React.createElement(DateFormatter, {
|
|
102
|
+
value: cellValue,
|
|
103
|
+
format: column.data.format,
|
|
104
|
+
containerClassName: containerClassName
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
case CellType.MULTIPLE_SELECT:
|
|
108
|
+
{
|
|
109
|
+
if (!cellValue || cellValue.length === 0) return this.renderEmptyFormatter();
|
|
110
|
+
const options = column.data && column.data.options || [];
|
|
111
|
+
return /*#__PURE__*/React.createElement(MultipleSelectFormatter, {
|
|
112
|
+
value: cellValue,
|
|
113
|
+
options: options,
|
|
114
|
+
containerClassName: containerClassName
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
case CellType.SINGLE_SELECT:
|
|
118
|
+
{
|
|
119
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
120
|
+
const options = this.getSelectColumnOptions(column);
|
|
121
|
+
if (options.length === 0) return this.renderEmptyFormatter();
|
|
122
|
+
return /*#__PURE__*/React.createElement(SingleSelectFormatter, {
|
|
123
|
+
value: cellValue,
|
|
124
|
+
options: options,
|
|
125
|
+
containerClassName: containerClassName
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
case CellType.CHECKBOX:
|
|
129
|
+
{
|
|
130
|
+
return /*#__PURE__*/React.createElement(CheckboxFormatter, {
|
|
131
|
+
value: cellValue,
|
|
132
|
+
containerClassName: containerClassName
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
case CellType.CTIME:
|
|
136
|
+
{
|
|
137
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
138
|
+
return /*#__PURE__*/React.createElement(CTimeFormatter, {
|
|
139
|
+
value: cellValue,
|
|
140
|
+
containerClassName: containerClassName
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
case CellType.MTIME:
|
|
144
|
+
{
|
|
145
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
146
|
+
return /*#__PURE__*/React.createElement(MTimeFormatter, {
|
|
147
|
+
value: cellValue,
|
|
148
|
+
containerClassName: containerClassName
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
case CellType.CREATOR:
|
|
152
|
+
case CellType.LAST_MODIFIER:
|
|
153
|
+
{
|
|
154
|
+
// TODO
|
|
155
|
+
return /*#__PURE__*/React.createElement(CreatorFormatter, {
|
|
156
|
+
value: cellValue,
|
|
157
|
+
collaborators: collaborators,
|
|
158
|
+
containerClassName: containerClassName,
|
|
159
|
+
renderEmptyFormatter: this.renderEmptyFormatter
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
case CellType.FORMULA:
|
|
163
|
+
case CellType.LINK_FORMULA:
|
|
164
|
+
{
|
|
165
|
+
if (!cellValue && cellValue !== 0 && cellValue !== false) return this.renderEmptyFormatter();
|
|
166
|
+
return /*#__PURE__*/React.createElement(FormulaFormatter, {
|
|
167
|
+
value: cellValue,
|
|
168
|
+
column: column,
|
|
169
|
+
collaborators: collaborators,
|
|
170
|
+
containerClassName: containerClassName
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
case CellType.LINK:
|
|
174
|
+
{
|
|
175
|
+
// TODO
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
case CellType.AUTO_NUMBER:
|
|
179
|
+
{
|
|
180
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
181
|
+
return /*#__PURE__*/React.createElement(AutoNumberFormatter, {
|
|
182
|
+
value: cellValue,
|
|
183
|
+
containerClassName: containerClassName
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
case CellType.URL:
|
|
187
|
+
{
|
|
188
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
189
|
+
return /*#__PURE__*/React.createElement(UrlFormatter, {
|
|
190
|
+
value: cellValue,
|
|
191
|
+
containerClassName: containerClassName
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
case CellType.EMAIL:
|
|
195
|
+
{
|
|
196
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
197
|
+
return /*#__PURE__*/React.createElement(EmailFormatter, {
|
|
198
|
+
value: cellValue,
|
|
199
|
+
containerClassName: containerClassName
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
case CellType.DURATION:
|
|
203
|
+
{
|
|
204
|
+
var _column$data;
|
|
205
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
206
|
+
return /*#__PURE__*/React.createElement(DurationFormatter, {
|
|
207
|
+
value: cellValue,
|
|
208
|
+
format: column === null || column === void 0 ? void 0 : (_column$data = column.data) === null || _column$data === void 0 ? void 0 : _column$data.duration_format,
|
|
209
|
+
containerClassName: containerClassName
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
case CellType.RATE:
|
|
213
|
+
{
|
|
214
|
+
if (!cellValue) return this.renderEmptyFormatter();
|
|
215
|
+
return /*#__PURE__*/React.createElement(RateFormatter, {
|
|
216
|
+
value: cellValue,
|
|
217
|
+
data: column.data || {},
|
|
218
|
+
containerClassName: containerClassName
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
case CellType.BUTTON:
|
|
222
|
+
{
|
|
223
|
+
return /*#__PURE__*/React.createElement(ButtonFormatter, {
|
|
224
|
+
data: column.data || {},
|
|
225
|
+
containerClassName: containerClassName,
|
|
226
|
+
optionColors: SELECT_OPTION_COLORS
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
default:
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
render() {
|
|
235
|
+
return /*#__PURE__*/React.createElement(Fragment, null, this.renderFormatter());
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
CellFormatter.defaultProps = {
|
|
239
|
+
isSample: true
|
|
240
|
+
};
|
|
241
|
+
export default CellFormatter;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.seatable-op-menu {
|
|
2
|
+
position: absolute;
|
|
3
|
+
padding: 7px;
|
|
4
|
+
height: 36px;
|
|
5
|
+
background-color: #fff;
|
|
6
|
+
border: 1px solid #eee;
|
|
7
|
+
border-radius: 3px;
|
|
8
|
+
z-index: 100;
|
|
9
|
+
display: flex;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.seatable-op-menu .sdocfont {
|
|
13
|
+
font-size: 12px;
|
|
14
|
+
color: #444;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { ElementPopover } from '../../../commons';
|
|
3
|
+
import './index.css';
|
|
4
|
+
export default function OpMenu(_ref) {
|
|
5
|
+
let {
|
|
6
|
+
editor,
|
|
7
|
+
element,
|
|
8
|
+
menuPosition
|
|
9
|
+
} = _ref;
|
|
10
|
+
const [isShowSettingPanel, setIsShowSettingPanel] = useState(false);
|
|
11
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ElementPopover, null, /*#__PURE__*/React.createElement("div", {
|
|
12
|
+
className: "seatable-op-menu",
|
|
13
|
+
style: menuPosition
|
|
14
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
15
|
+
className: "sdocfont sdoc-settings"
|
|
16
|
+
}))));
|
|
17
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { getColumnWidth } from '../../seatable-column/helpers';
|
|
3
|
+
import Formatter from '../formatter';
|
|
3
4
|
export default function RecordItem(_ref) {
|
|
4
5
|
let {
|
|
5
6
|
record,
|
|
6
7
|
columns,
|
|
7
|
-
|
|
8
|
+
editor
|
|
8
9
|
} = _ref;
|
|
9
10
|
return /*#__PURE__*/React.createElement("tr", {
|
|
10
11
|
className: "seatable-view-body-column-row"
|
|
@@ -16,6 +17,11 @@ export default function RecordItem(_ref) {
|
|
|
16
17
|
style: {
|
|
17
18
|
width
|
|
18
19
|
}
|
|
19
|
-
},
|
|
20
|
+
}, /*#__PURE__*/React.createElement(Formatter, {
|
|
21
|
+
isSample: true,
|
|
22
|
+
column: column,
|
|
23
|
+
cellValue: record[column.key],
|
|
24
|
+
collaborators: editor.collaborators
|
|
25
|
+
}));
|
|
20
26
|
}));
|
|
21
27
|
}
|
|
@@ -2,16 +2,16 @@ import React from 'react';
|
|
|
2
2
|
import RecordItem from './record-item';
|
|
3
3
|
export default function RecordList(_ref) {
|
|
4
4
|
let {
|
|
5
|
+
editor,
|
|
5
6
|
records,
|
|
6
|
-
columns
|
|
7
|
-
getTableCellValue
|
|
7
|
+
columns
|
|
8
8
|
} = _ref;
|
|
9
9
|
return /*#__PURE__*/React.createElement("tbody", null, records.map(record => {
|
|
10
10
|
return /*#__PURE__*/React.createElement(RecordItem, {
|
|
11
11
|
key: record._id,
|
|
12
|
+
editor: editor,
|
|
12
13
|
record: record,
|
|
13
|
-
columns: columns
|
|
14
|
-
getTableCellValue: getTableCellValue
|
|
14
|
+
columns: columns
|
|
15
15
|
});
|
|
16
16
|
}));
|
|
17
17
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useEffect,
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { useReadOnly, useSelected } from '@seafile/slate-react';
|
|
@@ -6,6 +6,8 @@ import Loading from '../../../../../components/loading';
|
|
|
6
6
|
import RecordHeader from './record-header';
|
|
7
7
|
import RecordList from './record-list';
|
|
8
8
|
import './index.css';
|
|
9
|
+
import OpMenu from '../op-menu';
|
|
10
|
+
import { useScrollContext } from '../../../../hooks/use-scroll-context';
|
|
9
11
|
function SeaTableTable(_ref) {
|
|
10
12
|
let {
|
|
11
13
|
element,
|
|
@@ -14,8 +16,9 @@ function SeaTableTable(_ref) {
|
|
|
14
16
|
children,
|
|
15
17
|
editor
|
|
16
18
|
} = _ref;
|
|
19
|
+
const scrollRef = useScrollContext();
|
|
17
20
|
const isSelected = useSelected();
|
|
18
|
-
const
|
|
21
|
+
const readOnly = useReadOnly();
|
|
19
22
|
const [isLoading, setIsLoading] = useState(true);
|
|
20
23
|
const [columns, setColumns] = useState([]);
|
|
21
24
|
const [records, setRecords] = useState([]);
|
|
@@ -24,6 +27,14 @@ function SeaTableTable(_ref) {
|
|
|
24
27
|
const {
|
|
25
28
|
t
|
|
26
29
|
} = useTranslation();
|
|
30
|
+
|
|
31
|
+
// menu control
|
|
32
|
+
const seaTableRef = useRef(null);
|
|
33
|
+
const [isShowMenu, setIsShowMenu] = useState(false);
|
|
34
|
+
const [menuPosition, setMenuPosition] = useState({
|
|
35
|
+
top: '',
|
|
36
|
+
left: ''
|
|
37
|
+
});
|
|
27
38
|
useEffect(() => {
|
|
28
39
|
const {
|
|
29
40
|
table_id
|
|
@@ -31,26 +42,77 @@ function SeaTableTable(_ref) {
|
|
|
31
42
|
const table = editor.getTableById(table_id);
|
|
32
43
|
setColumns(table.columns);
|
|
33
44
|
const records = table.rows;
|
|
34
|
-
const isShowTipMessage =
|
|
35
|
-
const shownRecords =
|
|
45
|
+
const isShowTipMessage = readOnly ? records.length > 200 : records.length > 10;
|
|
46
|
+
const shownRecords = readOnly ? records.slice(0, 200) : records.slice(0, 10);
|
|
36
47
|
setIsShowTipMessage(isShowTipMessage);
|
|
37
48
|
setRecords(records);
|
|
38
49
|
setShownRecords(shownRecords);
|
|
39
50
|
setIsLoading(false);
|
|
51
|
+
|
|
40
52
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
-
}, [element,
|
|
53
|
+
}, [element, readOnly]);
|
|
54
|
+
const handleScroll = useCallback(e => {
|
|
55
|
+
if (readOnly) return;
|
|
56
|
+
if (!isShowMenu) return;
|
|
57
|
+
if (e.currentTarget.scrollTop) {
|
|
58
|
+
const {
|
|
59
|
+
top,
|
|
60
|
+
left
|
|
61
|
+
} = seaTableRef.current.getBoundingClientRect();
|
|
62
|
+
const menuTop = top - 36; // top = top distance - menu height
|
|
63
|
+
const newMenuPosition = {
|
|
64
|
+
top: menuTop,
|
|
65
|
+
left: left // left = code-block left distance
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
setMenuPosition(newMenuPosition);
|
|
69
|
+
}
|
|
70
|
+
}, [isShowMenu, readOnly]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (readOnly) return;
|
|
73
|
+
let observerRefValue = null;
|
|
74
|
+
if (scrollRef.current) {
|
|
75
|
+
scrollRef.current.addEventListener('scroll', handleScroll);
|
|
76
|
+
observerRefValue = scrollRef.current;
|
|
77
|
+
}
|
|
78
|
+
return () => {
|
|
79
|
+
observerRefValue.removeEventListener('scroll', handleScroll);
|
|
80
|
+
};
|
|
81
|
+
}, [handleScroll, readOnly, scrollRef]);
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (!isSelected) {
|
|
84
|
+
setIsShowMenu(false);
|
|
85
|
+
}
|
|
86
|
+
}, [isSelected]);
|
|
87
|
+
const onTableClick = useCallback(event => {
|
|
88
|
+
if (readOnly) return;
|
|
89
|
+
const {
|
|
90
|
+
top,
|
|
91
|
+
left
|
|
92
|
+
} = seaTableRef.current.getBoundingClientRect();
|
|
93
|
+
const menuTop = top - 36; // top = top distance - menu height
|
|
94
|
+
const newMenuPosition = {
|
|
95
|
+
top: menuTop,
|
|
96
|
+
left: left // left = callout left distance
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
setMenuPosition(newMenuPosition);
|
|
100
|
+
setIsShowMenu(true);
|
|
101
|
+
}, [readOnly]);
|
|
42
102
|
const containerClass = classNames('seatable-view-container', {
|
|
43
103
|
selected: isSelected
|
|
44
104
|
});
|
|
45
|
-
const getTableCellValue = useCallback((row, column) => {
|
|
46
|
-
const {
|
|
47
|
-
table_id
|
|
48
|
-
} = element;
|
|
49
|
-
return editor.getTableCellValue(table_id, row, column);
|
|
50
|
-
}, [editor, element]);
|
|
51
105
|
return /*#__PURE__*/React.createElement("div", Object.assign({}, attributes, {
|
|
52
|
-
className:
|
|
106
|
+
className: "seatable-table-wrapper",
|
|
53
107
|
contentEditable: false
|
|
108
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
109
|
+
ref: seaTableRef,
|
|
110
|
+
className: containerClass,
|
|
111
|
+
onClick: onTableClick
|
|
112
|
+
}, isShowMenu && /*#__PURE__*/React.createElement(OpMenu, {
|
|
113
|
+
editor: editor,
|
|
114
|
+
element: element,
|
|
115
|
+
menuPosition: menuPosition
|
|
54
116
|
}), isLoading && /*#__PURE__*/React.createElement(Loading, null), !isLoading && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("table", {
|
|
55
117
|
className: "seatable-view-records"
|
|
56
118
|
}, /*#__PURE__*/React.createElement(RecordHeader, {
|
|
@@ -58,14 +120,13 @@ function SeaTableTable(_ref) {
|
|
|
58
120
|
}), /*#__PURE__*/React.createElement(RecordList, {
|
|
59
121
|
editor: editor,
|
|
60
122
|
records: shownRecords,
|
|
61
|
-
columns: columns
|
|
62
|
-
|
|
63
|
-
})), !isReadOnly && isShowTipMessage && /*#__PURE__*/React.createElement("div", {
|
|
123
|
+
columns: columns
|
|
124
|
+
})), !readOnly && isShowTipMessage && /*#__PURE__*/React.createElement("div", {
|
|
64
125
|
className: "d-print-none ml-2 m-2"
|
|
65
126
|
}, t('And_x_more_records', {
|
|
66
127
|
count: records.length - 10
|
|
67
|
-
})),
|
|
128
|
+
})), readOnly && isShowTipMessage && /*#__PURE__*/React.createElement("div", {
|
|
68
129
|
className: "d-print-none ml-2 m-2"
|
|
69
|
-
}, t('Print_limit_exceeded'))), children);
|
|
130
|
+
}, t('Print_limit_exceeded'))), children));
|
|
70
131
|
}
|
|
71
132
|
export default SeaTableTable;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.seatable-setting-container {}
|
|
@@ -30,6 +30,7 @@ const QuickInsertBlockMenu = _ref => {
|
|
|
30
30
|
const renderItemListRef = useRef([]);
|
|
31
31
|
const downDownWrapperRef = useRef(null);
|
|
32
32
|
const onInsertImageToggle = useCallback(() => {
|
|
33
|
+
callback && callback();
|
|
33
34
|
const eventBus = EventBus.getInstance();
|
|
34
35
|
if (insertPosition === INSERT_POSITION.CURRENT) {
|
|
35
36
|
Transforms.select(editor, editor.selection.focus);
|
|
@@ -39,47 +40,47 @@ const QuickInsertBlockMenu = _ref => {
|
|
|
39
40
|
insertPosition,
|
|
40
41
|
slateNode
|
|
41
42
|
});
|
|
42
|
-
callback && callback();
|
|
43
43
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
44
44
|
}, [editor, insertPosition]);
|
|
45
45
|
const createTable = useCallback(size => {
|
|
46
|
+
callback && callback();
|
|
46
47
|
const newInsertPosition = slateNode.type === ELEMENT_TYPE.LIST_ITEM ? INSERT_POSITION.AFTER : insertPosition;
|
|
47
48
|
insertTable(editor, size, editor.selection, newInsertPosition);
|
|
48
|
-
callback && callback();
|
|
49
49
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
50
|
}, [editor, insertPosition, slateNode]);
|
|
51
51
|
const openLinkDialog = useCallback(() => {
|
|
52
|
+
callback && callback();
|
|
52
53
|
const eventBus = EventBus.getInstance();
|
|
53
54
|
eventBus.dispatch(INTERNAL_EVENT.INSERT_ELEMENT, {
|
|
54
55
|
type: ELEMENT_TYPE.LINK,
|
|
55
56
|
insertPosition,
|
|
56
57
|
slateNode
|
|
57
58
|
});
|
|
58
|
-
callback && callback();
|
|
59
59
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
60
|
}, [insertPosition]);
|
|
61
61
|
const onInsertCodeBlock = useCallback(() => {
|
|
62
|
+
callback && callback();
|
|
62
63
|
const newInsertPosition = slateNode.type === ELEMENT_TYPE.LIST_ITEM ? INSERT_POSITION.AFTER : insertPosition;
|
|
63
64
|
changeToCodeBlock(editor, 'plaintext', newInsertPosition);
|
|
64
|
-
callback && callback();
|
|
65
65
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
66
66
|
}, [editor, insertPosition, slateNode]);
|
|
67
67
|
const onInsertList = useCallback(type => {
|
|
68
|
-
toggleList(editor, type, insertPosition);
|
|
69
68
|
callback && callback();
|
|
69
|
+
toggleList(editor, type, insertPosition);
|
|
70
70
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
71
|
}, [editor, insertPosition, slateNode]);
|
|
72
72
|
const onInsertCheckList = useCallback(() => {
|
|
73
|
-
setCheckListItemType(editor, ELEMENT_TYPE.CHECK_LIST_ITEM, insertPosition);
|
|
74
73
|
callback && callback();
|
|
74
|
+
setCheckListItemType(editor, ELEMENT_TYPE.CHECK_LIST_ITEM, insertPosition);
|
|
75
75
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
76
|
}, [editor, insertPosition, slateNode]);
|
|
77
77
|
const onInsert = useCallback(type => {
|
|
78
|
-
insertElement(editor, type, insertPosition);
|
|
79
78
|
callback && callback();
|
|
79
|
+
insertElement(editor, type, insertPosition);
|
|
80
80
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
81
81
|
}, [editor, insertPosition, slateNode]);
|
|
82
82
|
const onInsertCallout = useCallback(type => {
|
|
83
|
+
callback && callback();
|
|
83
84
|
if (insertPosition === INSERT_POSITION.CURRENT) {
|
|
84
85
|
wrapCallout(editor);
|
|
85
86
|
Transforms.removeNodes(editor, {
|
|
@@ -89,7 +90,6 @@ const QuickInsertBlockMenu = _ref => {
|
|
|
89
90
|
insertElement(editor, type, insertPosition);
|
|
90
91
|
wrapCallout(editor);
|
|
91
92
|
}
|
|
92
|
-
callback && callback();
|
|
93
93
|
}, [callback, editor, insertPosition]);
|
|
94
94
|
const isDisableCallout = useMemo(() => {
|
|
95
95
|
const callout = getAboveBlockNode(editor, {
|
|
@@ -33,9 +33,9 @@ const SideToolbar = () => {
|
|
|
33
33
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
34
|
}, []);
|
|
35
35
|
const handleClick = useCallback(e => {
|
|
36
|
-
if (!isShowSideMenu) return;
|
|
36
|
+
if (!isShowSideMenu || !menuRef.current) return;
|
|
37
37
|
const isClickSideTool = menuRef.current.contains(e.target);
|
|
38
|
-
if (isClickSideTool) return;
|
|
38
|
+
if (isClickSideTool || !sideMenuRef.current) return;
|
|
39
39
|
const {
|
|
40
40
|
sideMenuDom
|
|
41
41
|
} = sideMenuRef.current;
|
|
@@ -21,7 +21,7 @@ const DocumentPluginEditor = _ref => {
|
|
|
21
21
|
getColumnCellValue,
|
|
22
22
|
tables,
|
|
23
23
|
getTableById,
|
|
24
|
-
|
|
24
|
+
collaborators
|
|
25
25
|
} = _ref;
|
|
26
26
|
context.initApi();
|
|
27
27
|
const forceUpdate = useForceUpdate();
|
|
@@ -47,7 +47,7 @@ const DocumentPluginEditor = _ref => {
|
|
|
47
47
|
// insert table
|
|
48
48
|
newEditor.tables = tables || [];
|
|
49
49
|
newEditor.getTableById = getTableById;
|
|
50
|
-
newEditor.
|
|
50
|
+
newEditor.collaborators = collaborators;
|
|
51
51
|
newEditor.cursors = cursors || {};
|
|
52
52
|
newEditor.width = PAGE_EDIT_AREA_WIDTH; // default width
|
|
53
53
|
newEditor.editorType = DOCUMENT_PLUGIN_EDITOR;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/sdoc-editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"copy-to-clipboard": "^3.3.3",
|
|
17
17
|
"dayjs": "1.11.2",
|
|
18
18
|
"deep-copy": "1.4.2",
|
|
19
|
+
"dtable-ui-component": "^4.4.36",
|
|
19
20
|
"goober": "2.1.13",
|
|
20
21
|
"is-hotkey": "0.2.0",
|
|
21
22
|
"is-url": "^1.2.4",
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
@font-face {
|
|
2
|
-
font-family: "dtable-font";
|
|
3
|
-
|
|
4
|
-
src: url('./dtable-fonts/dtable-font.eot?t=1691034193364
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
font-family: "dtable-font";
|
|
3
|
+
/* Project id 1206632 */
|
|
4
|
+
src: url('./dtable-fonts/dtable-font.eot?t=1691034193364');
|
|
5
|
+
/* IE9 */
|
|
6
|
+
src: url('./dtable-fonts/dtable-font.eot?t=1691034193364#iefix') format('embedded-opentype'),
|
|
7
|
+
/* IE6-IE8 */
|
|
8
|
+
url('./dtable-fonts/dtable-font.woff2?t=1691034193364') format('woff2'),
|
|
9
|
+
url('./dtable-fonts/dtable-font.woff?t=1691034193364') format('woff'),
|
|
10
|
+
url('./dtable-fonts/dtable-font.ttf?t=1691034193364') format('truetype'),
|
|
11
|
+
url('./dtable-fonts/dtable-font.svg?t=1691034193364#dtable-font') format('svg');
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
.dtable-font {
|
|
@@ -1563,4 +1566,3 @@
|
|
|
1563
1566
|
.dtable-icon-calendar-alt-solid:before {
|
|
1564
1567
|
content: "\e622";
|
|
1565
1568
|
}
|
|
1566
|
-
|
|
Binary file
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
/>
|
|
15
15
|
<missing-glyph />
|
|
16
16
|
|
|
17
|
+
<glyph glyph-name="sdoc-settings" unicode="" d="M976 467.2c3.2-3.2 3.2-3.2 3.2-9.6L976 326.4c0-3.2-3.2-12.8-9.6-12.8l-108.8-38.4c-3.2-12.8-12.8-28.8-19.2-41.6l51.2-102.4c0-3.2 0-12.8-3.2-19.2l-96-96c-3.2-3.2-12.8-9.6-19.2-3.2L668.8 64c-12.8-9.6-28.8-12.8-41.6-19.2L588.8-64c0-3.2-3.2-9.6-12.8-9.6H444.8c-3.2 0-12.8 3.2-12.8 9.6l-38.4 108.8c-12.8 3.2-28.8 12.8-41.6 19.2l-102.4-51.2c-3.2 0-12.8 0-19.2 3.2l-96 96c-6.4 0-12.8 9.6-6.4 16l51.2 102.4c-9.6 12.8-12.8 28.8-19.2 41.6L51.2 310.4c-3.2 0-9.6 3.2-9.6 12.8V454.4c0 3.2 3.2 12.8 9.6 12.8L160 508.8c3.2 12.8 9.6 28.8 19.2 41.6L128 656c-6.4 6.4-6.4 12.8 0 12.8l96 96c3.2 9.6 9.6 9.6 16 3.2l102.4-51.2c12.8 9.6 28.8 12.8 41.6 19.2l38.4 112c0 3.2 3.2 9.6 12.8 9.6h128c3.2 0 12.8-3.2 12.8-9.6l38.4-108.8c12.8-3.2 28.8-12.8 41.6-19.2l102.4 51.2c3.2 0 12.8 0 19.2-3.2l96-96c3.2-3.2 9.6-12.8 3.2-19.2l-51.2-102.4c9.6-12.8 12.8-28.8 19.2-41.6L976 467.2zM566.4 614.4c-176 48-329.6-108.8-288-288 19.2-76.8 86.4-140.8 160-160 176-48 329.6 108.8 288 288-19.2 80-80 140.8-160 160z" horiz-adv-x="1024" />
|
|
18
|
+
|
|
17
19
|
<glyph glyph-name="sdoc-seatable-table" unicode="" d="M384 896c35.2 0 64-28.8 64-64v-320c0-35.2-28.8-64-64-64H64c-35.2 0-64 28.8-64 64V832C0 867.2 28.8 896 64 896h320z m-32-96H96v-256h256V800z m608 96c35.2 0 64-28.8 64-64v-320c0-35.2-28.8-64-64-64H640c-35.2 0-64 28.8-64 64V832c0 35.2 28.8 64 64 64h320z m-32-96h-256v-256h256V800zM384 320c35.2 0 64-28.8 64-64v-320c0-35.2-28.8-64-64-64H64c-35.2 0-64 28.8-64 64V256c0 35.2 28.8 64 64 64h320z m-32-96H96v-256h256v256z m608 96c35.2 0 64-28.8 64-64v-320c0-35.2-28.8-64-64-64H640c-35.2 0-64 28.8-64 64V256c0 35.2 28.8 64 64 64h320z m-32-96h-256v-256h256v256z" horiz-adv-x="1024" />
|
|
18
20
|
|
|
19
21
|
<glyph glyph-name="sdoc-more-vertical-left" unicode="" d="M703.629257 704.370743c-54.294956 0-95.814629 41.519672-95.814628 95.814628s41.519672 95.814629 95.814628 95.814629 95.814629-41.519672 95.814629-95.814629-41.519672-95.814629-95.814629-95.814628z m0-415.196724c-54.294956 0-95.814629 41.519672-95.814628 95.814628s41.519672 95.814629 95.814628 95.814629 95.814629-41.519672 95.814629-95.814629-41.519672-95.814629-95.814629-95.814628z m0-415.196724c-54.294956 0-95.814629 41.519672-95.814628 95.814628s41.519672 95.814629 95.814628 95.814629 95.814629-41.519672 95.814629-95.814629-41.519672-95.814629-95.814629-95.814628zM310.78928 857.674149L16.957752 432.895962c-19.162926-28.744389-19.162926-76.651703 0-105.396092L310.78928-94.084496c19.162926-28.744389 60.682598-44.713493 89.426987-25.550568 28.744389 22.356747 38.325851 63.876419 19.162925 92.620808L125.547665 381.794826l287.443885 405.615262c25.550568 35.13203 25.550568 73.457882-12.775283 95.814628s-67.07024 3.193821-89.426987-25.550567z" horiz-adv-x="1024" />
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
@font-face {
|
|
2
2
|
font-family: "sdocfont";
|
|
3
3
|
/* Project id 4097705 */
|
|
4
|
-
src: url('./sdoc-editor-font/iconfont.eot?t=
|
|
4
|
+
src: url('./sdoc-editor-font/iconfont.eot?t=1719382079268');
|
|
5
5
|
/* IE9 */
|
|
6
|
-
src: url('./sdoc-editor-font/iconfont.eot?t=
|
|
6
|
+
src: url('./sdoc-editor-font/iconfont.eot?t=1719382079268#iefix') format('embedded-opentype'),
|
|
7
7
|
/* IE6-IE8 */
|
|
8
|
-
url('./sdoc-editor-font/iconfont.woff2?t=
|
|
9
|
-
url('./sdoc-editor-font/iconfont.woff?t=
|
|
10
|
-
url('./sdoc-editor-font/iconfont.ttf?t=
|
|
11
|
-
url('./sdoc-editor-font/iconfont.svg?t=
|
|
8
|
+
url('./sdoc-editor-font/iconfont.woff2?t=1719382079268') format('woff2'),
|
|
9
|
+
url('./sdoc-editor-font/iconfont.woff?t=1719382079268') format('woff'),
|
|
10
|
+
url('./sdoc-editor-font/iconfont.ttf?t=1719382079268') format('truetype'),
|
|
11
|
+
url('./sdoc-editor-font/iconfont.svg?t=1719382079268#sdocfont') format('svg');
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.sdocfont {
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
-moz-osx-font-smoothing: grayscale;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
.sdoc-settings:before {
|
|
23
|
+
content: "\e671";
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
.sdoc-seatable-table:before {
|
|
23
27
|
content: "\e66f";
|
|
24
28
|
}
|