Initial
This commit is contained in:
2
resources/app/client-esm/applications/apps/_module.mjs
Normal file
2
resources/app/client-esm/applications/apps/_module.mjs
Normal file
@@ -0,0 +1,2 @@
|
||||
export {default as CompendiumArtConfig} from "./compendium-art-config.mjs";
|
||||
export {default as PermissionConfig} from "./permission-config.mjs";
|
||||
@@ -0,0 +1,105 @@
|
||||
import HandlebarsApplicationMixin from "../api/handlebars-application.mjs";
|
||||
import ApplicationV2 from "../api/application.mjs";
|
||||
|
||||
/**
|
||||
* An application for configuring compendium art priorities.
|
||||
* @extends ApplicationV2
|
||||
* @mixes HandlebarsApplication
|
||||
* @alias CompendiumArtConfig
|
||||
*/
|
||||
export default class CompendiumArtConfig extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
/** @override */
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: "compendium-art-config",
|
||||
tag: "form",
|
||||
window: {
|
||||
contentClasses: ["standard-form"],
|
||||
icon: "fas fa-palette",
|
||||
title: "COMPENDIUM.ART.SETTING.Title"
|
||||
},
|
||||
position: {
|
||||
width: 600,
|
||||
height: "auto"
|
||||
},
|
||||
form: {
|
||||
closeOnSubmit: true,
|
||||
handler: CompendiumArtConfig.#onSubmit
|
||||
},
|
||||
actions: {
|
||||
priority: CompendiumArtConfig.#onAdjustPriority
|
||||
}
|
||||
};
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
priorities: {
|
||||
id: "priorities",
|
||||
template: "templates/apps/compendium-art-config.hbs"
|
||||
},
|
||||
footer: {
|
||||
template: "templates/generic/form-footer.hbs"
|
||||
}
|
||||
};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Rendering */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(_options={}) {
|
||||
return {
|
||||
config: game.compendiumArt.getPackages(),
|
||||
buttons: [{ type: "submit", icon: "fas fa-save", label: "SETUP.SaveConfiguration" }]
|
||||
};
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Event Handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Adjust the priority of a package.
|
||||
* @this {ApplicationV2}
|
||||
* @param {MouseEvent} _event The click event.
|
||||
* @param {HTMLButtonElement} target The button that was clicked.
|
||||
*/
|
||||
static async #onAdjustPriority(_event, target) {
|
||||
const row = target.closest("[data-package-id]");
|
||||
const { packageId } = row.dataset;
|
||||
const configs = [];
|
||||
for ( const element of this.element.elements ) {
|
||||
const [id, key] = element.name.split(".");
|
||||
if ( key === "priority" ) configs.push({ packageId: id, priority: Number(element.value) });
|
||||
}
|
||||
const idx = configs.findIndex(config => config.packageId === packageId);
|
||||
if ( idx < 0 ) return;
|
||||
const sortBefore = "increase" in target.dataset;
|
||||
if ( sortBefore && (idx === 0) ) return;
|
||||
if ( !sortBefore && (idx >= configs.length - 1) ) return;
|
||||
const config = configs[idx];
|
||||
const sortTarget = configs[sortBefore ? idx - 1 : idx + 1];
|
||||
configs.splice(idx, 1);
|
||||
const updates = SortingHelpers.performIntegerSort(config, {
|
||||
sortBefore, target: sortTarget, siblings: configs, sortKey: "priority"
|
||||
});
|
||||
updates.forEach(({ target, update }) => {
|
||||
this.element.elements[`${target.packageId}.priority`].value = update.priority;
|
||||
});
|
||||
if ( sortBefore ) row.previousElementSibling.insertAdjacentElement("beforebegin", row);
|
||||
else row.nextElementSibling.insertAdjacentElement("afterend", row);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Save the compendium art configuration.
|
||||
* @this {ApplicationV2}
|
||||
* @param {SubmitEvent} _event The form submission event.
|
||||
* @param {HTMLFormElement} _form The form element that was submitted.
|
||||
* @param {FormDataExtended} formData Processed data for the submitted form.
|
||||
*/
|
||||
static async #onSubmit(_event, _form, formData) {
|
||||
await game.settings.set("core", game.compendiumArt.SETTING, foundry.utils.expandObject(formData.object));
|
||||
return SettingsConfig.reloadConfirm({ world: true });
|
||||
}
|
||||
}
|
||||
152
resources/app/client-esm/applications/apps/permission-config.mjs
Normal file
152
resources/app/client-esm/applications/apps/permission-config.mjs
Normal file
@@ -0,0 +1,152 @@
|
||||
import ApplicationV2 from "../api/application.mjs";
|
||||
import HandlebarsApplicationMixin from "../api/handlebars-application.mjs";
|
||||
|
||||
/**
|
||||
* An application for configuring the permissions which are available to each User role.
|
||||
* @extends ApplicationV2
|
||||
* @mixes HandlebarsApplication
|
||||
* @alias PermissionConfig
|
||||
*/
|
||||
export default class PermissionConfig extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: "permissions-config",
|
||||
tag: "form",
|
||||
window: {
|
||||
contentClasses: ["standard-form"],
|
||||
icon: "fa-solid fa-shield-keyhole",
|
||||
title: "PERMISSION.Title",
|
||||
},
|
||||
position: {
|
||||
width: 660,
|
||||
height: "auto"
|
||||
},
|
||||
form: {
|
||||
closeOnSubmit: true,
|
||||
handler: PermissionConfig.#onSubmit
|
||||
},
|
||||
actions: {
|
||||
reset: PermissionConfig.#onReset
|
||||
}
|
||||
};
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
permissions: {
|
||||
id: "permissions",
|
||||
template: "templates/apps/permission-config.hbs",
|
||||
scrollable: [".permissions-list"]
|
||||
},
|
||||
footer: {
|
||||
template: "templates/generic/form-footer.hbs"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Rendering */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @override */
|
||||
async _prepareContext(_options={}) {
|
||||
const current = await game.settings.get("core", "permissions");
|
||||
return {
|
||||
roles: Object.keys(CONST.USER_ROLES).reduce((obj, r) => {
|
||||
if ( r === "NONE" ) return obj;
|
||||
obj[r] = `USER.Role${r.titleCase()}`;
|
||||
return obj;
|
||||
}, {}),
|
||||
permissions: this.#preparePermissions(current),
|
||||
buttons: [
|
||||
{type: "reset", action: "reset", icon: "fa-solid fa-sync", label: "PERMISSION.Reset"},
|
||||
{type: "submit", icon: "fa-solid fa-save", label: "PERMISSION.Submit"}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Prepare the permissions object used to render the configuration template
|
||||
* @param {object} current The current permission configuration
|
||||
* @returns {object[]} Permission data for sheet rendering
|
||||
*/
|
||||
#preparePermissions(current) {
|
||||
const r = CONST.USER_ROLES;
|
||||
const rgm = r.GAMEMASTER;
|
||||
|
||||
// Get permissions
|
||||
const perms = Object.entries(CONST.USER_PERMISSIONS).reduce((arr, e) => {
|
||||
const perm = foundry.utils.deepClone(e[1]);
|
||||
perm.id = e[0];
|
||||
perm.label = game.i18n.localize(perm.label);
|
||||
perm.hint = game.i18n.localize(perm.hint);
|
||||
arr.push(perm);
|
||||
return arr;
|
||||
}, []);
|
||||
perms.sort((a, b) => a.label.localeCompare(b.label, game.i18n.lang));
|
||||
|
||||
// Configure permission roles
|
||||
for ( let p of perms ) {
|
||||
const roles = current[p.id] || Array.fromRange(rgm + 1).slice(p.defaultRole);
|
||||
p.roles = Object.values(r).reduce((arr, role) => {
|
||||
if ( role === r.NONE ) return arr;
|
||||
arr.push({
|
||||
name: `${p.id}.${role}`,
|
||||
value: roles.includes(role),
|
||||
readonly: (role === rgm) && (!p.disableGM) ? "readonly" : ""
|
||||
});
|
||||
return arr;
|
||||
}, []);
|
||||
}
|
||||
return perms;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Event Listeners and Handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Handle submission
|
||||
* @this {DocumentSheetV2} The handler is called with the application as its bound scope
|
||||
* @param {SubmitEvent} event The originating form submission event
|
||||
* @param {HTMLFormElement} form The form element that was submitted
|
||||
* @param {FormDataExtended} formData Processed data for the submitted form
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async #onSubmit(event, form, formData) {
|
||||
const permissions = foundry.utils.expandObject(formData.object);
|
||||
for ( let [k, v] of Object.entries(permissions) ) {
|
||||
if ( !(k in CONST.USER_PERMISSIONS ) ) {
|
||||
delete permissions[k];
|
||||
continue;
|
||||
}
|
||||
permissions[k] = Object.entries(v).reduce((arr, r) => {
|
||||
if ( r[1] === true ) arr.push(parseInt(r[0]));
|
||||
return arr;
|
||||
}, []);
|
||||
}
|
||||
await game.settings.set("core", "permissions", permissions);
|
||||
ui.notifications.info("SETTINGS.PermissionUpdate", {localize: true});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Handle click actions to reset all permissions back to their initial state.
|
||||
* @this {PermissionConfig}
|
||||
* @param {PointerEvent} event
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async #onReset(event) {
|
||||
event.preventDefault();
|
||||
const defaults = Object.entries(CONST.USER_PERMISSIONS).reduce((obj, [id, perm]) => {
|
||||
obj[id] = Array.fromRange(CONST.USER_ROLES.GAMEMASTER + 1).slice(perm.defaultRole);
|
||||
return obj;
|
||||
}, {});
|
||||
await game.settings.set("core", "permissions", defaults);
|
||||
ui.notifications.info("SETTINGS.PermissionReset", {localize: true});
|
||||
await this.render();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user