Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { describe, expect, it } from "vitest";
import { form } from "./field";

describe.concurrent("$helper.field.form()", () => {
// TODO: Remove once window.panel is globally typed
// @ts-expect-error - window.panel is not typed yet
// mock the app with the component setup
window.panel = {
app: {
Expand Down
70 changes: 44 additions & 26 deletions panel/src/helpers/field.js → panel/src/helpers/field.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { clone } from "./object.js";
import { clone } from "./object";

type Field = Record<string, unknown>;

/**
* Loads the default value for a field definition
* @unstable
*
* @param {Object} field
* @returns {mixed}
* @example
* defaultValue({ type: "text", default: "Hello" }) // => "Hello"
* defaultValue({ type: "text" }) // => null
*/
export function defaultValue(field) {
export function defaultValue(field: Field): unknown {
if (field.default !== undefined) {
return clone(field.default);
}

const component =
window.panel.app.$options.components[`k-${field.type}-field`];

// TODO: Remove once window.panel is globally typed
// @ts-expect-error - window.panel has no type yet
const options = window.panel.app.$options;
const component = options.components[`k-${field.type}-field`];
const valueProp = component?.options.props?.value;

// if the field has no value prop,
Expand All @@ -41,11 +45,12 @@ export function defaultValue(field) {
* Creates form values for provided fields
* @unstable
*
* @param {Object} fields
* @returns {Object}
* @example
* form({ title: { type: "text", default: "Hello" }, age: { type: "number" } })
* // => { title: "Hello" }
*/
export function form(fields) {
const form = {};
export function form(fields: Record<string, Field>): Record<string, unknown> {
const form: Record<string, unknown> = {};

for (const fieldName in fields) {
const defaultVal = defaultValue(fields[fieldName]);
Expand All @@ -63,11 +68,17 @@ export function form(fields) {
* and the current form values. Also works for sections.
* @unstable
*
* @param {Object} field - The form field object
* @param {Object} values - The current form values object
* @returns {boolean} - Whether the field is visible or not
* @example
* isVisible({ type: "text", when: { status: "draft" } }, { status: "draft" }) // => true
* isVisible({ type: "text", when: { status: "draft" } }, { status: "published" }) // => false
*
* @param field - The form field object
* @param values - The current form values object
*/
export function isVisible(field, values) {
export function isVisible(
field: Field,
values: Record<string, unknown>
): boolean {
if (field.type === "hidden" || field.hidden === true) {
return false;
}
Expand All @@ -76,9 +87,11 @@ export function isVisible(field, values) {
return true;
}

for (const key in field.when) {
const when = field.when as Record<string, unknown>;

for (const key in when) {
const value = values[key.toLowerCase()];
const condition = field.when[key];
const condition = when[key];

// if condition is checking for empty field
if (
Expand All @@ -100,24 +113,29 @@ export function isVisible(field, values) {
* Adds proper endpoint and section definitions
* to subfields for a form field.
* @unstable
*
* @param {object} field
* @param {object} fields
* @returns {object}
*/
export function subfields(field, fields) {
let subfields = {};
export function subfields(
field: Field,
fields: Record<string, Field>
): Record<string, Field> {
const subfields: Record<string, Field> = {};

for (const name in fields) {
const subfield = fields[name];

subfield.section = field.name;

if (field.endpoints) {
const endpoints = field.endpoints as {
field: string;
section: string;
model: string;
};

subfield.endpoints = {
field: field.endpoints.field + "+" + name,
section: field.endpoints.section,
model: field.endpoints.model
field: endpoints.field + "+" + name,
section: endpoints.section,
model: endpoints.model
};
}

Expand Down
2 changes: 1 addition & 1 deletion panel/src/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import clipboard from "./clipboard.js";
import color from "./color.js";
import debounce from "./debounce";
import embed from "./embed";
import field from "./field.js";
import field from "./field";
import file from "./file.js";
import focus from "./focus.js";
import isComponent from "./isComponent";
Expand Down