Compare commits

...

6 Commits

Author SHA1 Message Date
8fbbb4f788 Bump version to 0.2.1 and update download URL
Incremented the module version from 0.2.0 to 0.2.1 and updated the corresponding download URL to reflect the new release. This ensures proper version tracking and correct download linkage for the updated module.
2025-02-03 07:57:27 -06:00
e6e8ae4f3f Fix incorrect Handlebars context reference in input names
Updated the Handlebars template to correctly reference the parent context for `item_id` using `../item_id` instead of `item_id`. This ensures the input field names are properly constructed within nested loops, avoiding potential data binding issues.
2025-02-03 07:55:52 -06:00
fb9eeba103 Rename log and manifest files in asset manager macros
- Renamed `000028.log` to `000041.log`
- Renamed `MANIFEST-000027` to `MANIFEST-000039`
- Updated binary files `CURRENT`, `LOG`, and `LOG.old`
2025-01-31 09:57:34 -06:00
04aee6e44c Bump version to 0.2.0 and update download URL
- Updated the module version in `module.json` from `0.1.1` to `0.2.0`.
- Adjusted the `download` URL to point to the `0.2.0` release ZIP file.

This change reflects the addition of new features and improvements in the latest release.
2025-01-23 10:26:17 -06:00
3fdaadf7e0 Add customizable tags and categories with UI management
- Introduced settings for tags and categories in `settings.js`:
  - Added `tags` and `categories` settings with default values and support for customization.
  - Registered a new settings menu for managing tags and categories dynamically.
- Enhanced `main.js` to use the customizable tags and categories in templates.
  - Adjusted `AscAssetManager.TEMPLATES` to include a new `SETTINGS_TAGS_AND_CATEGORIES` template.
  - Updated the `renderUploadForm` hook to fetch tags and categories dynamically from settings.
- Added a new Handlebars template `settings-tags-and-categories.hbs`:
  - Provides a user interface for managing tags and categories.
  - Includes functionality to add, reset, and delete rows dynamically.

These updates allow users to define and manage tags and categories via the module's settings menu, improving flexibility and user experience.
2025-01-23 10:24:54 -06:00
4cd01570f7 Update and rename binary files in asset manager macros
- Renamed `000024.log` to `000028.log`.
- Renamed `MANIFEST-000023` to `MANIFEST-000027` with updated binary content.
- Updated binary content for `CURRENT`, `LOG`, and `LOG.old`.

These changes reorganize and modify the binary files in the `asc-asset-manager-macros` directory to reflect the latest updates.
2025-01-23 10:24:14 -06:00
9 changed files with 244 additions and 12 deletions

View File

@@ -8,7 +8,8 @@ export class AscAssetManager {
static TEMPLATES = {
UPLOAD_CHOOSE:`modules/${this.ID}/templates/upload-choose.hbs`,
UPLOAD_FORM:`modules/${this.ID}/templates/upload-form.hbs`,
SETTINGS_MENU_MACRO:`modules/${this.ID}/templates/settings-menu-macro.hbs`
SETTINGS_MENU_MACRO:`modules/${this.ID}/templates/settings-menu-macro.hbs`,
SETTINGS_TAGS_AND_CATEGORIES:`modules/${this.ID}/templates/settings-tags-and-categories.hbs`
}
static getDirectory () {
@@ -148,7 +149,11 @@ Hooks.on("renderHotbar", ({macros}, html) => {
});
Hooks.on("ascAssetManager.renderUploadForm", (data={})=>{
const templateData = {moduleId: AscAssetManager.ID, fileCategories: AscAssetManager.fileCategories, fileTags: AscAssetManager.fileTags}
const templateData = {
moduleId: AscAssetManager.ID,
fileCategories: game.settings.get(AscAssetManager.ID, "categories"),
fileTags: game.settings.get(AscAssetManager.ID, "tags")
}
renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_FORM, templateData).then(content => {
let {file} = data
const dialog = new Dialog({

View File

@@ -1,8 +1,8 @@
{
"id": "asc-asset-manager",
"title": "Asset Manager",
"version": "0.1.1",
"download": "https://gitea.ascorrea.com/asc/asc-asset-manager/releases/download/0.1.1/module.zip",
"version": "0.2.1",
"download": "https://gitea.ascorrea.com/asc/asc-asset-manager/releases/download/0.2.1/module.zip",
"manifest": "https://gitea.ascorrea.com/asc/asc-asset-manager/releases/download/latest/module.json",
"compatibility": {
"minimum": "12",

View File

@@ -1 +1 @@
MANIFEST-000023
MANIFEST-000039

View File

@@ -1,3 +1,7 @@
2025/01/23-07:36:18.512910 16efc3000 Recovering log #22
2025/01/23-07:36:18.513160 16efc3000 Delete type=3 #21
2025/01/23-07:36:18.513188 16efc3000 Delete type=0 #22
2025/01/29-15:45:18.681004 30ad38000 Recovering log #38
2025/01/29-15:45:18.681277 30ad38000 Delete type=0 #38
2025/01/29-15:45:18.681298 30ad38000 Delete type=3 #37
2025/01/29-15:46:39.436862 310dbb000 Level-0 table #42: started
2025/01/29-15:46:39.436930 310dbb000 Level-0 table #42: 0 bytes OK
2025/01/29-15:46:39.437031 310dbb000 Delete type=0 #40
2025/01/29-15:46:39.437558 310dbb000 Manual compaction at level-0 from '!macros!rdl3Dw3jRkibnQQC' @ 72057594037927935 : 1 .. '!macros!rdl3Dw3jRkibnQQC' @ 0 : 0; will stop at (end)

View File

@@ -1,3 +1,3 @@
2025/01/23-07:33:44.757771 172f3f000 Recovering log #18
2025/01/23-07:33:44.758028 172f3f000 Delete type=3 #16
2025/01/23-07:33:44.758052 172f3f000 Delete type=0 #18
2025/01/27-20:40:12.716406 16fa73000 Recovering log #35
2025/01/27-20:40:12.716718 16fa73000 Delete type=3 #33
2025/01/27-20:40:12.716753 16fa73000 Delete type=0 #35

View File

@@ -16,6 +16,41 @@ export function registerSettings(AscAssetManager) {
}
});
// Register default tags setting
game.settings.register(ID, "tags", {
name: "Tags",
hint: "A list of tags to use in the module.",
scope: "world", // "world" means the setting is shared across all users; "client" means it's per-user
config: false, // Whether the setting shows up in the settings menu
type: Object, // Data type
default: [
{id:"tk", label: "Token"},
{id:"sq", label: "Square"}
], // Default tags
onChange: (value) => console.log("Tags updated to:", value) // Optional: Triggered when setting is updated
});
// Register default categories setting
game.settings.register(ID, "categories", {
name: "Categories",
hint: "A list of categories to use in the module.",
scope: "world",
config: false,
type: Object,
default: [
{id: "npcn", label: "NPC (Named)"},
{id: "npcu", label: "NPC (Unnamed)"},
{id: "scene", label: "Scene Background"},
{id: "pc", label: "PC"},
{id: "inset", label: "Inset"},
{id: "vehicle", label: "Vehicle"},
{id: "weapon", label: "Weapon"},
{id: "icon", label: "Icon"},
{id: "map", label: "Map"}
],
onChange: (value) => console.log("Categories updated to:", value)
});
// Register the "customMessage" setting
game.settings.register(ID, "rootDirectory", {
name: "Root Directory",
@@ -38,7 +73,7 @@ export function registerSettings(AscAssetManager) {
config: true,
type: class extends FormApplication {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
return foundry.utils.FormApplicationmergeObject(super.defaultOptions, {
id: ID, // Unique ID for the application
title: "Simple Form Application", // Title of the window
template: AscAssetManager.TEMPLATES.SETTINGS_MENU_MACRO, // Path to your Handlebars template
@@ -55,4 +90,148 @@ export function registerSettings(AscAssetManager) {
}
},
});
game.settings.registerMenu(ID, "categories", {
name: "Set Tags and Categories",
label: "Set Tags and Categories",
scope: "world",
icon: "fas fa-list",
config: true,
type: class extends FormApplication {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: ID, // Unique ID for the application
title: "Simple Form Application", // Title of the window
template: AscAssetManager.TEMPLATES.SETTINGS_TAGS_AND_CATEGORIES, // Path to your Handlebars template
width: 300, // Width of the form
height: "auto", // Adjust height automatically
});
}
getData() {
return {
moduleId: ID,
categories: game.settings.get(ID, "categories"),
tags: game.settings.get(ID, "tags")
}
}
activateListeners(html) {
super.activateListeners(html);
function addRow (html) {
// Find the nearest parent div
const parentDiv = html.closest("div:has(table)");
// Find the last row in the body
const lastRow = parentDiv.find("tbody tr:last");
// Clone the last row
const newRow = lastRow.clone();
// Loop through each input in the new row to reset values and update names/ids
newRow.find("input").each(function () {
const input = $(this);
// Reset the input value
input.val("");
// Update the name and id to n+1
const name = input.attr("name");
const id = input.attr("id");
if (name) {
const match = name.match(/(\d+)/); // Find the index in the name
if (match) {
const index = parseInt(match[1], 10) + 1;
input.attr("name", name.replace(/\d+/, index));
}
}
if (id) {
const match = id.match(/(\d+)/); // Find the index in the id
if (match) {
const index = parseInt(match[1], 10) + 1;
input.attr("id", id.replace(/\d+/, index));
}
}
});
// Append the new row to the table
parentDiv.find("tbody").append(newRow);
}
html.find('#add-category, #add-tag').click((evt)=>{
evt.preventDefault()
addRow($(evt.currentTarget));
})
html.find('#reset-category, #reset-tag').click((evt)=>{
evt.preventDefault()
let data
let item_id
if (evt.currentTarget.id == "reset-category"){
item_id = "category"
data = game.settings.settings.get(`${ID}.categories`).default
} else if (evt.currentTarget.id == "reset-tag") {
item_id = "tag"
data = game.settings.settings.get(`${ID}.tags`).default
}
const tbody = $(evt.currentTarget).closest('div:has(table)').find("tbody")
tbody.empty();
for (let [idx, {id, label}] of data.entries()){
const newRow = $(`<tr></tr>`)
newRow.append(`<td><input type="text" name="${item_id}-id-${idx}" value="${id}"></input></td>`)
newRow.append(`<td><input type="text" name="${item_id}-label-${idx}" value="${label}"></input></td>`)
newRow.append(`<td><button id="delete-row-${idx}" class="delete-row"><i class="delete-row fa-solid fa-trash-can"></i></button></td>`)
tbody.append(newRow)
}
})
html.find('.delete-row').click((evt)=>{
evt.preventDefault();
const button = $(evt.currentTarget)
button.closest('tr').remove()
})
}
async _updateObject(event, formData) {
// Save updates when the form is submitted
const categories = [];
const tags = [];
// Dynamically group rows for categories and tags
for (const [key, value] of Object.entries(formData)) {
// Match category rows
const categoryMatch = key.match(/^category-(id|label)-(\d+)$/);
if (categoryMatch) {
const [_, field, index] = categoryMatch; // Extract field (id/label) and index
const i = parseInt(index);
// Ensure the index exists in the categories array
if (!categories[i]) categories[i] = { id: "", label: "" };
categories[i][field] = value;
continue;
}
// Match tag rows
const tagMatch = key.match(/^tag-(id|label)-(\d+)$/);
if (tagMatch) {
const [_, field, index] = tagMatch; // Extract field (id/label) and index
const i = parseInt(index);
// Ensure the index exists in the tags array
if (!tags[i]) tags[i] = { id: "", label: "" };
tags[i][field] = value;
continue;
}
}
await game.settings.set(ID, "tags", tags);
await game.settings.set(ID, "categories", categories);
ui.notifications.info("Settings updated!");
}
},
});
game
}

View File

@@ -0,0 +1,44 @@
{{#*inline "table"}}
<table>
<thead>
<tr><th colspan=3>{{collection_title}}</th></tr>
<tr>
<th>ID</th>
<th>Label</th>
<th></th>
</tr>
</thead>
<tbody>
{{#each collection}}
<tr>
<td><input type="text" name="{{../item_id}}-id-{{@index}}" value="{{id}}"></input></td>
<td><input type="text" name="{{../item_id}}-label-{{@index}}" value="{{label}}"></input></td>
<td><button id="delete-row-{{@index}}" class="delete-row"><i class="delete-row fa-solid fa-trash-can"></i></button></td>
</tr>
{{else}}
<tr>
<td><input type="text" name="{{../item_id}}-id-0" value="" placeholder="id"></input></td>
<td><input type="text" name="{{../item_id}}-label-0" value="" placeholder="label"></input></td>
<td><button id="delete-row-0" class="delete-row"><i class="delete-row fa-solid fa-trash-can"></i></button></td>
</tr>
{{/each}}
</tbody>
</table>
<div class="dialog-buttons">
<button id="add-{{item_id}}" class="dialog-button"><i class="fa-solid fa-plus"></i>Add {{item_title}}</button>
<button id="reset-{{item_id}}" class="dialog-button"><i class="fa-solid fa-arrow-rotate-left"></i>Reset {{collection_ttitle}}</button>
</div>
{{/inline}}
<div class="{{moduleId}}">
<form id="form-categories-and-tags">
<div>
{{> table collection_title="Categories" item_title="Category" collection=categories item_id="category"}}
</div>
<div>
{{> table collection_title="Tags" item_title="Tag" collection=tags item_id="tag"}}
</div>
<hr>
<button id="save" class="dialog-button"><i class="fa-solid fa-check"></i> Save</button>
</form>
</div>