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:
@@ -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}'`] }],
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user