From a3900a6c7c3debcca8b00337319b6c75dfc46a92 Mon Sep 17 00:00:00 2001 From: Oliver-Akins Date: Wed, 30 Apr 2025 22:51:03 -0600 Subject: [PATCH] Start working on the dialog to make a new table --- module/Apps/StatSidebar.mjs | 8 ++ module/Apps/TableCreator.mjs | 96 ++++++++++++++++++++++ module/utils/validateValue.mjs | 20 ++++- public/styles/Apps/StatsSidebar.css | 5 +- public/styles/Apps/TableCreator.css | 23 ++++++ public/styles/main.css | 3 +- public/templates/Apps/StatSidebar/main.hbs | 6 ++ public/templates/Apps/TableCreator.hbs | 30 +++++++ 8 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 module/Apps/TableCreator.mjs create mode 100644 public/styles/Apps/TableCreator.css create mode 100644 public/templates/Apps/TableCreator.hbs diff --git a/module/Apps/StatSidebar.mjs b/module/Apps/StatSidebar.mjs index 93e90ab..ce8f0eb 100644 --- a/module/Apps/StatSidebar.mjs +++ b/module/Apps/StatSidebar.mjs @@ -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 }); + }; }; diff --git a/module/Apps/TableCreator.mjs b/module/Apps/TableCreator.mjs new file mode 100644 index 0000000..ba55600 --- /dev/null +++ b/module/Apps/TableCreator.mjs @@ -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`); + }; + }; +}; diff --git a/module/utils/validateValue.mjs b/module/utils/validateValue.mjs index 4440d96..3c51987 100644 --- a/module/utils/validateValue.mjs +++ b/module/utils/validateValue.mjs @@ -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; + }; }, }, }; diff --git a/public/styles/Apps/StatsSidebar.css b/public/styles/Apps/StatsSidebar.css index 59506f3..eb41421 100644 --- a/public/styles/Apps/StatsSidebar.css +++ b/public/styles/Apps/StatsSidebar.css @@ -1,5 +1,8 @@ .stats-sidebar { - display: flex; + + &.active { + display: flex; + } flex-direction: column; gap: 2rem; padding: 1rem; diff --git a/public/styles/Apps/TableCreator.css b/public/styles/Apps/TableCreator.css new file mode 100644 index 0000000..3500b6a --- /dev/null +++ b/public/styles/Apps/TableCreator.css @@ -0,0 +1,23 @@ +.TableCreator { + .window-content { + display: flex; + flex-direction: column; + gap: 1rem; + } + + .group { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 3fr); + gap: 0.5rem; + } + + label { + color: var(--color-form-label); + font-weight: bold; + line-height: var(--input-height); + } + + button { + height: calc(1.25 * var(--input-height)); + } +} \ No newline at end of file diff --git a/public/styles/main.css b/public/styles/main.css index b8e4b39..4a4eea0 100644 --- a/public/styles/main.css +++ b/public/styles/main.css @@ -3,4 +3,5 @@ @import url("./elements/custom-multi-select.css") layer(elements); @import url("./Apps/StatsViewer.css") layer(apps); -@import url("./Apps/StatsSidebar.css") layer(apps); \ No newline at end of file +@import url("./Apps/StatsSidebar.css") layer(apps); +@import url("./Apps/TableCreator.css") layer(apps); \ No newline at end of file diff --git a/public/templates/Apps/StatSidebar/main.hbs b/public/templates/Apps/StatSidebar/main.hbs index 1b8d89e..4487cd9 100644 --- a/public/templates/Apps/StatSidebar/main.hbs +++ b/public/templates/Apps/StatSidebar/main.hbs @@ -26,6 +26,12 @@ > View Statistics + diff --git a/public/templates/Apps/TableCreator.hbs b/public/templates/Apps/TableCreator.hbs new file mode 100644 index 0000000..b32e950 --- /dev/null +++ b/public/templates/Apps/TableCreator.hbs @@ -0,0 +1,30 @@ +
+ + +
+ +
+ + +
+ +