Skip to content

Commit

Permalink
Merge pull request #2020 from crnormand/features/mass_import
Browse files Browse the repository at this point in the history
Features/mass import
  • Loading branch information
mjeffw authored Nov 2, 2024
2 parents 21b12de + 5030e33 commit e02a5f9
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 37 deletions.
6 changes: 5 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
### [Users Guide](https://bit.ly/2JaSlQd) for GURPS 4e Game Aid for Foundry VTT

Release 0.17.16

- Feature: Multiple actor import. Import multiple GCS and GCA files with one command.

Release 0.17.15 10/31/2024

- Feature: Customizable/floating Roll3d6 button and modifier bucket.
Expand All @@ -13,7 +17,7 @@ Release 0.17.14 10/28/2024
This is a minor release in preparation for the release of the Warlock Knight VTT module by Gaming Ballistic.

- Bugfix: Size modifier is not being imported.
- Bugfix: `system.equippedparry` and `system.equippedblock` now return the *best* value, not the first.
- Bugfix: `system.equippedparry` and `system.equippedblock` now return the _best_ value, not the first.
- Feature: Hit locations and trackers can be referenced by name (for macros). Eg. `system.hitlocationNames['Torso'].import` and `system.trackersByName['Control Points'].value`.

- Add nonstandard values for Control Rolls to the language files.
Expand Down
3 changes: 3 additions & 0 deletions lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,9 @@
"GURPS.importCreate": "Erstellen",
"GURPS.importUpdate": "Aktualisieren",
"GURPS.importReplace": "Ersetzen",
"GURPS.importCancel": "Import abbrechen",
"GURPS.importSelected": "Ausgewählte importieren",
"GURPS.importNoFilesSelected": "Keine Dateien zum Importieren ausgewählt.",
"__System Settings__": "=========",
"GURPS.settingShowReadMe": "Bei Versionswechsel 'Liesmich' anzeigen",
"GURPS.settingHintShowReadMe": "Wenn diese Option aktiviert ist, zeigt das System bei jeder Versionsänderung die Datei 'Liesmich' an.",
Expand Down
4 changes: 3 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,9 @@
"GURPS.importCreate": "Create",
"GURPS.importUpdate": "Update",
"GURPS.importReplace": "Replace",
"GURPS.importCancel": "Cancel",
"GURPS.importCancel": "Cancel Import",
"GURPS.importSelected": "Import Selected",
"GURPS.importNoFilesSelected": "No files selected for import.",
"__System Settings__": "=========",
"GURPS.settingShowReadMe": "Show 'Read Me' on version change",
"GURPS.settingHintShowReadMe": "If checked, the system will display the 'Read Me' file every time a version change is detected.",
Expand Down
3 changes: 3 additions & 0 deletions lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,9 @@
"GURPS.importCreate": "Créer",
"GURPS.importUpdate": "Mettre à jour",
"GURPS.importReplace": "Remplacer",
"GURPS.importCancel": "Annuler l'importation",
"GURPS.importSelected": "Importer sélectionné",
"GURPS.importNoFilesSelected": "Aucun fichier sélectionné pour l'importation.",
"__System Settings__": "=========",
"GURPS.settingShowReadMe": "Montrez le 'Lisez-Moi' sur le changement de version",
"GURPS.settingHintShowReadMe": "Si coché, le system affichera le fichier 'Liez-Moi' chaque fois qu'un changement de version est détecté.",
Expand Down
3 changes: 3 additions & 0 deletions lang/pt_br.json
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,9 @@
"GURPS.importCreate": "Criar",
"GURPS.importUpdate": "Atualizar",
"GURPS.importReplace": "Substituir",
"GURPS.importCancel": "Cancelar Importação",
"GURPS.importSelected": "Importar Selecionados",
"GURPS.importNoFilesSelected": "Nenhum arquivo selecionado para importação.",
"__System Settings__": "=========",
"GURPS.settingShowReadMe": "Exibir 'Leia-Me' quando houver atualização",
"GURPS.settingHintShowReadMe": "Se marcado, o sistema vai exibir o arquivo 'Leia-Me' sempre que uma mudança de versão for detectada.",
Expand Down
5 changes: 4 additions & 1 deletion lang/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,9 @@
"GURPS.importCreate": "Создать",
"GURPS.importUpdate": "Обновить",
"GURPS.importReplace": "Заменить",
"GURPS.importCancel": "Отменить импорт",
"GURPS.importSelected": "Импортировать выбранное",
"GURPS.importNoFilesSelected": "Файлы для импорта не выбраны.",
"__System Settings__": "=========",
"GURPS.settingDamageLocationTorso": "Торс",
"GURPS.settingUseFoundryItems": "Использовать Foundry Items для снаряжения",
Expand All @@ -467,4 +470,4 @@
"GURPS.parentItemTooltip": "<div>Из {type}:<br>{name}</div>",
"GURPS.cannotDropItemAlreadyExists": "У вас уже есть этот предмет.",
"GURPS.droppingItemNotification": "{actorName} получил {itemName}"
}
}
108 changes: 79 additions & 29 deletions module/actor/multiple-import-app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { i18n } from '../../lib/utilities.js'
import { ActorImporter } from './actor-importer.js'
import { GurpsActor } from './actor.js'

