feat(editor): Add examples for object and array expression methods (#9360)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
Elias Meire
2024-05-14 16:32:31 +02:00
committed by GitHub
parent 78e7c7a9da
commit 52936633af
11 changed files with 890 additions and 193 deletions

View File

@@ -466,9 +466,20 @@ const stringOptions = (input: AutocompleteInput<string>): Completion[] => {
]);
if (resolved && validateFieldType('string', resolved, 'number').valid) {
const recommended = ['toNumber()'];
const timestampUnit = toTimestampUnit(Number(resolved));
if (timestampUnit) {
return applySections({
options,
recommended: [...recommended, { label: 'toDateTime()', args: [`'${timestampUnit}'`] }],
sections: STRING_SECTIONS,
});
}
return applySections({
options,
recommended: ['toNumber()'],
recommended,
sections: STRING_SECTIONS,
});
}
@@ -541,6 +552,29 @@ const booleanOptions = (): Completion[] => {
});
};
const isWithinMargin = (ts: number, now: number, margin: number): boolean => {
return ts > now - margin && ts < now + margin;
};
const toTimestampUnit = (ts: number): null | 'ms' | 's' | 'us' => {
const nowMillis = Date.now();
const marginMillis = 946_707_779_000; // 30y
if (isWithinMargin(ts, nowMillis, marginMillis)) {
return 'ms';
}
if (isWithinMargin(ts, nowMillis / 1000, marginMillis / 1000)) {
return 's';
}
if (isWithinMargin(ts, nowMillis * 1000, marginMillis * 1000)) {
return 'us';
}
return null;
};
const numberOptions = (input: AutocompleteInput<number>): Completion[] => {
const { resolved, transformLabel } = input;
const options = sortCompletionsAlpha([
@@ -550,26 +584,11 @@ const numberOptions = (input: AutocompleteInput<number>): Completion[] => {
const ONLY_INTEGER = ['isEven()', 'isOdd()'];
if (Number.isInteger(resolved)) {
const nowMillis = Date.now();
const marginMillis = 946_707_779_000; // 30y
const isPlausableMillisDateTime =
resolved > nowMillis - marginMillis && resolved < nowMillis + marginMillis;
if (isPlausableMillisDateTime) {
const timestampUnit = toTimestampUnit(resolved);
if (timestampUnit) {
return applySections({
options,
recommended: [{ label: 'toDateTime()', args: ["'ms'"] }],
});
}
const nowSeconds = nowMillis / 1000;
const marginSeconds = marginMillis / 1000;
const isPlausableSecondsDateTime =
resolved > nowSeconds - marginSeconds && resolved < nowSeconds + marginSeconds;
if (isPlausableSecondsDateTime) {
return applySections({
options,
recommended: [{ label: 'toDateTime()', args: ["'s'"] }],
recommended: [{ label: 'toDateTime()', args: [`'${timestampUnit}'`] }],
});
}

View File

@@ -110,6 +110,66 @@ const renderDescription = ({
return descriptionBody;
};
const renderArg = (arg: DocMetadataArgument) => {
const argItem = document.createElement('li');
const argName = document.createElement('span');
argName.classList.add('autocomplete-info-arg-name');
argName.textContent = arg.name.replaceAll('?', '');
const tags = [];
if (arg.type) {
tags.push(arg.type);
}
if (!!arg.optional || arg.name.endsWith('?')) {
tags.push(i18n.baseText('codeNodeEditor.optional'));
}
if (tags.length > 0) {
argName.textContent += ` (${tags.join(', ')})`;
}
if (arg.description) {
argName.textContent += ':';
}
argItem.appendChild(argName);
if (arg.description) {
const argDescription = document.createElement('span');
argDescription.classList.add('autocomplete-info-arg-description');
if (arg.default && arg.optional && !arg.description.toLowerCase().includes('default')) {
const separator = arg.description.endsWith('.') ? ' ' : '. ';
arg.description +=
separator +
i18n.baseText('codeNodeEditor.defaultsTo', {
interpolate: { default: arg.default },
});
}
argDescription.innerHTML = sanitizeHtml(arg.description.replace(/`(.*?)`/g, '<code>$1</code>'));
argItem.appendChild(argDescription);
}
if (Array.isArray(arg.args)) {
argItem.appendChild(renderArgList(arg.args));
}
return argItem;
};
const renderArgList = (args: DocMetadataArgument[]) => {
const argsList = document.createElement('ul');
argsList.classList.add('autocomplete-info-args');
for (const arg of args) {
argsList.appendChild(renderArg(arg));
}
return argsList;
};
const renderArgs = (args: DocMetadataArgument[]) => {
const argsContainer = document.createElement('div');
argsContainer.classList.add('autocomplete-info-args-container');
@@ -118,58 +178,7 @@ const renderArgs = (args: DocMetadataArgument[]) => {
argsTitle.classList.add('autocomplete-info-section-title');
argsTitle.textContent = i18n.baseText('codeNodeEditor.parameters');
argsContainer.appendChild(argsTitle);
const argsList = document.createElement('ul');
argsList.classList.add('autocomplete-info-args');
for (const arg of args.filter((a) => a.name !== '...')) {
const argItem = document.createElement('li');
const argName = document.createElement('span');
argName.classList.add('autocomplete-info-arg-name');
argName.textContent = arg.name.replaceAll('?', '');
const tags = [];
if (arg.type) {
tags.push(arg.type);
}
if (arg.optional || arg.name.endsWith('?')) {
tags.push(i18n.baseText('codeNodeEditor.optional'));
}
if (args.length > 0) {
argName.textContent += ` (${tags.join(', ')})`;
}
if (arg.description) {
argName.textContent += ':';
}
argItem.appendChild(argName);
if (arg.description) {
const argDescription = document.createElement('span');
argDescription.classList.add('autocomplete-info-arg-description');
if (arg.default && !arg.description.toLowerCase().includes('default')) {
const separator = arg.description.endsWith('.') ? ' ' : '. ';
arg.description +=
separator +
i18n.baseText('codeNodeEditor.defaultsTo', {
interpolate: { default: arg.default },
});
}
argDescription.innerHTML = sanitizeHtml(
arg.description.replace(/`(.*?)`/g, '<code>$1</code>'),
);
argItem.appendChild(argDescription);
}
argsList.appendChild(argItem);
}
argsContainer.appendChild(argsList);
argsContainer.appendChild(renderArgList(args));
return argsContainer;
};

View File

@@ -197,6 +197,11 @@
li + li {
margin-top: var(--spacing-4xs);
}
.autocomplete-info-args {
margin-top: var(--spacing-4xs);
padding-left: var(--spacing-s);
}
}
.autocomplete-info-arg-name {