Start working on the dialog to make a new table
This commit is contained in:
parent
46a9d46e9a
commit
a3900a6c7c
8 changed files with 186 additions and 5 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import { filePath } from "../consts.mjs";
|
import { filePath } from "../consts.mjs";
|
||||||
import { StatsViewer } from "./StatsViewer.mjs";
|
import { StatsViewer } from "./StatsViewer.mjs";
|
||||||
|
import { TableCreator } from "./TableCreator.mjs";
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
const { AbstractSidebarTab } = foundry.applications.sidebar;
|
const { AbstractSidebarTab } = foundry.applications.sidebar;
|
||||||
|
|
@ -16,6 +17,7 @@ export class StatSidebar extends HandlebarsApplicationMixin(AbstractSidebarTab)
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
openStats: this.#openStats,
|
openStats: this.#openStats,
|
||||||
|
createTable: this.#createTable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -44,4 +46,10 @@ export class StatSidebar extends HandlebarsApplicationMixin(AbstractSidebarTab)
|
||||||
const app = new StatsViewer();
|
const app = new StatsViewer();
|
||||||
app.render({ force: true });
|
app.render({ force: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @this {StatSidebar} */
|
||||||
|
static async #createTable() {
|
||||||
|
const app = new TableCreator;
|
||||||
|
app.render({ force: true });
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
96
module/Apps/TableCreator.mjs
Normal file
96
module/Apps/TableCreator.mjs
Normal 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`);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -26,8 +26,14 @@ export function validateValue(value, options) {
|
||||||
return !error;
|
return !error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const BucketTypes = {
|
||||||
|
STRING: `string`,
|
||||||
|
NUMBER: `number`,
|
||||||
|
RANGE: `range`,
|
||||||
|
};
|
||||||
|
|
||||||
const validatorTypes = {
|
const validatorTypes = {
|
||||||
string: {
|
[BucketTypes.STRING]: {
|
||||||
field: StringField,
|
field: StringField,
|
||||||
transformOptions: (opts) => {
|
transformOptions: (opts) => {
|
||||||
delete opts.type;
|
delete opts.type;
|
||||||
|
|
@ -40,20 +46,28 @@ const validatorTypes = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
number: {
|
[BucketTypes.NUMBER]: {
|
||||||
field: NumberField,
|
field: NumberField,
|
||||||
transformOptions: (opts) => {
|
transformOptions: (opts) => {
|
||||||
delete opts.type;
|
delete opts.type;
|
||||||
opts.nullable = false;
|
opts.nullable = false;
|
||||||
opts.integer = true;
|
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,
|
field: NumberField,
|
||||||
transformOptions: (opts) => {
|
transformOptions: (opts) => {
|
||||||
delete opts.type;
|
delete opts.type;
|
||||||
opts.nullable = false;
|
opts.nullable = false;
|
||||||
opts.integer = true;
|
opts.integer = true;
|
||||||
|
if (typeof opts.choices === `function`) {
|
||||||
|
Logger.error(`Choices cannot be a function in a table's buckets configuraion`);
|
||||||
|
delete opts.choices;
|
||||||
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
.stats-sidebar {
|
.stats-sidebar {
|
||||||
|
|
||||||
|
&.active {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
}
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 2rem;
|
gap: 2rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
|
|
||||||
23
public/styles/Apps/TableCreator.css
Normal file
23
public/styles/Apps/TableCreator.css
Normal file
|
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,3 +4,4 @@
|
||||||
|
|
||||||
@import url("./Apps/StatsViewer.css") layer(apps);
|
@import url("./Apps/StatsViewer.css") layer(apps);
|
||||||
@import url("./Apps/StatsSidebar.css") layer(apps);
|
@import url("./Apps/StatsSidebar.css") layer(apps);
|
||||||
|
@import url("./Apps/TableCreator.css") layer(apps);
|
||||||
|
|
@ -26,6 +26,12 @@
|
||||||
>
|
>
|
||||||
View Statistics
|
View Statistics
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-action="createTable"
|
||||||
|
>
|
||||||
|
Create New Table
|
||||||
|
</button>
|
||||||
<button type="button">Manage Tables</button>
|
<button type="button">Manage Tables</button>
|
||||||
<button type="button">Manage Rows</button>
|
<button type="button">Manage Rows</button>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
30
public/templates/Apps/TableCreator.hbs
Normal file
30
public/templates/Apps/TableCreator.hbs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<div class="group">
|
||||||
|
<label for="{{meta.idp}}-name">
|
||||||
|
Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="{{meta.idp}}-name"
|
||||||
|
type="text"
|
||||||
|
value="{{ name }}"
|
||||||
|
data-bind="_name"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="group">
|
||||||
|
<label for="{{meta.idp}}-type">
|
||||||
|
Type
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
id="{{meta.idp}}-type"
|
||||||
|
data-bind="_type"
|
||||||
|
>
|
||||||
|
{{ st-options type types }}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-action="createTable"
|
||||||
|
>
|
||||||
|
Create Table
|
||||||
|
</button>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue