Browse Source

:art: https://github.com/siyuan-note/siyuan/issues/8692

Vanessa 2 years ago
parent
commit
1ac46032fa
3 changed files with 144 additions and 18 deletions
  1. 125 14
      app/src/protyle/render/av/date.ts
  2. 17 2
      app/src/protyle/render/av/openMenuPanel.ts
  3. 2 2
      app/src/types/index.d.ts

+ 125 - 14
app/src/protyle/render/av/date.ts

@@ -1,21 +1,18 @@
+import {transaction} from "../../wysiwyg/transaction";
+import * as dayjs from "dayjs";
+
 export const getDateHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
-    const colId = cellElements[0].dataset["colId"];
-    const colData = data.columns.find(item => {
-        if (item.id === colId) {
-            return item;
-        }
-    });
     let hasEndDate = true;
-    let hasMatch = false;
+    let cellValue:IAVCell
     cellElements.forEach((cellElement) => {
         data.rows.find(row => {
             if (cellElement.parentElement.dataset.id === row.id) {
                 row.cells.find(cell => {
                     if (cell.id === cellElement.dataset.id) {
-                        if (!cell.value || !cell.value.date || !cell.value.date.content2) {
+                        if (!cell.value || !cell.value.date || !cell.value.date.hasEndDate) {
                             hasEndDate = false;
-                            hasMatch = true;
                         }
+                        cellValue = cell;
                         return true;
                     }
                 });
@@ -23,21 +20,135 @@ export const getDateHTML = (data: IAVTable, cellElements: HTMLElement[]) => {
             }
         });
     });
-    if (!hasMatch) {
+    if (!cellValue) {
         hasEndDate = false;
     }
+    let value = ""
+    if (cellValue?.value?.date?.content) {
+        value = dayjs(cellValue.value.date.content).format("YYYY-MM-DDTHH:mm")
+    }
+    let value2 = ""
+    if (cellValue?.value?.date?.content2) {
+        value2 = dayjs(cellValue.value.date.content2).format("YYYY-MM-DDTHH:mm")
+    }
     return `<div>
-    <input type="datetime-local" class="b3-text-field fn__block">
-    <input type="datetime-local" class="b3-text-field fn__block${hasEndDate ? "" : " fn__none"}">
+    <input type="datetime-local" value="${value}" class="b3-text-field fn__size200"><br>
+    <input type="datetime-local" value="${value2}" style="margin-top: 8px" class="b3-text-field fn__size200${hasEndDate ? "" : " fn__none"}">
     <button class="b3-menu__separator"></button>
     <button class="b3-menu__item">
         <span>${window.siyuan.languages.endDate}</span>
         <span class="fn__space fn__flex-1"></span>
         <input type="checkbox" class="b3-switch fn__flex-center"${hasEndDate ? " checked" : ""}>
     </button>
+    <button class="b3-menu__separator"></button>
+    <button class="b3-menu__item" data-type="clearDate">
+        <svg class="b3-menu__icon"><use xlink:href="#iconTrashcan"></use></svg>
+        <span class="b3-menu__label">${window.siyuan.languages.clear}</span>
+    </button>
 </div>`;
 };
 
-export const bindDateEvent = (options: { protyle: IProtyle, data: IAV, menuElement: HTMLElement }) => {
-
+export const bindDateEvent = (options: {
+    protyle: IProtyle,
+    data: IAV,
+    menuElement: HTMLElement,
+    cellElements: HTMLElement[]
+}) => {
+    const inputElements: NodeListOf<HTMLInputElement> = options.menuElement.querySelectorAll(".b3-text-field");
+    inputElements[0].addEventListener("change", () => {
+        setDateValue({
+            cellElements: options.cellElements,
+            data: options.data,
+            protyle: options.protyle,
+            value: {
+                content: new Date(inputElements[0].value).getTime()
+            }
+        });
+    })
+    inputElements[1].addEventListener("change", () => {
+        setDateValue({
+            cellElements: options.cellElements,
+            data: options.data,
+            protyle: options.protyle,
+            value: {
+                content2: new Date(inputElements[1].value).getTime()
+            }
+        });
+    })
+    const checkElement = options.menuElement.querySelector(".b3-switch") as HTMLInputElement;
+    checkElement.addEventListener("change", () => {
+        if (checkElement.checked) {
+            inputElements[1].classList.remove("fn__none")
+        } else {
+            inputElements[1].classList.add("fn__none")
+        }
+        setDateValue({
+            cellElements: options.cellElements,
+            data: options.data,
+            protyle: options.protyle,
+            value: {
+                hasEndDate: checkElement.checked
+            }
+        });
+    });
 };
+
+export const setDateValue = (options: {
+    cellElements: HTMLElement[],
+    data: IAV
+    protyle: IProtyle,
+    value: {
+        content?: number,
+        content2?: number,
+        hasEndDate?: boolean
+    }
+}) => {
+    let cellIndex = 0;
+    Array.from(options.cellElements[0].parentElement.querySelectorAll(".av__cell")).find((item: HTMLElement, index) => {
+        if (item.dataset.id === options.cellElements[0].dataset.id) {
+            cellIndex = index;
+            return true;
+        }
+    });
+    const colId = options.cellElements[0].dataset.colId;
+    const cellDoOperations: IOperation[] = [];
+    const cellUndoOperations: IOperation[] = [];
+    options.cellElements.forEach(item => {
+        let cellData: IAVCell;
+        let oldValue
+        const rowID = item.parentElement.dataset.id;
+        options.data.view.rows.find(row => {
+            if (row.id === rowID) {
+                cellData = row.cells[cellIndex];
+                // 为空时 cellId 每次请求都不一致
+                cellData.id = item.dataset.id;
+                if (!cellData.value) {
+                    cellData.value = {};
+                }
+                oldValue = Object.assign({}, cellData.value.date);
+                cellData.value.date = Object.assign(cellData.value.date || {}, options.value);
+                return true;
+            }
+        });
+
+        cellDoOperations.push({
+            action: "updateAttrViewCell",
+            id: cellData.id,
+            keyID: colId,
+            rowID,
+            avID: options.data.id,
+            data: cellData.value
+        });
+        cellUndoOperations.push({
+            action: "updateAttrViewCell",
+            id: cellData.id,
+            keyID: colId,
+            rowID,
+            avID: options.data.id,
+            data: {
+                date: oldValue
+            }
+        });
+    });
+    transaction(options.protyle, cellDoOperations, cellUndoOperations);
+}

+ 17 - 2
app/src/protyle/render/av/openMenuPanel.ts

@@ -7,7 +7,7 @@ import {hasClosestByAttribute} from "../../util/hasClosest";
 import {bindSelectEvent, getSelectHTML, addColOptionOrCell, setColOption, removeCellOption} from "./select";
 import {addFilter, getFiltersHTML, setFilter} from "./filter";
 import {addSort, bindSortsEvent, getSortsHTML} from "./sort";
-import {bindDateEvent, getDateHTML} from "./date";
+import {bindDateEvent, getDateHTML, setDateValue} from "./date";
 
 export const openMenuPanel = (options: {
     protyle: IProtyle,
@@ -59,7 +59,7 @@ export const openMenuPanel = (options: {
         } else if (options.type === "date") {
             const cellRect = options.cellElements[options.cellElements.length - 1].getBoundingClientRect();
             setPosition(menuElement, cellRect.left, cellRect.bottom, cellRect.height);
-            bindDateEvent({protyle: options.protyle, data, menuElement});
+            bindDateEvent({protyle: options.protyle, data, menuElement, cellElements: options.cellElements});
             const inputElement = menuElement.querySelector("input");
             inputElement.select();
             inputElement.focus();
@@ -604,6 +604,21 @@ export const openMenuPanel = (options: {
                     event.preventDefault();
                     event.stopPropagation();
                     break;
+                } else if (type === "clearDate") {
+                    setDateValue({
+                        cellElements: options.cellElements,
+                        data,
+                        protyle: options.protyle,
+                        value: {
+                            content: 0,
+                            content2: 0,
+                            hasEndDate: false
+                        }
+                    });
+                    avPanelElement.remove();
+                    event.preventDefault();
+                    event.stopPropagation();
+                    break;
                 }
                 target = target.parentElement;
             }

+ 2 - 2
app/src/types/index.d.ts

@@ -925,10 +925,10 @@ interface IAVCell {
 }
 
 interface IAVCellValue {
-    type: TAVCol,
+    type?: TAVCol,
     text?: { content: string },
     number?: { content?: number, isNotEmpty: boolean, format?: string, formattedContent?: string },
     mSelect?: { content: string, color: string }[]
     block?: { content: string, id: string }
-    date?: { content: string, content2?: string }
+    date?: { content?: number, content2?: number, hasEndDate?: boolean }
 }