export const AddMultipleImportButton = function (html) {
let button = $(
Expand All @@ -18,26 +20,23 @@ export const AddMultipleImportButton = function (html) {
}
}

// Log the list of files
console.log('Files in directory:', files)

if (files.length === 0) {
return ui.notifications.error(i18n('GURPS.importEmptyDirectory'))
}

new MultipleImportForm(files).render(true)
new MultipleImportApp(dirHandle, files).render(true)
})

html.find('.directory-footer').append(button)
}

class MultipleImportForm extends Application {
class MultipleImportApp extends Application {
static getSource(filename) {
if (filename.endsWith('.gcs')) return 'GCS'
else return 'GCA'
}

constructor(files, options = {}) {
constructor(dirHandle, files, options = {}) {
super(options)

this.data = {
Expand All @@ -51,13 +50,14 @@ class MultipleImportForm extends Application {
selected: false,
file: files[ii],
actor: actor,
source: MultipleImportForm.getSource(files[ii]),
source: MultipleImportApp.getSource(files[ii]),
version: null,
onImport: actor ? 'update' : 'create',
})
}

this.data.files.sort((a, b) => a.file.localeCompare(b.file))
this.dirHandle = dirHandle
}

/** @override */
Expand Down Expand Up @@ -90,40 +90,90 @@ class MultipleImportForm extends Application {
async _onFilelistClick(event) {
event.preventDefault()
const target = event.currentTarget

if (target.dataset.action === 'select-all') {
const isChecked = target.checked
this.data.selectAll = isChecked
for (const ii in this.data.files) {
this.data.files[ii].selected = isChecked
}
return this.render(true)
}

if (target.dataset.action === 'select') {
const isChecked = target.checked
const index = parseInt(target.dataset.filelistId)
this.data.files[index].selected = isChecked
return this.render(true)
const isChecked = target.checked
const index = parseInt(target.dataset.filelistId)

switch (target.dataset.action) {
case 'select-all':
this.data.selectAll = isChecked
for (const ii in this.data.files) {
this.data.files[ii].selected = isChecked
}
return this.render(true)

case 'select':
this.data.files[index].selected = isChecked
return this.render(true)

case 'import':
// Import the selected files
const selectedFiles = this.data.files.filter(it => it.selected)
if (selectedFiles.length === 0) {
return ui.notifications.error(i18n('GURPS.importNoFilesSelected'))
}
this._importFiles(selectedFiles)
return this.close()

case 'cancel':
this.close()
}
}

async _onFilelistChange(event) {
event.preventDefault()
const target = event.currentTarget

if (target.dataset.action === 'import') {
if (target.dataset.action === 'option') {
const index = parseInt(target.dataset.filelistId)
const file = this.data.files[index]

const value = target.value
this.data.files[index].onImport = value
file.onImport = file.actor ? value : 'create'
return this.render(true)
}
}

/** @override */
async _updateObject(event, formData) {
// Handle form submission
console.log('Form submitted with data:', formData)
console.log('Selected files:', this.files)
async _importFiles(files) {
for (const file of files) {
let actor = file.actor
const onImport = file.onImport

// If Create or Replace, create a new actor.
if (onImport === 'replace' || onImport === 'create') {
actor = await GurpsActor.create(
{
name: file.file,
type: 'character',
},
{ renderSheet: false }
)
}

// Load the file.
const fileHandle = await this.dirHandle.getFileHandle(file.file)
const fileObject = await fileHandle.getFile()
const text = await GURPS.readTextFromFile(fileObject)

// Import the actor.
const importer = new ActorImporter(actor)
await importer.importActorFromExternalProgram(text, fileObject.name, await this.getDirectoryPath(this.dirHandle))

// If Replace, delete the old actor.
if (onImport === 'replace') {
await file.actor.delete()
}
}
}

async getDirectoryPath(dirHandle) {
let path = dirHandle.name
let currentHandle = dirHandle

while (currentHandle.parent) {
currentHandle = await currentHandle.parent
path = `${currentHandle.name}/${path}`
}

return path
}
}
14 changes: 9 additions & 5 deletions templates/actor/import-multiple-file-list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,18 @@
<div class='value'>{{file}}</div>
<div class='value'>{{actor.name}}</div>
<div class='value'>{{source}}</div>
<select name='options' class='filelist-control' data-action='import' data-filelist-id='{{@index}}'>
{{selectOptions ../choices selected=onImport localize=true}}
</select>
{{#if actor}}
<select name='options' class='filelist-control value' data-action='option' data-filelist-id='{{@index}}'>
{{selectOptions ../choices selected=onImport localize=true}}
</select>
{{else}}
<div class='value'>{{i18n 'GURPS.importCreate'}}</div>
{{/if}}
{{/each}}
</div>
<div class='gga-button-bar'>
<button class='filelist-control' data-action='cancel' id='cancel'><i class='fas fa-times'></i>Clear Configuration</button>
<button class='filelist-control' data-action='import' id='import'><i class='fas fa-file-import'></i>Update</button>
<button class='filelist-control' data-action='cancel' id='cancel'><i class='fas fa-times'></i>{{i18n 'GURPS.importCancel'}}</button>
<button class='filelist-control' data-action='import' id='import'><i class='fas fa-file-import'></i>{{i18n 'GURPS.importSelected'}}</button>
</div>
</div>
</form>

0 comments on commit e02a5f9

Please sign in to comment.