mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 10:02:59 +08:00
Merge pull request #2072 from vanndoublen/feature/custom-datetime-format
Feature/custom datetime format
This commit is contained in:
commit
e2ac581b14
@ -124,8 +124,23 @@ function formatDateISO(date: Date) {
|
||||
return `${date.getFullYear()}-${padNum(date.getMonth() + 1)}-${padNum(date.getDate())}`;
|
||||
}
|
||||
|
||||
function formatDateTime(date: Date) {
|
||||
return `${formatDate(date)} ${formatTime(date)}`;
|
||||
|
||||
export function formatDateTime(date: Date, userSuppliedFormat?: string): string {
|
||||
const DEFAULT_FORMAT = 'YYYY-MM-DD HH:mm';
|
||||
const formatToUse = (typeof userSuppliedFormat === 'string' && userSuppliedFormat.trim() !== "")
|
||||
? userSuppliedFormat.trim()
|
||||
: DEFAULT_FORMAT;
|
||||
|
||||
if (!date) {
|
||||
date = new Date();
|
||||
}
|
||||
|
||||
try {
|
||||
return dayjs(date).format(formatToUse);
|
||||
} catch (e: any) {
|
||||
console.warn(`TriliumNext: Day.js encountered an error with format string "${formatToUse}". Falling back to default. Error: ${e.message}`);
|
||||
return dayjs(date).format(DEFAULT_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
function localNowDateTime() {
|
||||
|
@ -1962,5 +1962,16 @@
|
||||
"title": "Appearance",
|
||||
"word_wrapping": "Word wrapping",
|
||||
"color-scheme": "Color scheme"
|
||||
},
|
||||
"custom_date_time_format": {
|
||||
"title": "Custom Date/Time Format (Alt+T)",
|
||||
"desc1": "Define a custom format for the date and time inserted using the Alt+T shortcut.",
|
||||
"desc2": "Uses <a href=\"https://day.js.org/docs/en/display/format\" target=\"_blank\" rel=\"noopener noreferrer\">Day.js format tokens</a>. Refer to the Day.js documentation for valid tokens.",
|
||||
"important_label": "Important:",
|
||||
"desc3": "If you provide a format string that Day.js does not recognize (e.g., mostly plain text without valid Day.js tokens), the text you typed might be inserted literally. If the format string is left empty, or if Day.js encounters a critical internal error with your format, a default format (e.g., YYYY-MM-DD HH:mm) will be used.",
|
||||
"format_string_label": "Format String:",
|
||||
"placeholder": "e.g., DD/MM/YYYY HH:mm:ss or dddd, MMMM D",
|
||||
"examples_label": "Examples of valid Day.js formats:",
|
||||
"example_default": "Default-like"
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ import LanguageOptions from "./options/i18n/language.js";
|
||||
import type BasicWidget from "../basic_widget.js";
|
||||
import CodeTheme from "./options/code_notes/code_theme.js";
|
||||
import RelatedSettings from "./options/related_settings.js";
|
||||
import DateTimeFormatOptions from "./options/text_notes/date_time_format.js";
|
||||
|
||||
const TPL = /*html*/`<div class="note-detail-content-widget note-detail-printable">
|
||||
<style>
|
||||
@ -83,6 +84,7 @@ const CONTENT_WIDGETS: Record<OptionPages | "_backendLog", (typeof NoteContextAw
|
||||
KeyboardShortcutsOptions
|
||||
],
|
||||
_optionsTextNotes: [
|
||||
DateTimeFormatOptions,
|
||||
EditorOptions,
|
||||
HeadingStyleOptions,
|
||||
CodeBlockOptions,
|
||||
|
@ -266,7 +266,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
}
|
||||
|
||||
item.on("change:isOpen", () => {
|
||||
if (!("isOpen" in item) || !item.isOpen ) {
|
||||
if (!("isOpen" in item) || !item.isOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -375,9 +375,24 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
}
|
||||
}
|
||||
|
||||
insertDateTimeToTextCommand() {
|
||||
async insertDateTimeToTextCommand() {
|
||||
const date = new Date();
|
||||
const dateString = utils.formatDateTime(date);
|
||||
let userPreferredFormat = "";
|
||||
|
||||
try {
|
||||
|
||||
await options.initializedPromise;
|
||||
|
||||
const customFormatFromSettings = options.get("customDateTimeFormatString");
|
||||
|
||||
if (typeof customFormatFromSettings === 'string') {
|
||||
userPreferredFormat = customFormatFromSettings;
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error("TriliumNext: Error during options initialization or getting custom date/time format. Using default.", e);
|
||||
}
|
||||
|
||||
const dateString = utils.formatDateTime(date, userPreferredFormat);
|
||||
|
||||
this.addTextToEditor(dateString);
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
import OptionsWidget from "../options_widget.js";
|
||||
import { t } from "../../../../services/i18n.js";
|
||||
import type { OptionMap } from "@triliumnext/commons";
|
||||
|
||||
|
||||
const TPL = /*html*/`
|
||||
<div class="options-section">
|
||||
<h4>${t("custom_date_time_format.title")}</h4>
|
||||
|
||||
<p>
|
||||
${t("custom_date_time_format.desc1")}
|
||||
${t("custom_date_time_format.desc2")}
|
||||
</p>
|
||||
<p>
|
||||
<strong>${t("custom_date_time_format.important_label")}</strong>
|
||||
${t("custom_date_time_format.desc3")}
|
||||
</p>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="customDateTimeFormatInput" style="margin-right: 10px;">
|
||||
${t("custom_date_time_format.format_string_label")}
|
||||
</label>
|
||||
<input type="text" id="customDateTimeFormatInput" class="form-control custom-datetime-format-input"
|
||||
placeholder="${t("custom_date_time_format.placeholder")}"
|
||||
style="width: 300px; display: inline-block;">
|
||||
</div>
|
||||
<p style="margin-top: 5px;">
|
||||
<em>${t("custom_date_time_format.examples_label")}</em>
|
||||
<code>YYYY-MM-DD HH:mm</code> (${t("custom_date_time_format.example_default")}),
|
||||
<code>DD.MM.YYYY</code>,
|
||||
<code>MMMM D, YYYY h:mm A</code>,
|
||||
<code>[Today is] dddd</code>
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
export default class DateTimeFormatOptions extends OptionsWidget {
|
||||
|
||||
private $formatInput!: JQuery<HTMLInputElement>;
|
||||
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$formatInput = this.$widget.find(
|
||||
"input.custom-datetime-format-input"
|
||||
) as JQuery<HTMLInputElement>;
|
||||
|
||||
this.$formatInput.on("input", () => {
|
||||
const formatString = this.$formatInput.val() as string;
|
||||
this.updateOption("customDateTimeFormatString", formatString);
|
||||
});
|
||||
|
||||
return this.$widget;
|
||||
}
|
||||
|
||||
async optionsLoaded(options: OptionMap) {
|
||||
const currentFormat = options.customDateTimeFormatString || "";
|
||||
|
||||
if (this.$formatInput) {
|
||||
this.$formatInput.val(currentFormat);
|
||||
} else {
|
||||
|
||||
console.warn(
|
||||
"TriliumNext DateTimeFormatOptions: $formatInput not initialized when optionsLoaded was called. Attempting to find again."
|
||||
);
|
||||
const inputField = this.$widget?.find(
|
||||
"input.custom-datetime-format-input"
|
||||
) as JQuery<HTMLInputElement> | undefined;
|
||||
|
||||
if (inputField?.length) {
|
||||
this.$formatInput = inputField;
|
||||
this.$formatInput.val(currentFormat);
|
||||
} else {
|
||||
console.error(
|
||||
"TriliumNext DateTimeFormatOptions: Could not find format input field in optionsLoaded."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -90,6 +90,7 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
|
||||
"redirectBareDomain",
|
||||
"showLoginInShareTheme",
|
||||
"splitEditorOrientation",
|
||||
"customDateTimeFormatString",
|
||||
|
||||
// AI/LLM integration options
|
||||
"aiEnabled",
|
||||
|
@ -47,6 +47,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
|
||||
passwordDerivedKeySalt: string;
|
||||
encryptedDataKey: string;
|
||||
hoistedNoteId: string;
|
||||
customDateTimeFormatString: string;
|
||||
|
||||
// Multi-Factor Authentication
|
||||
mfaEnabled: boolean;
|
||||
|
Loading…
x
Reference in New Issue
Block a user