mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 09:30:14 +01:00
✨ https://github.com/siyuan-note/siyuan/issues/8895 edit asset item
This commit is contained in:
parent
67574984d0
commit
e8c15eebb6
7 changed files with 192 additions and 37 deletions
|
|
@ -2,7 +2,47 @@ import {Constants} from "../../constants";
|
||||||
import {addScript} from "../util/addScript";
|
import {addScript} from "../util/addScript";
|
||||||
import {fetchPost} from "../../util/fetch";
|
import {fetchPost} from "../../util/fetch";
|
||||||
|
|
||||||
export const previewImage = (src: string, id: string) => {
|
export const previewImage = (src: string) => {
|
||||||
|
addScript(`${Constants.PROTYLE_CDN}/js/viewerjs/viewer.js?v=1.10.4`, "protyleViewerScript").then(() => {
|
||||||
|
const imagesElement = document.createElement("ul");
|
||||||
|
imagesElement.innerHTML = `<li><img src="${src}"></li>`;
|
||||||
|
// @ts-ignore
|
||||||
|
window.siyuan.viewer = new Viewer(imagesElement, {
|
||||||
|
title: [1, (image: HTMLImageElement, imageData: IObject) => {
|
||||||
|
let name = image.alt;
|
||||||
|
if (!name) {
|
||||||
|
name = image.src.substring(image.src.lastIndexOf("/") + 1);
|
||||||
|
}
|
||||||
|
name = name.substring(0, name.lastIndexOf(".")).replace(/-\d{14}-\w{7}$/, "");
|
||||||
|
return `${name} [${imageData.naturalWidth} × ${imageData.naturalHeight}]`;
|
||||||
|
}],
|
||||||
|
button: false,
|
||||||
|
transition: false,
|
||||||
|
hidden: function () {
|
||||||
|
window.siyuan.viewer.destroy();
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
zoomIn: true,
|
||||||
|
zoomOut: true,
|
||||||
|
oneToOne: true,
|
||||||
|
reset: true,
|
||||||
|
prev: true,
|
||||||
|
play: true,
|
||||||
|
next: true,
|
||||||
|
rotateLeft: true,
|
||||||
|
rotateRight: true,
|
||||||
|
flipHorizontal: true,
|
||||||
|
flipVertical: true,
|
||||||
|
close: function () {
|
||||||
|
window.siyuan.viewer.destroy();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
window.siyuan.viewer.show();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const previewDocImage = (src: string, id: string) => {
|
||||||
addScript(`${Constants.PROTYLE_CDN}/js/viewerjs/viewer.js?v=1.10.4`, "protyleViewerScript").then(() => {
|
addScript(`${Constants.PROTYLE_CDN}/js/viewerjs/viewer.js?v=1.10.4`, "protyleViewerScript").then(() => {
|
||||||
fetchPost("/api/asset/getDocImageAssets", {id}, (response) => {
|
fetchPost("/api/asset/getDocImageAssets", {id}, (response) => {
|
||||||
const imagesElement = document.createElement("ul");
|
const imagesElement = document.createElement("ul");
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import {openByMobile, writeText} from "../util/compatibility";
|
||||||
import {focusByRange} from "../util/selection";
|
import {focusByRange} from "../util/selection";
|
||||||
import {showMessage} from "../../dialog/message";
|
import {showMessage} from "../../dialog/message";
|
||||||
import {isLocalPath, pathPosix} from "../../util/pathName";
|
import {isLocalPath, pathPosix} from "../../util/pathName";
|
||||||
import {previewImage} from "./image";
|
import {previewDocImage} from "./image";
|
||||||
import {needSubscribe} from "../../util/needSubscribe";
|
import {needSubscribe} from "../../util/needSubscribe";
|
||||||
import {Constants} from "../../constants";
|
import {Constants} from "../../constants";
|
||||||
import {getSearch, isMobile} from "../../util/functions";
|
import {getSearch, isMobile} from "../../util/functions";
|
||||||
|
|
@ -117,7 +117,7 @@ export class Preview {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else if (target.tagName === "IMG") {
|
} else if (target.tagName === "IMG") {
|
||||||
previewImage((event.target as HTMLImageElement).src, protyle.block.rootID);
|
previewDocImage((event.target as HTMLImageElement).src, protyle.block.rootID);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ import {isMobile} from "../../../util/functions";
|
||||||
import {Constants} from "../../../constants";
|
import {Constants} from "../../../constants";
|
||||||
import {uploadFiles} from "../../upload";
|
import {uploadFiles} from "../../upload";
|
||||||
import {pathPosix} from "../../../util/pathName";
|
import {pathPosix} from "../../../util/pathName";
|
||||||
|
import {openMenu} from "../../../menus/commonMenuItem";
|
||||||
|
import {MenuItem} from "../../../menus/Menu";
|
||||||
|
import {exportAsset} from "../../../menus/util";
|
||||||
|
import {setPosition} from "../../../util/setPosition";
|
||||||
|
import {previewImage} from "../../preview/image";
|
||||||
|
|
||||||
export const bindAssetEvent = (options: {
|
export const bindAssetEvent = (options: {
|
||||||
protyle: IProtyle,
|
protyle: IProtyle,
|
||||||
|
|
@ -62,15 +66,17 @@ export const getAssetHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
|
||||||
}
|
}
|
||||||
let contentHTML
|
let contentHTML
|
||||||
if (item.type === "image") {
|
if (item.type === "image") {
|
||||||
contentHTML = `<img style="max-height: 180px;max-width: 360px;border-radius: var(--b3-border-radius);margin: 4px 0;" src="${item.content}"/>`
|
contentHTML = `<span class="fn__flex-1">
|
||||||
|
<img style="max-height: 180px;max-width: 360px;border-radius: var(--b3-border-radius);margin: 4px 0;" src="${item.content}"/>
|
||||||
|
</span>`
|
||||||
} else {
|
} else {
|
||||||
contentHTML = `<span class="fn__ellipsis b3-menu__label" style="max-width: 360px">${item.name}</span>`
|
contentHTML = `<span class="fn__ellipsis b3-menu__label" style="max-width: 360px">${item.name}</span>`
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `<button data-type="addColOptionOrCell" class="b3-menu__item" draggable="true">
|
html += `<button class="b3-menu__item" draggable="true" data-name="${item.name}" data-type="${item.type}" data-content="${item.content}">
|
||||||
<svg class="b3-menu__icon"><use xlink:href="#iconDrag"></use></svg>
|
<svg class="b3-menu__icon"><use xlink:href="#iconDrag"></use></svg>
|
||||||
${contentHTML}
|
${contentHTML}
|
||||||
<svg class="b3-menu__action" data-type="setColOption"><use xlink:href="#iconEdit"></use></svg>
|
<svg class="b3-menu__action" data-type="editAssetItem"><use xlink:href="#iconEdit"></use></svg>
|
||||||
</button>`
|
</button>`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -92,11 +98,9 @@ const updateAssetCell = (options: {
|
||||||
protyle: IProtyle,
|
protyle: IProtyle,
|
||||||
data: IAV,
|
data: IAV,
|
||||||
cellElements: HTMLElement[],
|
cellElements: HTMLElement[],
|
||||||
value: IAVCellAssetValue[]
|
value?: IAVCellAssetValue[],
|
||||||
|
removeContent?: string
|
||||||
}) => {
|
}) => {
|
||||||
if (!options.value || options.value.length === 0 || !options.value[0].content) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let cellIndex = 0;
|
let cellIndex = 0;
|
||||||
Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
|
||||||
if (item.dataset.id === options.cellElements[0].dataset.id) {
|
if (item.dataset.id === options.cellElements[0].dataset.id) {
|
||||||
|
|
@ -123,9 +127,33 @@ const updateAssetCell = (options: {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const oldValue = Object.assign([], cellData.value.mAsset);
|
const oldValue = Object.assign([], cellData.value.mAsset);
|
||||||
options.value.forEach(item => {
|
if (options.removeContent) {
|
||||||
cellData.value.mAsset.push(item);
|
cellData.value.mAsset.find((oldItem, index) => {
|
||||||
|
if (oldItem.content === options.removeContent) {
|
||||||
|
cellData.value.mAsset.splice(index, 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
options.value.forEach(newitem => {
|
||||||
|
if (!newitem.content) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const hasMatch = cellData.value.mAsset.find(oldItem => {
|
||||||
|
if (oldItem.content === newitem.content) {
|
||||||
|
oldItem.name = newitem.name;
|
||||||
|
oldItem.type = newitem.type;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
if (!hasMatch) {
|
||||||
|
if (newitem.type === "file" && !newitem.name) {
|
||||||
|
newitem.name = newitem.content
|
||||||
|
}
|
||||||
|
cellData.value.mAsset.push(newitem);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
cellDoOperations.push({
|
cellDoOperations.push({
|
||||||
action: "updateAttrViewCell",
|
action: "updateAttrViewCell",
|
||||||
id: cellData.id,
|
id: cellData.id,
|
||||||
|
|
@ -147,6 +175,81 @@ const updateAssetCell = (options: {
|
||||||
updateAttrViewCellAnimation(item);
|
updateAttrViewCellAnimation(item);
|
||||||
});
|
});
|
||||||
transaction(options.protyle, cellDoOperations, cellUndoOperations);
|
transaction(options.protyle, cellDoOperations, cellUndoOperations);
|
||||||
|
const menuElement = document.querySelector(".av__panel > .b3-menu") as HTMLElement;
|
||||||
|
if (menuElement) {
|
||||||
|
menuElement.innerHTML = getAssetHTML(options.data.view, options.cellElements);
|
||||||
|
bindAssetEvent({protyle: options.protyle, data: options.data, menuElement, cellElements: options.cellElements})
|
||||||
|
const cellRect = options.protyle.wysiwyg.element.querySelector(`.av__cell[data-id="${options.cellElements[0].dataset.id}"]`).getBoundingClientRect();
|
||||||
|
setTimeout(() => {
|
||||||
|
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
||||||
|
}, Constants.TIMEOUT_LOAD); // 等待图片加载
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const editAssetItem = (protyle: IProtyle, data: IAV, cellElements: HTMLElement[], target: HTMLElement) => {
|
||||||
|
const linkAddress = target.dataset.content
|
||||||
|
const type = target.dataset.type as "image" | "file"
|
||||||
|
const menu = new Menu("av-asset-edit", () => {
|
||||||
|
if (!textElement || !textElement.value || textElement.value === target.dataset.name) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updateAssetCell({
|
||||||
|
protyle,
|
||||||
|
data,
|
||||||
|
cellElements,
|
||||||
|
value: [{
|
||||||
|
content: linkAddress,
|
||||||
|
name: textElement.value,
|
||||||
|
type
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if (menu.isOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type === "file") {
|
||||||
|
menu.addItem({
|
||||||
|
iconHTML: "",
|
||||||
|
label: `<textarea rows="1" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" class="b3-text-field"></textarea>`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconPreview",
|
||||||
|
label: window.siyuan.languages.cardPreview,
|
||||||
|
click() {
|
||||||
|
previewImage(linkAddress);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
menu.addItem({
|
||||||
|
icon: "iconTrashcan",
|
||||||
|
label: window.siyuan.languages.delete,
|
||||||
|
click() {
|
||||||
|
updateAssetCell({
|
||||||
|
protyle,
|
||||||
|
data,
|
||||||
|
cellElements,
|
||||||
|
removeContent: linkAddress
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
openMenu(protyle.app, linkAddress, false, true);
|
||||||
|
/// #if !BROWSER
|
||||||
|
if (linkAddress?.startsWith("assets/")) {
|
||||||
|
window.siyuan.menus.menu.append(new MenuItem(exportAsset(linkAddress)).element);
|
||||||
|
}
|
||||||
|
/// #endif
|
||||||
|
const textElement = menu.element.querySelector("textarea")
|
||||||
|
if (textElement) {
|
||||||
|
textElement.value = target.dataset.name;
|
||||||
|
}
|
||||||
|
const rect = target.getBoundingClientRect();
|
||||||
|
menu.open({
|
||||||
|
x: rect.right,
|
||||||
|
y: rect.top,
|
||||||
|
w: rect.width,
|
||||||
|
h: rect.height,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addAssetLink = (protyle: IProtyle, data: IAV, cellElements: HTMLElement[], target: HTMLElement) => {
|
export const addAssetLink = (protyle: IProtyle, data: IAV, cellElements: HTMLElement[], target: HTMLElement) => {
|
||||||
|
|
@ -166,7 +269,9 @@ export const addAssetLink = (protyle: IProtyle, data: IAV, cellElements: HTMLEle
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
if (menu.isOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
menu.addItem({
|
menu.addItem({
|
||||||
iconHTML: "",
|
iconHTML: "",
|
||||||
label: `<textarea rows="1" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" class="b3-text-field" placeholder="${window.siyuan.languages.link}"></textarea>`,
|
label: `<textarea rows="1" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" class="b3-text-field" placeholder="${window.siyuan.languages.link}"></textarea>`,
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,7 @@ export const getCalcValue = (column: IAVColumn) => {
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const genCellValue = (colType: TAVCol, value: string | {
|
export const genCellValue = (colType: TAVCol, value: string | any) => {
|
||||||
content: string,
|
|
||||||
color: string
|
|
||||||
}[] | IAVCellDateValue) => {
|
|
||||||
let cellValue: IAVCellValue;
|
let cellValue: IAVCellValue;
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
if (colType === "number") {
|
if (colType === "number") {
|
||||||
|
|
@ -118,16 +115,18 @@ export const genCellValue = (colType: TAVCol, value: string | {
|
||||||
if (colType === "mSelect" || colType === "select") {
|
if (colType === "mSelect" || colType === "select") {
|
||||||
cellValue = {
|
cellValue = {
|
||||||
type: colType,
|
type: colType,
|
||||||
mSelect: value as {
|
mSelect: value as IAVCellSelectValue[]
|
||||||
content: string,
|
|
||||||
color: string
|
|
||||||
}[]
|
|
||||||
};
|
};
|
||||||
} else if (colType === "date") {
|
} else if (colType === "date") {
|
||||||
cellValue = {
|
cellValue = {
|
||||||
type: colType,
|
type: colType,
|
||||||
date: value as IAVCellDateValue
|
date: value as IAVCellDateValue
|
||||||
};
|
};
|
||||||
|
} else if (colType === "mAsset") {
|
||||||
|
cellValue = {
|
||||||
|
type: colType,
|
||||||
|
mAsset: value as IAVCellAssetValue[]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cellValue;
|
return cellValue;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ import {addSort, bindSortsEvent, getSortsHTML} from "./sort";
|
||||||
import {bindDateEvent, getDateHTML, setDateValue} from "./date";
|
import {bindDateEvent, getDateHTML, setDateValue} from "./date";
|
||||||
import {formatNumber} from "./number";
|
import {formatNumber} from "./number";
|
||||||
import {removeAttrViewColAnimation} from "./action";
|
import {removeAttrViewColAnimation} from "./action";
|
||||||
import {addAssetLink, bindAssetEvent, getAssetHTML} from "./asset";
|
import {addAssetLink, bindAssetEvent, editAssetItem, getAssetHTML} from "./asset";
|
||||||
|
import {Constants} from "../../../constants";
|
||||||
|
|
||||||
export const openMenuPanel = (options: {
|
export const openMenuPanel = (options: {
|
||||||
protyle: IProtyle,
|
protyle: IProtyle,
|
||||||
|
|
@ -60,18 +61,21 @@ export const openMenuPanel = (options: {
|
||||||
const tabRect = options.blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
const tabRect = options.blockElement.querySelector(".layout-tab-bar").getBoundingClientRect();
|
||||||
if (["select", "date", "asset"].includes(options.type)) {
|
if (["select", "date", "asset"].includes(options.type)) {
|
||||||
const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
|
const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
|
||||||
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
|
||||||
if (options.type === "select") {
|
if (options.type === "select") {
|
||||||
bindSelectEvent(options.protyle, data, menuElement, options.cellElements);
|
bindSelectEvent(options.protyle, data, menuElement, options.cellElements);
|
||||||
} else if (options.type === "date") {
|
} else if (options.type === "date") {
|
||||||
bindDateEvent({protyle: options.protyle, data, menuElement, cellElements: options.cellElements});
|
bindDateEvent({protyle: options.protyle, data, menuElement, cellElements: options.cellElements});
|
||||||
} else if (options.type === "asset") {
|
} else if (options.type === "asset") {
|
||||||
bindAssetEvent({protyle: options.protyle, data, menuElement, cellElements: options.cellElements});
|
bindAssetEvent({protyle: options.protyle, data, menuElement, cellElements: options.cellElements});
|
||||||
|
setTimeout(() => {
|
||||||
|
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
||||||
|
}, Constants.TIMEOUT_LOAD); // 等待图片加载
|
||||||
}
|
}
|
||||||
if (["select", "date"].includes(options.type)) {
|
if (["select", "date"].includes(options.type)) {
|
||||||
const inputElement = menuElement.querySelector("input");
|
const inputElement = menuElement.querySelector("input");
|
||||||
inputElement.select();
|
inputElement.select();
|
||||||
inputElement.focus();
|
inputElement.focus();
|
||||||
|
setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
setPosition(menuElement, tabRect.right - menuElement.clientWidth, tabRect.bottom, tabRect.height);
|
||||||
|
|
@ -639,6 +643,11 @@ export const openMenuPanel = (options: {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
|
} else if (type === "editAssetItem") {
|
||||||
|
editAssetItem(options.protyle, data, options.cellElements, target.parentElement)
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
break;
|
||||||
} else if (type === "clearDate") {
|
} else if (type === "clearDate") {
|
||||||
setDateValue({
|
setDateValue({
|
||||||
cellElements: options.cellElements,
|
cellElements: options.cellElements,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import {Constants} from "../../constants";
|
||||||
import {getSearch, isMobile} from "../../util/functions";
|
import {getSearch, isMobile} from "../../util/functions";
|
||||||
import {isLocalPath, pathPosix} from "../../util/pathName";
|
import {isLocalPath, pathPosix} from "../../util/pathName";
|
||||||
import {genEmptyElement} from "../../block/util";
|
import {genEmptyElement} from "../../block/util";
|
||||||
import {previewImage} from "../preview/image";
|
import {previewDocImage} from "../preview/image";
|
||||||
import {
|
import {
|
||||||
contentMenu,
|
contentMenu,
|
||||||
enterBack,
|
enterBack,
|
||||||
|
|
@ -1592,7 +1592,7 @@ export class WYSIWYG {
|
||||||
|
|
||||||
this.element.addEventListener("dblclick", (event: MouseEvent & { target: HTMLElement }) => {
|
this.element.addEventListener("dblclick", (event: MouseEvent & { target: HTMLElement }) => {
|
||||||
if (event.target.tagName === "IMG" && !event.target.classList.contains("emoji")) {
|
if (event.target.tagName === "IMG" && !event.target.classList.contains("emoji")) {
|
||||||
previewImage((event.target as HTMLImageElement).src, protyle.block.rootID);
|
previewDocImage((event.target as HTMLImageElement).src, protyle.block.rootID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
22
app/src/types/index.d.ts
vendored
22
app/src/types/index.d.ts
vendored
|
|
@ -998,12 +998,6 @@ interface IAVCell {
|
||||||
valueType: TAVCol,
|
valueType: TAVCol,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IAVCellAssetValue {
|
|
||||||
content: string,
|
|
||||||
name: string,
|
|
||||||
type: "file" | "image"
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IAVCellValue {
|
interface IAVCellValue {
|
||||||
type?: TAVCol,
|
type?: TAVCol,
|
||||||
text?: {
|
text?: {
|
||||||
|
|
@ -1015,10 +1009,7 @@ interface IAVCellValue {
|
||||||
format?: string,
|
format?: string,
|
||||||
formattedContent?: string
|
formattedContent?: string
|
||||||
},
|
},
|
||||||
mSelect?: {
|
mSelect?: IAVCellSelectValue[]
|
||||||
content: string,
|
|
||||||
color: string
|
|
||||||
}[]
|
|
||||||
mAsset?: IAVCellAssetValue[]
|
mAsset?: IAVCellAssetValue[]
|
||||||
block?: {
|
block?: {
|
||||||
content: string,
|
content: string,
|
||||||
|
|
@ -1043,3 +1034,14 @@ interface IAVCellDateValue {
|
||||||
isNotEmpty2?: boolean
|
isNotEmpty2?: boolean
|
||||||
hasEndDate?: boolean
|
hasEndDate?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IAVCellSelectValue {
|
||||||
|
content: string,
|
||||||
|
color: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IAVCellAssetValue {
|
||||||
|
content: string,
|
||||||
|
name: string,
|
||||||
|
type: "file" | "image"
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue