mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-02-19 13:38:06 +01:00
This commit is contained in:
parent
ec4da7cde7
commit
c8ea33c5ce
13 changed files with 372 additions and 245 deletions
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"checked": "Checked",
|
||||||
|
"unchecked": "Unchecked",
|
||||||
|
"percentChecked": "Percent checked",
|
||||||
|
"percentUnchecked": "Percent unchecked",
|
||||||
|
"checkbox": "Checkbox",
|
||||||
"copyInline": "Copy inline element",
|
"copyInline": "Copy inline element",
|
||||||
"unsplit": "Unsplit",
|
"unsplit": "Unsplit",
|
||||||
"unsplitAll": "Unsplit All",
|
"unsplitAll": "Unsplit All",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"checked": "marcado",
|
||||||
|
"unchecked": "desmarcado",
|
||||||
|
"percentChecked": "Porcentaje comprobado",
|
||||||
|
"percentUnchecked": "Porcentaje no marcado",
|
||||||
|
"checkbox": "Casilla de verificación",
|
||||||
"copyInline": "Copiar elemento en línea",
|
"copyInline": "Copiar elemento en línea",
|
||||||
"unsplit": "Desdividir",
|
"unsplit": "Desdividir",
|
||||||
"unsplitAll": "Desdividir Todo",
|
"unsplitAll": "Desdividir Todo",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"checked": "Coché",
|
||||||
|
"unchecked": "Décoché",
|
||||||
|
"percentChecked": "Pourcentage vérifié",
|
||||||
|
"percentUnchecked": "Pourcentage non coché",
|
||||||
|
"checkbox": "case à cocher",
|
||||||
"copyInline": "Copier l'élément en ligne",
|
"copyInline": "Copier l'élément en ligne",
|
||||||
"unsplit": "Unsplit",
|
"unsplit": "Unsplit",
|
||||||
"unsplitAll": "Tout dédiviser",
|
"unsplitAll": "Tout dédiviser",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"checked": "已完成",
|
||||||
|
"unchecked": "未完成",
|
||||||
|
"percentChecked": "已完成佔比",
|
||||||
|
"percentUnchecked": "未完成佔比",
|
||||||
|
"checkbox": "勾選方塊",
|
||||||
"copyInline": "複製行級元素",
|
"copyInline": "複製行級元素",
|
||||||
"unsplit": "取消分割畫面",
|
"unsplit": "取消分割畫面",
|
||||||
"unsplitAll": "取消全部分螢幕",
|
"unsplitAll": "取消全部分螢幕",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"checked": "已完成",
|
||||||
|
"unchecked": "未完成",
|
||||||
|
"percentChecked": "已完成占比",
|
||||||
|
"percentUnchecked": "未完成占比",
|
||||||
|
"checkbox": "勾选框",
|
||||||
"copyInline": "复制行级元素",
|
"copyInline": "复制行级元素",
|
||||||
"unsplit": "取消分屏",
|
"unsplit": "取消分屏",
|
||||||
"unsplitAll": "取消全部分屏",
|
"unsplitAll": "取消全部分屏",
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&--select {
|
&--select {
|
||||||
&:not(.av__row--header) .av__cell {
|
&:not(.av__row--header) .av__cell,
|
||||||
|
&:not(.av__row--header) .av__firstcol {
|
||||||
background-color: var(--b3-av-background-hl);
|
background-color: var(--b3-av-background-hl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,7 +232,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
top: 8px;
|
top: 5.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.dragover__right {
|
&.dragover__right {
|
||||||
|
|
@ -267,15 +268,15 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
& > .av__cellicon {
|
&__cellheadericon {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
color: var(--b3-theme-on-surface);
|
color: var(--b3-theme-on-surface);
|
||||||
margin: 0 5px 0 0;
|
margin: 0 5px 0 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__celltext {
|
&__celltext {
|
||||||
|
|
@ -292,15 +293,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__checkbox {
|
||||||
|
color: var(--b3-theme-on-surface);
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
float: left;
|
||||||
|
padding: 4.5px 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--b3-theme-on-background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__firstcol {
|
&__firstcol {
|
||||||
svg {
|
svg {
|
||||||
color: var(--b3-theme-on-surface);
|
@extend .av__checkbox;
|
||||||
height: 33px;
|
|
||||||
width: 24px;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
padding: 5px;
|
padding: 9.5px 5px;
|
||||||
box-sizing: border-box;
|
|
||||||
float: left;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover svg {
|
&:hover svg {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../
|
||||||
import {transaction} from "../../wysiwyg/transaction";
|
import {transaction} from "../../wysiwyg/transaction";
|
||||||
import {openEditorTab} from "../../../menus/util";
|
import {openEditorTab} from "../../../menus/util";
|
||||||
import {copySubMenu} from "../../../menus/commonMenuItem";
|
import {copySubMenu} from "../../../menus/commonMenuItem";
|
||||||
import {getTypeByCellElement, openCalcMenu, popTextCell} from "./cell";
|
import {getTypeByCellElement, popTextCell} from "./cell";
|
||||||
import {getColIconByType, showColMenu} from "./col";
|
import {getColIconByType, showColMenu} from "./col";
|
||||||
import {insertAttrViewBlockAnimation, updateHeader} from "./row";
|
import {insertAttrViewBlockAnimation, updateHeader} from "./row";
|
||||||
import {emitOpenMenu} from "../../../plugin/EventBus";
|
import {emitOpenMenu} from "../../../plugin/EventBus";
|
||||||
|
|
@ -23,6 +23,7 @@ import {getSearch} from "../../../util/functions";
|
||||||
import {unicode2Emoji} from "../../../emoji";
|
import {unicode2Emoji} from "../../../emoji";
|
||||||
import {selectRow} from "./row";
|
import {selectRow} from "./row";
|
||||||
import * as dayjs from "dayjs";
|
import * as dayjs from "dayjs";
|
||||||
|
import {openCalcMenu} from "./calc";
|
||||||
|
|
||||||
export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLElement }) => {
|
export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLElement }) => {
|
||||||
const blockElement = hasClosestBlock(event.target);
|
const blockElement = hasClosestBlock(event.target);
|
||||||
|
|
|
||||||
256
app/src/protyle/render/av/calc.ts
Normal file
256
app/src/protyle/render/av/calc.ts
Normal file
|
|
@ -0,0 +1,256 @@
|
||||||
|
import {Menu} from "../../../plugin/Menu";
|
||||||
|
import {transaction} from "../../wysiwyg/transaction";
|
||||||
|
import {hasClosestBlock, hasClosestByClassName} from "../../util/hasClosest";
|
||||||
|
|
||||||
|
const calcItem = (options: {
|
||||||
|
menu: Menu,
|
||||||
|
protyle: IProtyle,
|
||||||
|
label: string,
|
||||||
|
operator: string,
|
||||||
|
oldOperator: string,
|
||||||
|
colId: string,
|
||||||
|
avId: string
|
||||||
|
}) => {
|
||||||
|
options.menu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
label: options.label,
|
||||||
|
click() {
|
||||||
|
transaction(options.protyle, [{
|
||||||
|
action: "setAttrViewColCalc",
|
||||||
|
avID: options.avId,
|
||||||
|
id: options.colId,
|
||||||
|
data: {
|
||||||
|
operator: options.operator
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
action: "setAttrViewColCalc",
|
||||||
|
avID: options.avId,
|
||||||
|
id: options.colId,
|
||||||
|
data: {
|
||||||
|
operator: options.oldOperator
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
|
||||||
|
const blockElement = hasClosestBlock(calcElement);
|
||||||
|
if (!blockElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rowElement = hasClosestByClassName(calcElement, "av__row--footer");
|
||||||
|
if (!rowElement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rowElement.classList.add("av__row--show");
|
||||||
|
const menu = new Menu("av-calc", () => {
|
||||||
|
rowElement.classList.remove("av__row--show");
|
||||||
|
});
|
||||||
|
if (menu.isOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const type = calcElement.dataset.dtype as TAVCol;
|
||||||
|
const colId = calcElement.dataset.colId;
|
||||||
|
const avId = blockElement.dataset.avId;
|
||||||
|
const oldOperator = calcElement.dataset.operator;
|
||||||
|
if (type !== "checkbox") {
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "",
|
||||||
|
label: window.siyuan.languages.calcOperatorNone
|
||||||
|
});
|
||||||
|
}
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Count all",
|
||||||
|
label: window.siyuan.languages.calcOperatorCountAll
|
||||||
|
});
|
||||||
|
if (type !== "checkbox") {
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Count values",
|
||||||
|
label: window.siyuan.languages.calcOperatorCountValues
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Count unique values",
|
||||||
|
label: window.siyuan.languages.calcOperatorCountUniqueValues
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Count empty",
|
||||||
|
label: window.siyuan.languages.calcOperatorCountEmpty
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Count not empty",
|
||||||
|
label: window.siyuan.languages.calcOperatorCountNotEmpty
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Percent empty",
|
||||||
|
label: window.siyuan.languages.calcOperatorPercentEmpty
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Percent not empty",
|
||||||
|
label: window.siyuan.languages.calcOperatorPercentNotEmpty
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Checked",
|
||||||
|
label: window.siyuan.languages.checked
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Unchecked",
|
||||||
|
label: window.siyuan.languages.unchecked
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Percent checked",
|
||||||
|
label: window.siyuan.languages.percentChecked
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Percent unchecked",
|
||||||
|
label: window.siyuan.languages.percentUnchecked
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (["number", "template"].includes(type)) {
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Sum",
|
||||||
|
label: window.siyuan.languages.calcOperatorSum
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Average",
|
||||||
|
label: window.siyuan.languages.calcOperatorAverage
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Median",
|
||||||
|
label: window.siyuan.languages.calcOperatorMedian
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Min",
|
||||||
|
label: window.siyuan.languages.calcOperatorMin
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Max",
|
||||||
|
label: window.siyuan.languages.calcOperatorMax
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Range",
|
||||||
|
label: window.siyuan.languages.calcOperatorRange
|
||||||
|
});
|
||||||
|
} else if (["date", "created", "updated"].includes(type)) {
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Earliest",
|
||||||
|
label: window.siyuan.languages.calcOperatorEarliest
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Latest",
|
||||||
|
label: window.siyuan.languages.calcOperatorLatest
|
||||||
|
});
|
||||||
|
calcItem({
|
||||||
|
menu,
|
||||||
|
protyle,
|
||||||
|
colId,
|
||||||
|
avId,
|
||||||
|
oldOperator,
|
||||||
|
operator: "Range",
|
||||||
|
label: window.siyuan.languages.calcOperatorRange
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const calcRect = calcElement.getBoundingClientRect();
|
||||||
|
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
||||||
|
};
|
||||||
|
|
@ -133,223 +133,18 @@ export const genCellValue = (colType: TAVCol, value: string | any) => {
|
||||||
type: colType,
|
type: colType,
|
||||||
mAsset: value as IAVCellAssetValue[]
|
mAsset: value as IAVCellAssetValue[]
|
||||||
};
|
};
|
||||||
|
} else if (colType === "checkbox") {
|
||||||
|
cellValue = {
|
||||||
|
type: colType,
|
||||||
|
checkbox: {
|
||||||
|
checked: value ? true : false
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cellValue;
|
return cellValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
const calcItem = (options: {
|
|
||||||
menu: Menu,
|
|
||||||
protyle: IProtyle,
|
|
||||||
label: string,
|
|
||||||
operator: string,
|
|
||||||
oldOperator: string,
|
|
||||||
colId: string,
|
|
||||||
avId: string
|
|
||||||
}) => {
|
|
||||||
options.menu.addItem({
|
|
||||||
iconHTML: "",
|
|
||||||
label: options.label,
|
|
||||||
click() {
|
|
||||||
transaction(options.protyle, [{
|
|
||||||
action: "setAttrViewColCalc",
|
|
||||||
avID: options.avId,
|
|
||||||
id: options.colId,
|
|
||||||
data: {
|
|
||||||
operator: options.operator
|
|
||||||
}
|
|
||||||
}], [{
|
|
||||||
action: "setAttrViewColCalc",
|
|
||||||
avID: options.avId,
|
|
||||||
id: options.colId,
|
|
||||||
data: {
|
|
||||||
operator: options.oldOperator
|
|
||||||
}
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const openCalcMenu = (protyle: IProtyle, calcElement: HTMLElement) => {
|
|
||||||
const blockElement = hasClosestBlock(calcElement);
|
|
||||||
if (!blockElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const rowElement = hasClosestByClassName(calcElement, "av__row--footer");
|
|
||||||
if (!rowElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rowElement.classList.add("av__row--show");
|
|
||||||
const menu = new Menu("av-calc", () => {
|
|
||||||
rowElement.classList.remove("av__row--show");
|
|
||||||
});
|
|
||||||
if (menu.isOpen) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const type = calcElement.dataset.dtype as TAVCol;
|
|
||||||
const colId = calcElement.dataset.colId;
|
|
||||||
const avId = blockElement.dataset.avId;
|
|
||||||
const oldOperator = calcElement.dataset.operator;
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "",
|
|
||||||
label: window.siyuan.languages.calcOperatorNone
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Count all",
|
|
||||||
label: window.siyuan.languages.calcOperatorCountAll
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Count values",
|
|
||||||
label: window.siyuan.languages.calcOperatorCountValues
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Count unique values",
|
|
||||||
label: window.siyuan.languages.calcOperatorCountUniqueValues
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Count empty",
|
|
||||||
label: window.siyuan.languages.calcOperatorCountEmpty
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Count not empty",
|
|
||||||
label: window.siyuan.languages.calcOperatorCountNotEmpty
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Percent empty",
|
|
||||||
label: window.siyuan.languages.calcOperatorPercentEmpty
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Percent not empty",
|
|
||||||
label: window.siyuan.languages.calcOperatorPercentNotEmpty
|
|
||||||
});
|
|
||||||
if (["number", "template"].includes(type)) {
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Sum",
|
|
||||||
label: window.siyuan.languages.calcOperatorSum
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Average",
|
|
||||||
label: window.siyuan.languages.calcOperatorAverage
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Median",
|
|
||||||
label: window.siyuan.languages.calcOperatorMedian
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Min",
|
|
||||||
label: window.siyuan.languages.calcOperatorMin
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Max",
|
|
||||||
label: window.siyuan.languages.calcOperatorMax
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Range",
|
|
||||||
label: window.siyuan.languages.calcOperatorRange
|
|
||||||
});
|
|
||||||
} else if (["date", "created", "updated"].includes(type)) {
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Earliest",
|
|
||||||
label: window.siyuan.languages.calcOperatorEarliest
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Latest",
|
|
||||||
label: window.siyuan.languages.calcOperatorLatest
|
|
||||||
});
|
|
||||||
calcItem({
|
|
||||||
menu,
|
|
||||||
protyle,
|
|
||||||
colId,
|
|
||||||
avId,
|
|
||||||
oldOperator,
|
|
||||||
operator: "Range",
|
|
||||||
label: window.siyuan.languages.calcOperatorRange
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const calcRect = calcElement.getBoundingClientRect();
|
|
||||||
menu.open({x: calcRect.left, y: calcRect.bottom, h: calcRect.height});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const cellScrollIntoView = (blockElement: HTMLElement, cellElement: Element, onlyHeight = true) => {
|
export const cellScrollIntoView = (blockElement: HTMLElement, cellElement: Element, onlyHeight = true) => {
|
||||||
const cellRect = cellElement.getBoundingClientRect();
|
const cellRect = cellElement.getBoundingClientRect();
|
||||||
if (!onlyHeight) {
|
if (!onlyHeight) {
|
||||||
|
|
@ -427,7 +222,7 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
|
||||||
}
|
}
|
||||||
cellRect = cellElements[0].getBoundingClientRect();
|
cellRect = cellElements[0].getBoundingClientRect();
|
||||||
let html = "";
|
let html = "";
|
||||||
const style = `style="position:absolute;left: ${cellRect.left}px;top: ${cellRect.top}px;width:${Math.max(cellRect.width, 58)}px;height: ${cellRect.height}px"`;
|
const style = `style="position:absolute;left: ${cellRect.left}px;top: ${cellRect.top}px;width:${Math.max(cellRect.width, 25)}px;height: ${cellRect.height}px"`;
|
||||||
if (["text", "url", "email", "phone", "block", "template"].includes(type)) {
|
if (["text", "url", "email", "phone", "block", "template"].includes(type)) {
|
||||||
html = `<textarea ${style} class="b3-text-field">${cellElements[0].firstElementChild.textContent}</textarea>`;
|
html = `<textarea ${style} class="b3-text-field">${cellElements[0].firstElementChild.textContent}</textarea>`;
|
||||||
} else if (type === "number") {
|
} else if (type === "number") {
|
||||||
|
|
@ -439,6 +234,8 @@ export const popTextCell = (protyle: IProtyle, cellElements: HTMLElement[], type
|
||||||
openMenuPanel({protyle, blockElement, type: "asset", cellElements});
|
openMenuPanel({protyle, blockElement, type: "asset", cellElements});
|
||||||
} else if (type === "date") {
|
} else if (type === "date") {
|
||||||
openMenuPanel({protyle, blockElement, type: "date", cellElements});
|
openMenuPanel({protyle, blockElement, type: "date", cellElements});
|
||||||
|
} else if (type === "checkbox") {
|
||||||
|
updateCellValue(protyle, type, cellElements);
|
||||||
}
|
}
|
||||||
if (!hasClosestByClassName(cellElements[0], "custom-attr")) {
|
if (!hasClosestByClassName(cellElements[0], "custom-attr")) {
|
||||||
cellElements[0].classList.add("av__cell--select");
|
cellElements[0].classList.add("av__cell--select");
|
||||||
|
|
@ -548,22 +345,28 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem
|
||||||
const cellId = item.getAttribute("data-id");
|
const cellId = item.getAttribute("data-id");
|
||||||
const colId = item.getAttribute("data-col-id");
|
const colId = item.getAttribute("data-col-id");
|
||||||
const inputValue: {
|
const inputValue: {
|
||||||
content: string | number,
|
content?: string | number,
|
||||||
isNotEmpty?: boolean
|
isNotEmpty?: boolean,
|
||||||
} = {
|
checked?: boolean,
|
||||||
content: (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value
|
} = {};
|
||||||
};
|
|
||||||
const oldValue: {
|
const oldValue: {
|
||||||
content: string | number,
|
content?: string | number,
|
||||||
isNotEmpty?: boolean
|
isNotEmpty?: boolean,
|
||||||
} = {
|
checked?: boolean,
|
||||||
content: type === "block" ? item.firstElementChild.textContent.trim() : item.textContent.trim()
|
} = {};
|
||||||
};
|
|
||||||
if (type === "number") {
|
if (type === "number") {
|
||||||
oldValue.content = parseFloat(oldValue.content as string);
|
oldValue.content = parseFloat(oldValue.content as string);
|
||||||
oldValue.isNotEmpty = typeof oldValue.content === "number" && !isNaN(oldValue.content);
|
oldValue.isNotEmpty = typeof oldValue.content === "number" && !isNaN(oldValue.content);
|
||||||
inputValue.content = parseFloat(inputValue.content as string);
|
inputValue.content = parseFloat(inputValue.content as string);
|
||||||
inputValue.isNotEmpty = typeof inputValue.content === "number" && !isNaN(inputValue.content);
|
inputValue.isNotEmpty = typeof inputValue.content === "number" && !isNaN(inputValue.content);
|
||||||
|
} else if (type === "checkbox") {
|
||||||
|
const useElement = item.querySelector("use")
|
||||||
|
inputValue.checked = useElement.getAttribute("xlink:href") === "#iconUncheck"
|
||||||
|
oldValue.checked = !inputValue.checked
|
||||||
|
useElement.setAttribute("xlink:href", inputValue.checked ? "#iconCheck" : "#iconUncheck")
|
||||||
|
} else {
|
||||||
|
inputValue.content = (avMaskElement.querySelector(".b3-text-field") as HTMLInputElement).value
|
||||||
|
oldValue.content = type === "block" ? item.firstElementChild.textContent.trim() : item.textContent.trim()
|
||||||
}
|
}
|
||||||
if (objEquals(inputValue, oldValue)) {
|
if (objEquals(inputValue, oldValue)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -607,6 +410,6 @@ const updateCellValue = (protyle: IProtyle, type: TAVCol, cellElements: HTMLElem
|
||||||
focusBlock(blockElement);
|
focusBlock(blockElement);
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
avMaskElement.remove();
|
avMaskElement?.remove();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,8 @@ export const getColIconByType = (type: TAVCol) => {
|
||||||
return "iconPhone";
|
return "iconPhone";
|
||||||
case "template":
|
case "template":
|
||||||
return "iconMath";
|
return "iconMath";
|
||||||
|
case "checkbox":
|
||||||
|
return "iconCheck";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -379,7 +381,7 @@ export const addAttrViewColAnimation = (options: {
|
||||||
if (index === 0) {
|
if (index === 0) {
|
||||||
html = `<div class="av__cell" data-icon="${options.icon || ""}" data-col-id="${options.id}" data-dtype="${options.type}" style="width: 200px;white-space: nowrap;">
|
html = `<div class="av__cell" data-icon="${options.icon || ""}" data-col-id="${options.id}" data-dtype="${options.type}" style="width: 200px;white-space: nowrap;">
|
||||||
<div draggable="true" class="av__cellheader">
|
<div draggable="true" class="av__cellheader">
|
||||||
${options.icon ? unicode2Emoji(options.icon, "av__cellicon", true) : `<svg class="av__cellicon"><use xlink:href="#${getColIconByType(options.type)}"></use></svg>`}
|
${options.icon ? unicode2Emoji(options.icon, "av__cellheadericon", true) : `<svg class="av__cellheadericon"><use xlink:href="#${getColIconByType(options.type)}"></use></svg>`}
|
||||||
<span class="av__celltext">${options.name}</span>
|
<span class="av__celltext">${options.name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="av__widthdrag"></div>
|
<div class="av__widthdrag"></div>
|
||||||
|
|
@ -825,6 +827,31 @@ export const addCol = (protyle: IProtyle, blockElement: Element) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconCheck",
|
||||||
|
label: window.siyuan.languages.checkbox,
|
||||||
|
click() {
|
||||||
|
const id = Lute.NewNodeID();
|
||||||
|
transaction(protyle, [{
|
||||||
|
action: "addAttrViewCol",
|
||||||
|
name: window.siyuan.languages.checkbox,
|
||||||
|
avID,
|
||||||
|
type: "checkbox",
|
||||||
|
id
|
||||||
|
}], [{
|
||||||
|
action: "removeAttrViewCol",
|
||||||
|
id,
|
||||||
|
avID,
|
||||||
|
}]);
|
||||||
|
addAttrViewColAnimation({
|
||||||
|
blockElement: blockElement,
|
||||||
|
protyle: protyle,
|
||||||
|
type: "checkbox",
|
||||||
|
name: window.siyuan.languages.checkbox,
|
||||||
|
id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
menu.addItem({
|
menu.addItem({
|
||||||
icon: "iconLink",
|
icon: "iconLink",
|
||||||
label: window.siyuan.languages.link,
|
label: window.siyuan.languages.link,
|
||||||
|
|
|
||||||
|
|
@ -85,9 +85,9 @@ data-icon="${column.icon}" data-dtype="${column.type}" data-pin="${column.pin}"
|
||||||
style="width: ${column.width || "200px"};
|
style="width: ${column.width || "200px"};
|
||||||
${column.wrap ? "" : "white-space: nowrap;"}">
|
${column.wrap ? "" : "white-space: nowrap;"}">
|
||||||
<div draggable="true" class="av__cellheader">
|
<div draggable="true" class="av__cellheader">
|
||||||
${column.icon ? unicode2Emoji(column.icon, "av__cellicon", true) : `<svg class="av__cellicon"><use xlink:href="#${getColIconByType(column.type)}"></use></svg>`}
|
${column.icon ? unicode2Emoji(column.icon, "av__cellheadericon", true) : `<svg class="av__cellheadericon"><use xlink:href="#${getColIconByType(column.type)}"></use></svg>`}
|
||||||
<span class="av__celltext">${column.name}</span>
|
<span class="av__celltext">${column.name}</span>
|
||||||
${column.pin ? '<div class="fn__flex-1"></div><svg class="av__cellicon"><use xlink:href="#iconPin"></use></svg>' : ""}
|
${column.pin ? '<div class="fn__flex-1"></div><svg class="av__cellheadericon"><use xlink:href="#iconPin"></use></svg>' : ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="av__widthdrag"></div>
|
<div class="av__widthdrag"></div>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
@ -172,6 +172,8 @@ style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use x
|
||||||
text += `<span class="b3-chip av__celltext--url" data-url="${item.content}">${item.name}</span>`;
|
text += `<span class="b3-chip av__celltext--url" data-url="${item.content}">${item.name}</span>`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else if (cell.valueType === "checkbox") {
|
||||||
|
text += `<svg class="av__checkbox"><use xlink:href="#icon${cell.value?.checkbox?.checked ? "Check" : "Uncheck"}"></use></svg>`;
|
||||||
}
|
}
|
||||||
if (["text", "template", "url", "email", "phone", "number", "date", "created", "updated"].includes(cell.valueType) &&
|
if (["text", "template", "url", "email", "phone", "number", "date", "created", "updated"].includes(cell.valueType) &&
|
||||||
cell.value && cell.value[cell.valueType as "url"].content) {
|
cell.value && cell.value[cell.valueType as "url"].content) {
|
||||||
|
|
|
||||||
|
|
@ -385,7 +385,7 @@ export class WYSIWYG {
|
||||||
const scrollElement = nodeElement.querySelector(".av__scroll");
|
const scrollElement = nodeElement.querySelector(".av__scroll");
|
||||||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||||
documentSelf.onmousemove = (moveEvent: MouseEvent) => {
|
documentSelf.onmousemove = (moveEvent: MouseEvent) => {
|
||||||
newWidth = Math.max(oldWidth + (moveEvent.clientX - event.clientX), 58) + "px";
|
newWidth = Math.max(oldWidth + (moveEvent.clientX - event.clientX), 25) + "px";
|
||||||
scrollElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
|
scrollElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
|
||||||
(item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
|
(item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
4
app/src/types/index.d.ts
vendored
4
app/src/types/index.d.ts
vendored
|
|
@ -71,6 +71,7 @@ type TAVCol =
|
||||||
| "template"
|
| "template"
|
||||||
| "created"
|
| "created"
|
||||||
| "updated"
|
| "updated"
|
||||||
|
| "checkbox"
|
||||||
type THintSource = "search" | "av" | "hint";
|
type THintSource = "search" | "av" | "hint";
|
||||||
type TAVFilterOperator =
|
type TAVFilterOperator =
|
||||||
"="
|
"="
|
||||||
|
|
@ -1094,6 +1095,9 @@ interface IAVCellValue {
|
||||||
}
|
}
|
||||||
template?: {
|
template?: {
|
||||||
content: string
|
content: string
|
||||||
|
},
|
||||||
|
checkbox?: {
|
||||||
|
checked: boolean
|
||||||
}
|
}
|
||||||
date?: IAVCellDateValue
|
date?: IAVCellDateValue
|
||||||
created?: IAVCellDateValue
|
created?: IAVCellDateValue
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue