Start working on the dialog to make a new table

This commit is contained in:
Oliver-Akins 2025-04-30 22:51:03 -06:00
parent 46a9d46e9a
commit a3900a6c7c
8 changed files with 186 additions and 5 deletions

View file

@ -1,5 +1,6 @@
import { filePath } from "../consts.mjs";
import { StatsViewer } from "./StatsViewer.mjs";
import { TableCreator } from "./TableCreator.mjs";
const { HandlebarsApplicationMixin } = foundry.applications.api;
const { AbstractSidebarTab } = foundry.applications.sidebar;
@ -16,6 +17,7 @@ export class StatSidebar extends HandlebarsApplicationMixin(AbstractSidebarTab)
},
actions: {
openStats: this.#openStats,
createTable: this.#createTable,
},
};
@ -44,4 +46,10 @@ export class StatSidebar extends HandlebarsApplicationMixin(AbstractSidebarTab)
const app = new StatsViewer();
app.render({ force: true });
};
/** @this {StatSidebar} */
static async #createTable() {
const app = new TableCreator;
app.render({ force: true });
};
};

View file

@ -0,0 +1,96 @@
import { BucketTypes } from "../utils/validateValue.mjs";
import { filePath } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
export class TableCreator extends HandlebarsApplicationMixin(ApplicationV2) {
// #region Options
static DEFAULT_OPTIONS = {
classes: [
__ID__,
`TableCreator`,
],
window: {
title: `Create Table`,
frame: true,
positioned: true,
resizable: false,
minimizable: true,
},
position: {
width: 320,
height: 206,
},
actions: {
createTable: this.#createTable,
},
};
static PARTS = {
tableSelect: {
template: filePath(`templates/Apps/TableCreator.hbs`),
root: true,
},
};
// #endregion
async render({ userUpdated, ...opts } = {}) {
if (userUpdated && !this._selectedUsers.includes(userUpdated)) {
return;
}
await super.render(opts);
};
async _onRender(context, options) {
await super._onRender(context, options);
const elements = this.element
.querySelectorAll(`[data-bind]`);
for (const input of elements) {
input.addEventListener(`change`, this.#bindListener.bind(this));
};
};
_name = ``;
_type = BucketTypes.NUMBER;
async _preparePartContext(partId) {
const ctx = {};
ctx.meta = {
idp: this.id,
};
ctx.name = this._name;
ctx.type = this._type;
ctx.types = Object.values(BucketTypes);
if (import.meta.env.DEV) {
Logger.log(`Context`, ctx);
};
return ctx;
};
/**
* @param {Event} event
*/
async #bindListener(event) {
const target = event.target;
const data = target.dataset;
const binding = data.bind;
if (!binding || !Object.hasOwn(this, binding)) {
Logger.debug(`Skipping change for element with binding "${binding}"`);
return;
};
Logger.log(`updating ${binding} value to ${target.value}`);
this[binding] = target.value;
this.render();
};
static async #createTable() {
if (this._name === ``) {
ui.notifications.error(`Cannot create a table without a name`);
};
};
};

View file

@ -26,8 +26,14 @@ export function validateValue(value, options) {
return !error;
};
export const BucketTypes = {
STRING: `string`,
NUMBER: `number`,
RANGE: `range`,
};
const validatorTypes = {
string: {
[BucketTypes.STRING]: {
field: StringField,
transformOptions: (opts) => {
delete opts.type;
@ -40,20 +46,28 @@ const validatorTypes = {
};
},
},
number: {
[BucketTypes.NUMBER]: {
field: NumberField,
transformOptions: (opts) => {
delete opts.type;
opts.nullable = false;
opts.integer = true;
if (typeof opts.choices === `function`) {
Logger.error(`Choices cannot be a function in a table's buckets configuraion`);
delete opts.choices;
};
},
},
range: {
[BucketTypes.RANGE]: {
field: NumberField,
transformOptions: (opts) => {
delete opts.type;
opts.nullable = false;
opts.integer = true;
if (typeof opts.choices === `function`) {
Logger.error(`Choices cannot be a function in a table's buckets configuraion`);
delete opts.choices;
};
},
},
};