Get most of the prompt to create new tables working, and keeping the Dice namespace restricted to a certain bucket type

This commit is contained in:
Oliver-Akins 2025-05-01 23:02:36 -06:00
parent 8c9fd1930a
commit dfc75fceaf
8 changed files with 73 additions and 19 deletions

View file

@ -1,4 +1,5 @@
import { Chart } from "chart.js"; import { Chart } from "chart.js";
import { diceSizeSorter } from "../utils/sorters/diceSize.mjs";
import { filePath } from "../consts.mjs"; import { filePath } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { smallToLarge } from "../utils/sorters/smallToLarge.mjs"; import { smallToLarge } from "../utils/sorters/smallToLarge.mjs";
@ -36,7 +37,7 @@ export class StatsViewer extends HandlebarsApplicationMixin(ApplicationV2) {
static PARTS = { static PARTS = {
tableSelect: { tableSelect: {
template: filePath(`templates/Apps/StatsViewer/tableSelect.hbs`), template: filePath(`templates/Apps/common/tableSelect.hbs`),
}, },
dataFilters: { dataFilters: {
template: filePath(`templates/Apps/StatsViewer/dataFilters.hbs`), template: filePath(`templates/Apps/StatsViewer/dataFilters.hbs`),
@ -138,6 +139,14 @@ export class StatsViewer extends HandlebarsApplicationMixin(ApplicationV2) {
ctx.tables = tableList; ctx.tables = tableList;
const subtableList = subtables[this._selectedTable]; const subtableList = subtables[this._selectedTable];
// Sort the subtables to be sane
if (this._selectedTable === `Dice`) {
subtableList?.sort(diceSizeSorter);
} else {
subtableList?.sort(smallToLarge);
}
if (!subtableList) { if (!subtableList) {
this._selectedSubtable = undefined; this._selectedSubtable = undefined;
} else if (!subtableList.includes(this._selectedSubtable)) { } else if (!subtableList.includes(this._selectedSubtable)) {

View file

@ -1,4 +1,5 @@
import { BucketTypes } from "../utils/validateValue.mjs"; import { BucketTypes } from "../utils/validateValue.mjs";
import { createDiceTable } from "../utils/databases/utils.mjs";
import { filePath } from "../consts.mjs"; import { filePath } from "../consts.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
@ -20,7 +21,7 @@ export class TableCreator extends HandlebarsApplicationMixin(ApplicationV2) {
}, },
position: { position: {
width: 320, width: 320,
height: 206, height: `auto`,
}, },
actions: { actions: {
createTable: this.#createTable, createTable: this.#createTable,
@ -52,9 +53,12 @@ export class TableCreator extends HandlebarsApplicationMixin(ApplicationV2) {
}; };
}; };
/** @type {string} */
_name = ``; _name = ``;
/** @type {string} */
_type = BucketTypes.NUMBER; _type = BucketTypes.NUMBER;
async _preparePartContext(partId) { #diceNamespaceAlert = null;
async _preparePartContext() {
const ctx = {}; const ctx = {};
ctx.meta = { ctx.meta = {
idp: this.id, idp: this.id,
@ -62,8 +66,21 @@ export class TableCreator extends HandlebarsApplicationMixin(ApplicationV2) {
ctx.name = this._name; ctx.name = this._name;
ctx.type = this._type; ctx.type = this._type;
ctx.typeDisabled = false;
ctx.types = Object.values(BucketTypes); ctx.types = Object.values(BucketTypes);
// Special Case for the dice namespace
if (this._name.startsWith(`Dice`)) {
ctx.typeDisabled = true;
ctx.type = BucketTypes.RANGE;
this.#diceNamespaceAlert = ui.notifications.info(
`Tables in the "Dice" namespace must be formatted as "Dice/dX" where X is the number of sides on the die and are restricted to be ranges 1 to X.`,
{ permanent: true },
);
} else if (this.#diceNamespaceAlert != null) {
ui.notifications.remove(this.#diceNamespaceAlert);
};
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
Logger.log(`Context`, ctx); Logger.log(`Context`, ctx);
}; };
@ -89,8 +106,25 @@ export class TableCreator extends HandlebarsApplicationMixin(ApplicationV2) {
}; };
static async #createTable() { static async #createTable() {
if (this._name === ``) { /** @type {string} */
const name = this._name;
if (name === ``) {
ui.notifications.error(`Cannot create a table without a name`); ui.notifications.error(`Cannot create a table without a name`);
}; };
const existing = CONFIG.StatsDatabase.getTable(name);
if (existing) {
ui.notifications.error(`A table with the name "${name}" already exists`);
};
if (name.startsWith(`Dice`)) {
if (!name.match(/^Dice\/d[0-9]+$/)) {
ui.notifications.error(`Table name doesn't conform to the "Dice/dX" format required by the Dice namespace.`);
return;
};
const size = Number(name.replace(`Dice/d`, ``));
CONFIG.StatsDatabase.createTable(createDiceTable(size));
return;
};
}; };
}; };

View file

@ -1,18 +1,4 @@
function createDiceTable(size) { import { createDiceTable } from "../utils/databases/utils.mjs";
return {
name: `Dice/d${size}`,
buckets: {
type: `range`,
min: 1,
max: size,
step: 1,
},
graph: {
type: `bar`,
stacked: true,
},
};
};
export function registerMetaSettings() { export function registerMetaSettings() {
game.settings.register(__ID__, `tables`, { game.settings.register(__ID__, `tables`, {

View file

@ -74,6 +74,10 @@ export class MemoryDatabase extends Database {
static #rows = {}; static #rows = {};
static createTable(tableConfig) {
this.#tables[tableConfig.name] = tableConfig;
};
/** @returns {Array<Table>} */ /** @returns {Array<Table>} */
static getTables() { static getTables() {
return Object.values(this.#tables); return Object.values(this.#tables);

View file

@ -0,0 +1,15 @@
export function createDiceTable(size) {
return {
name: `Dice/d${size}`,
buckets: {
type: `range`,
min: 1,
max: size,
step: 1,
},
graph: {
type: `bar`,
stacked: true,
},
};
};

View file

@ -0,0 +1,5 @@
export function diceSizeSorter(a, b) {
const aInt = Number(a.slice(1));
const bInt = Number(b.slice(1));
return Math.sign(aInt - bInt);
};

View file

@ -17,6 +17,7 @@
<select <select
id="{{meta.idp}}-type" id="{{meta.idp}}-type"
data-bind="_type" data-bind="_type"
{{ disabled typeDisabled }}
> >
{{ st-options type types }} {{ st-options type types }}
</select> </select>