intelligent-system-design-language 0.3.21 → 0.3.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.claude/agents/langium-language-designer.md +38 -38
  2. package/.claude/agents/typescript-vscode-expert.md +29 -29
  3. package/.claude/agents/ui-ux-designer.md +36 -36
  4. package/.claude/settings.local.json +33 -33
  5. package/.idea/inspectionProfiles/Project_Default.xml +6 -6
  6. package/.idea/isdl.iml +13 -13
  7. package/.idea/modules.xml +8 -8
  8. package/.idea/vcs.xml +6 -6
  9. package/.idea/watcherTasks.xml +3 -3
  10. package/.vscodeignore +18 -18
  11. package/LICENSE +673 -673
  12. package/README.md +86 -86
  13. package/bin/cli.js +4 -4
  14. package/bin/lsp.js +8 -8
  15. package/out/_backgrounds.scss +91 -91
  16. package/out/_handlebars.scss +497 -497
  17. package/out/_isdlStyles.scss +1444 -1381
  18. package/out/_vuetifyOverrides.scss +425 -425
  19. package/out/_vuetifyStyles.scss +31957 -31957
  20. package/out/cli/components/_backgrounds.scss +91 -91
  21. package/out/cli/components/_handlebars.scss +497 -497
  22. package/out/cli/components/_isdlStyles.scss +1444 -1381
  23. package/out/cli/components/_vuetifyOverrides.scss +425 -425
  24. package/out/cli/components/_vuetifyStyles.scss +31957 -31957
  25. package/out/cli/components/active-effect-sheet-generator.js +453 -453
  26. package/out/cli/components/chat-card-generator.js +654 -651
  27. package/out/cli/components/chat-card-generator.js.map +1 -1
  28. package/out/cli/components/css-generator.js +4 -4
  29. package/out/cli/components/damage-roll-generator.js +160 -160
  30. package/out/cli/components/datamodel-generator.js +264 -257
  31. package/out/cli/components/datamodel-generator.js.map +1 -1
  32. package/out/cli/components/derived-data-generator.js +923 -923
  33. package/out/cli/components/hotbar-drop-hook-generator.js +82 -82
  34. package/out/cli/components/init-hook-generator.js +495 -495
  35. package/out/cli/components/language-generator.js +1 -1
  36. package/out/cli/components/language-generator.js.map +1 -1
  37. package/out/cli/components/measured-template-preview.js +221 -221
  38. package/out/cli/components/method-generator.js +979 -887
  39. package/out/cli/components/method-generator.js.map +1 -1
  40. package/out/cli/components/ready-hook-generator.js +404 -404
  41. package/out/cli/components/token-generator.js +116 -116
  42. package/out/cli/components/vue/base-components/vue-attribute.js +138 -138
  43. package/out/cli/components/vue/base-components/vue-boolean.js +64 -64
  44. package/out/cli/components/vue/base-components/vue-calculator.js +93 -93
  45. package/out/cli/components/vue/base-components/vue-damage-application.js +356 -356
  46. package/out/cli/components/vue/base-components/vue-damage-bonuses.js +165 -165
  47. package/out/cli/components/vue/base-components/vue-damage-resistances.js +196 -196
  48. package/out/cli/components/vue/base-components/vue-damage-track.js +121 -121
  49. package/out/cli/components/vue/base-components/vue-date-time.js +42 -42
  50. package/out/cli/components/vue/base-components/vue-dice.js +98 -98
  51. package/out/cli/components/vue/base-components/vue-die.js +73 -73
  52. package/out/cli/components/vue/base-components/vue-document-choice.js +149 -149
  53. package/out/cli/components/vue/base-components/vue-document-choices.js +179 -179
  54. package/out/cli/components/vue/base-components/vue-document-link.js +60 -60
  55. package/out/cli/components/vue/base-components/vue-extended-choice.js +88 -88
  56. package/out/cli/components/vue/base-components/vue-inventory.js +519 -519
  57. package/out/cli/components/vue/base-components/vue-macro-choice.js +138 -138
  58. package/out/cli/components/vue/base-components/vue-measured-template.js +530 -530
  59. package/out/cli/components/vue/base-components/vue-money.js +483 -483
  60. package/out/cli/components/vue/base-components/vue-number.js +174 -174
  61. package/out/cli/components/vue/base-components/vue-paperdoll.js +43 -43
  62. package/out/cli/components/vue/base-components/vue-parent-property-reference.js +76 -76
  63. package/out/cli/components/vue/base-components/vue-prosemirror.js +18 -18
  64. package/out/cli/components/vue/base-components/vue-resource.js +136 -136
  65. package/out/cli/components/vue/base-components/vue-roll-visualizer.js +286 -109
  66. package/out/cli/components/vue/base-components/vue-roll-visualizer.js.map +1 -1
  67. package/out/cli/components/vue/base-components/vue-self-property-reference.js +62 -62
  68. package/out/cli/components/vue/base-components/vue-string-choice.js +98 -98
  69. package/out/cli/components/vue/base-components/vue-string-choices.js +203 -203
  70. package/out/cli/components/vue/base-components/vue-string.js +60 -60
  71. package/out/cli/components/vue/base-components/vue-text-field.js +53 -53
  72. package/out/cli/components/vue/base-components/vue-tracker.js +431 -431
  73. package/out/cli/components/vue/vue-action-component-generator.js +64 -64
  74. package/out/cli/components/vue/vue-active-effect-sheet-generator.js +856 -856
  75. package/out/cli/components/vue/vue-datatable-sheet-class-generator.js +292 -292
  76. package/out/cli/components/vue/vue-datatable2-component-generator.js +824 -824
  77. package/out/cli/components/vue/vue-document-creation-app.js +121 -121
  78. package/out/cli/components/vue/vue-document-creation-sheet.js +94 -94
  79. package/out/cli/components/vue/vue-generator.js +40 -40
  80. package/out/cli/components/vue/vue-mixin.js +296 -296
  81. package/out/cli/components/vue/vue-pinned-datatable-component-generator.js +260 -260
  82. package/out/cli/components/vue/vue-prompt-generator.js +91 -76
  83. package/out/cli/components/vue/vue-prompt-generator.js.map +1 -1
  84. package/out/cli/components/vue/vue-prompt-sheet-class-generator.js +317 -317
  85. package/out/cli/components/vue/vue-sheet-application-generator.js +1177 -1167
  86. package/out/cli/components/vue/vue-sheet-application-generator.js.map +1 -1
  87. package/out/cli/components/vue/vue-sheet-class-generator.js +510 -510
  88. package/out/cli/generator.js +438 -433
  89. package/out/cli/generator.js.map +1 -1
  90. package/out/extension/github/githubAuthProvider.js +71 -29
  91. package/out/extension/github/githubAuthProvider.js.map +1 -1
  92. package/out/extension/github/githubGistManager.js +4 -3
  93. package/out/extension/github/githubGistManager.js.map +1 -1
  94. package/out/extension/github/githubManager.js +40 -38
  95. package/out/extension/github/githubManager.js.map +1 -1
  96. package/out/extension/github/githubQuickActions.js +120 -120
  97. package/out/extension/github/system-workflow.yml +47 -47
  98. package/out/extension/main.cjs +909 -532
  99. package/out/extension/main.cjs.map +3 -3
  100. package/out/extension/package.json +419 -419
  101. package/out/language/generated/ast.js +51 -2
  102. package/out/language/generated/ast.js.map +1 -1
  103. package/out/language/generated/grammar.js +14240 -13991
  104. package/out/language/generated/grammar.js.map +1 -1
  105. package/out/language/intelligent-system-design-language-validator.js +32 -2
  106. package/out/language/intelligent-system-design-language-validator.js.map +1 -1
  107. package/out/language/isdl-scope-provider.js +14 -1
  108. package/out/language/isdl-scope-provider.js.map +1 -1
  109. package/out/language/main.cjs +913 -569
  110. package/out/language/main.cjs.map +3 -3
  111. package/out/package.json +419 -419
  112. package/out/progressbar.min.js +6 -6
  113. package/out/styles.scss +762 -747
  114. package/out/test/validating/diagnostics.test.js +40 -0
  115. package/out/test/validating/diagnostics.test.js.map +1 -1
  116. package/package.json +419 -419
@@ -1,14 +1,14 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs';
3
3
  import { expandToNode, joinToNode, toString } from 'langium/generate';
4
- import { isAccess, isAction, isActor, isAttributeExp, isAttributeParamMod, isAttributeRollParam, isAttributeFunctionParam, isAttributeStyleParam, isBackgroundParam, isBooleanExp, isBooleanParamValue, isChoiceCustomProperty, isChoiceStringValue, isColorParam, isColumn, isDateExp, isDateTimeExp, isDiceField, isDiceFields, isDieChoicesParam, isDieNoneParam, isDieField, isDocumentChoiceExp, isDocumentChoicesExp, isEntry, isHtmlExp, isIconParam, isImageParam, isLabelParam, isMacroField, isMeasuredTemplateField, isDamageBonusesField, isDamageResistancesField, isPinnedField, isMoneyField, isDamageTrackExp, isDamageTrackTypesParam, isMethodBlock, isNumberExp, isNumberParamMax, isNumberParamMin, isNumberParamValue, isNumberParamCalculator, isPage, isPaperDollExp, isParentPropertyRefChoiceParam, isParentPropertyRefExp, isSelfPropertyRefExp, isProperty, isResourceExp, isRow, isSection, isSegmentsParameter, isSingleDocumentExp, isSizeParam, isStatusProperty, isStringChoiceField, isDamageTypeChoiceField, isStringChoicesField, isStringExp, isStringExtendedChoice, isStringParamChoices, isStringParamValue, isTableField, isTimeExp, isTrackerExp, isTrackerStyleParameter, isVisibilityParam, isInventoryField, isInventorySlotsParam, isInventoryRowsParam, isInventoryColumnsParam, isInventorySlotSizeParam, isInventoryQuantityParam, isInventoryMoneyParam, isInventorySumParam, isInventorySumMaxParam, isInventorySortParam, isInventoryEmptySlotsParam, isInventorySummaryParam, isWhereParam, isGlobalParam } from "../../../language/generated/ast.js";
4
+ import { isAccess, isAction, isActor, isAttributeExp, isAttributeParamMod, isAttributeRollParam, isAttributeFunctionParam, isAttributeStyleParam, isBackgroundParam, isBooleanExp, isBooleanParamValue, isChoiceCustomProperty, isChoiceStringValue, isColorParam, isColumn, isDateExp, isDateTimeExp, isDiceField, isDiceFields, isDieChoicesParam, isDieNoneParam, isDieField, isDocumentChoiceExp, isDocumentChoicesExp, isEntry, isHtmlExp, isIconParam, isImageParam, isLabelParam, isMacroField, isMeasuredTemplateField, isDamageBonusesField, isDamageResistancesField, isPinnedField, isMoneyField, isDamageTrackExp, isDamageTrackTypesParam, isRollVisualizerField, isMethodBlock, isNumberExp, isNumberParamMax, isNumberParamMin, isNumberParamValue, isNumberParamCalculator, isPage, isPaperDollExp, isParentPropertyRefChoiceParam, isParentPropertyRefExp, isSelfPropertyRefExp, isProperty, isResourceExp, isRow, isSection, isSegmentsParameter, isSingleDocumentExp, isSizeParam, isStatusProperty, isStringChoiceField, isDamageTypeChoiceField, isStringChoicesField, isStringExp, isStringExtendedChoice, isStringParamChoices, isStringParamValue, isTableField, isTimeExp, isTrackerExp, isTrackerStyleParameter, isVisibilityParam, isInventoryField, isInventorySlotsParam, isInventoryRowsParam, isInventoryColumnsParam, isInventorySlotSizeParam, isInventoryQuantityParam, isInventoryMoneyParam, isInventorySumParam, isInventorySumMaxParam, isInventorySortParam, isInventoryEmptySlotsParam, isInventorySummaryParam, isWhereParam, isGlobalParam } from "../../../language/generated/ast.js";
5
5
  import { getAllOfType, getDocument, getSystemPath, globalGetAllOfType, toMachineIdentifier } from '../utils.js';
6
6
  import { AstUtils } from 'langium';
7
7
  import { generateActionComponent } from './vue-action-component-generator.js';
8
8
  import { generatePinnedVuetifyDatatableComponent } from './vue-pinned-datatable-component-generator.js';
9
9
  // import {generateDocumentChoiceComponent} from './vue-document-choice-component-generator.js';
10
10
  import { generateDocumentChoicesComponent } from './base-components/vue-document-choices.js';
11
- import { translateBodyExpressionToJavascript, translateExpression } from '../method-generator.js';
11
+ import { translateBodyExpressionToJavascript, translateExpression, compileVisualizerFormula } from '../method-generator.js';
12
12
  import { humanize } from "inflection";
13
13
  import { generateVuetifyDatatableComponent } from "./vue-datatable2-component-generator.js";
14
14
  import { generateDocumentChoiceComponent } from "./base-components/vue-document-choice.js";
@@ -19,9 +19,9 @@ export function generateDocumentVueComponent(entry, id, document, destination) {
19
19
  if (!fs.existsSync(generatedFileDir)) {
20
20
  fs.mkdirSync(generatedFileDir, { recursive: true });
21
21
  }
22
- const fileNode = expandToNode `
23
- ${generateVueComponentScript(entry, id, document, destination)}
24
- ${generateVueComponentTemplate(entry, id, document)}
22
+ const fileNode = expandToNode `
23
+ ${generateVueComponentScript(entry, id, document, destination)}
24
+ ${generateVueComponentTemplate(entry, id, document)}
25
25
  `.appendNewLineIfNotEmpty();
26
26
  fs.writeFileSync(generatedFilePath, toString(fileNode));
27
27
  }
@@ -43,22 +43,22 @@ function generateVueComponentScript(entry, id, document, destination) {
43
43
  const page = AstUtils.getContainerOfType(table, isPage);
44
44
  const pageName = page ? page.name : document.name;
45
45
  generateVuetifyDatatableComponent(entry, id, document, pageName, table, destination);
46
- return expandToNode `
47
- import ${document.name}${pageName}${table.name}VuetifyDatatable from './components/datatables/${document.name.toLowerCase()}${pageName}${table.name}VuetifyDatatable.vue';
46
+ return expandToNode `
47
+ import ${document.name}${pageName}${table.name}VuetifyDatatable from './components/datatables/${document.name.toLowerCase()}${pageName}${table.name}VuetifyDatatable.vue';
48
48
  `;
49
49
  }
50
50
  function importEffectsDataTable() {
51
51
  generateEffectsVuetifyDatatableComponent(id, document, destination);
52
- return expandToNode `
53
- import ${document.name}EffectsVuetifyDatatable from './components/datatables/${document.name.toLowerCase()}EffectsVuetifyDatatable.vue';
52
+ return expandToNode `
53
+ import ${document.name}EffectsVuetifyDatatable from './components/datatables/${document.name.toLowerCase()}EffectsVuetifyDatatable.vue';
54
54
  `;
55
55
  }
56
56
  function importPinnedDataTable(pinnedField) {
57
57
  generatePinnedVuetifyDatatableComponent(id, document, pinnedField, destination, entry);
58
58
  const page = AstUtils.getContainerOfType(pinnedField, isPage);
59
59
  const pageName = page ? page.name : document.name;
60
- return expandToNode `
61
- import ${document.name}${pageName}${pinnedField.name}VuetifyDatatable from './components/datatables/${document.name.toLowerCase()}${pageName}${pinnedField.name}VuetifyDatatable.vue';
60
+ return expandToNode `
61
+ import ${document.name}${pageName}${pinnedField.name}VuetifyDatatable from './components/datatables/${document.name.toLowerCase()}${pageName}${pinnedField.name}VuetifyDatatable.vue';
62
62
  `;
63
63
  }
64
64
  function generateEffectsVuetifyDatatableComponent(id, document, destination) {
@@ -68,292 +68,292 @@ function generateVueComponentScript(entry, id, document, destination) {
68
68
  if (!fs.existsSync(generatedFileDir)) {
69
69
  fs.mkdirSync(generatedFileDir, { recursive: true });
70
70
  }
71
- const fileNode = expandToNode `
72
- <script setup>
73
- import { ref, computed, inject, onMounted } from "vue";
74
-
75
- const props = defineProps({
76
- context: Object,
77
- primaryColor: String,
78
- secondaryColor: String,
79
- tertiaryColor: String
80
- });
81
-
82
- const document = inject('rawDocument');
83
- const search = ref('');
84
- const loading = ref(false);
85
-
86
- const data = ref([]);
87
-
88
- function updateEffects() {
89
- data.value = Array.from(document.allApplicableEffects());
90
- }
91
-
92
- updateEffects();
93
-
94
- Hooks.on("createActiveEffect", updateEffects);
95
- Hooks.on("updateActiveEffect", updateEffects);
96
- Hooks.on("deleteActiveEffect", updateEffects);
97
-
98
- const headers = [
99
- {
100
- title: game.i18n.localize("Image"),
101
- key: 'img',
102
- sortable: false,
103
- width: '50px',
104
- maxWidth: '50px'
105
- },
106
- {
107
- title: game.i18n.localize("Name"),
108
- key: 'name',
109
- sortable: true,
110
- minWidth: '120px'
111
- },
112
- {
113
- title: game.i18n.localize("Source"),
114
- key: 'source',
115
- sortable: true,
116
- minWidth: '120px'
117
- },
118
- {
119
- title: game.i18n.localize("Duration"),
120
- key: 'duration',
121
- sortable: true,
122
- minWidth: '100px'
123
- },
124
- {
125
- title: game.i18n.localize("Actions"),
126
- key: 'actions',
127
- sortable: false,
128
- width: '150px',
129
- align: 'center'
130
- }
131
- ];
132
-
133
- const editItem = (item) => {
134
- const foundryItem = document.effects.get(item._id);
135
- foundryItem.sheet.render(true);
136
- };
137
-
138
- const toggleEffect = async (item) => {
139
- const update = {
140
- _id: item._id,
141
- disabled: !item.disabled
142
- };
143
- item.disabled = !item.disabled;
144
- document.updateEmbeddedDocuments("ActiveEffect", [update]);
145
- };
146
-
147
- const deleteEffect = async (item) => {
148
- const shouldDelete = await Dialog.confirm({
149
- title: "Delete Confirmation",
150
- content: \`<p>Are you sure you would like to delete the "\${item.name}" Effect?</p>\`,
151
- defaultYes: false
152
- });
153
- if (shouldDelete) {
154
- await document.deleteEmbeddedDocuments("ActiveEffect", [item.id]);
155
- // Don't call updateEffects() here as the Hooks will handle it
156
- };
157
- };
158
-
159
- const addNewEffect = async () => {
160
- loading.value = true;
161
- try {
162
- const effects = await ActiveEffect.createDocuments([{
163
- name: "New Effect",
164
- icon: "icons/svg/aura.svg"
165
- }], {parent: document});
166
-
167
- if (effects && effects[0]) {
168
- effects[0].sheet.render(true);
169
- updateEffects();
170
- }
171
- } catch (error) {
172
- console.error("Error creating effect:", error);
173
- ui.notifications.error("Failed to create new effect");
174
- } finally {
175
- loading.value = false;
176
- }
177
- };
178
-
179
- const formatDuration = (effect) => {
180
- if (!effect.duration) return "Permanent";
181
- if (effect.duration.type === "none") return "Permanent";
182
- if (effect.duration.type === "turns") {
183
- return \`\${effect.duration.remaining} turns\`;
184
- }
185
- if (effect.duration.type === "seconds") {
186
- return \`\${effect.duration.remaining} seconds\`;
187
- }
188
- return "Temporary";
189
- };
190
- </script>
191
-
192
- <template>
193
- <v-card flat class="isdl-datatable">
194
- <v-card-title class="d-flex align-center pe-1" style="height: 40px;">
195
- <v-icon icon="fa-solid fa-sparkles" size="small" />
196
- &nbsp; {{ game.i18n.localize("Effects") }}
197
- <v-spacer></v-spacer>
198
- <v-text-field
199
- v-model="search"
200
- density="compact"
201
- label="Search"
202
- prepend-inner-icon="fa-solid fa-magnify"
203
- variant="outlined"
204
- flat
205
- hide-details
206
- single-line
207
- clearable
208
- style="margin: 0; margin-right: 8px;"
209
- ></v-text-field>
210
- <v-btn
211
- :color="primaryColor || 'primary'"
212
- prepend-icon="fa-solid fa-plus"
213
- rounded="0"
214
- size="small"
215
- :loading="loading"
216
- @click="addNewEffect"
217
- style="max-width: 80px; height: 38px;"
218
- >
219
- {{ game.i18n.localize("Add") }}
220
- </v-btn>
221
- </v-card-title>
222
- <v-divider></v-divider>
223
-
224
- <v-data-table
225
- v-model:search="search"
226
- :headers="headers"
227
- :items="data"
228
- :search="search"
229
- hover
230
- density="compact"
231
- hide-default-footer
232
- style="background: none;"
233
- class="custom-datatable"
234
- >
235
- <!-- Image slot -->
236
- <template v-slot:item.img="{ item }">
237
- <v-avatar size="40" rounded="0">
238
- <v-img :src="item.img ?? item.icon" :alt="item.name" cover></v-img>
239
- </v-avatar>
240
- </template>
241
-
242
- <!-- Name slot -->
243
- <template v-slot:item.name="{ item }">
244
- <div class="d-flex align-center">
245
- <div class="font-weight-medium text-truncate" style="min-width: 120px; max-width: 200px;">{{ item.name }}</div>
246
- </div>
247
- </template>
248
-
249
- <!-- Source slot -->
250
- <template v-slot:item.source="{ item }">
251
- <v-chip
252
- label
253
- size="x-small"
254
- variant="elevated"
255
- class="text-caption text-truncate"
256
- style="max-width: 150px;"
257
- :data-tooltip="item.flags?.['${id}']?.source || 'Unknown'">
258
- {{ item.flags?.['${id}']?.source || 'Unknown' }}
259
- </v-chip>
260
- </template>
261
-
262
- <!-- Duration slot -->
263
- <template v-slot:item.duration="{ item }">
264
- <v-chip
265
- label
266
- size="x-small"
267
- variant="elevated"
268
- class="text-caption"
269
- :color="item.duration?.type === 'none' ? 'primary' : 'secondary'"
270
- >
271
- {{ formatDuration(item) }}
272
- </v-chip>
273
- </template>
274
-
275
- <!-- Actions slot -->
276
- <template v-slot:item.actions="{ item }">
277
- <div class="d-flex align-center justify-center ga-1">
278
- <v-tooltip :text="item.disabled ? 'Enable' : 'Disable'">
279
- <template v-slot:activator="{ props }">
280
- <v-btn
281
- v-bind="props"
282
- :icon="item.disabled ? 'fa-solid fa-pause' : 'fa-solid fa-play'"
283
- size="x-small"
284
- variant="text"
285
- :color="item.disabled ? 'warning' : 'success'"
286
- @click="toggleEffect(item)"
287
- ></v-btn>
288
- </template>
289
- </v-tooltip>
290
- <v-tooltip text="Edit">
291
- <template v-slot:activator="{ props }">
292
- <v-btn
293
- v-bind="props"
294
- icon="fa-solid fa-edit"
295
- size="x-small"
296
- variant="text"
297
- @click="editItem(item)"
298
- ></v-btn>
299
- </template>
300
- </v-tooltip>
301
- <v-tooltip text="Delete">
302
- <template v-slot:activator="{ props }">
303
- <v-btn
304
- v-bind="props"
305
- icon="fa-solid fa-trash"
306
- size="x-small"
307
- variant="text"
308
- color="error"
309
- @click="deleteEffect(item)"
310
- ></v-btn>
311
- </template>
312
- </v-tooltip>
313
- </div>
314
- </template>
315
-
316
- <!-- No data slot -->
317
- <template v-slot:no-data>
318
- <div class="text-center pa-4">
319
- <v-icon size="48" color="grey-lighten-1">fa-solid fa-magic</v-icon>
320
- <div class="text-h6 mt-2">No effects found</div>
321
- <div class="text-body-2 text-medium-emphasis">
322
- Add your first effect to get started
323
- </div>
324
- </div>
325
- </template>
326
- </v-data-table>
327
- </v-card>
328
- </template>
71
+ const fileNode = expandToNode `
72
+ <script setup>
73
+ import { ref, computed, inject, onMounted } from "vue";
74
+
75
+ const props = defineProps({
76
+ context: Object,
77
+ primaryColor: String,
78
+ secondaryColor: String,
79
+ tertiaryColor: String
80
+ });
81
+
82
+ const document = inject('rawDocument');
83
+ const search = ref('');
84
+ const loading = ref(false);
85
+
86
+ const data = ref([]);
87
+
88
+ function updateEffects() {
89
+ data.value = Array.from(document.allApplicableEffects());
90
+ }
91
+
92
+ updateEffects();
93
+
94
+ Hooks.on("createActiveEffect", updateEffects);
95
+ Hooks.on("updateActiveEffect", updateEffects);
96
+ Hooks.on("deleteActiveEffect", updateEffects);
97
+
98
+ const headers = [
99
+ {
100
+ title: game.i18n.localize("Image"),
101
+ key: 'img',
102
+ sortable: false,
103
+ width: '50px',
104
+ maxWidth: '50px'
105
+ },
106
+ {
107
+ title: game.i18n.localize("Name"),
108
+ key: 'name',
109
+ sortable: true,
110
+ minWidth: '120px'
111
+ },
112
+ {
113
+ title: game.i18n.localize("Source"),
114
+ key: 'source',
115
+ sortable: true,
116
+ minWidth: '120px'
117
+ },
118
+ {
119
+ title: game.i18n.localize("Duration"),
120
+ key: 'duration',
121
+ sortable: true,
122
+ minWidth: '100px'
123
+ },
124
+ {
125
+ title: game.i18n.localize("Actions"),
126
+ key: 'actions',
127
+ sortable: false,
128
+ width: '150px',
129
+ align: 'center'
130
+ }
131
+ ];
132
+
133
+ const editItem = (item) => {
134
+ const foundryItem = document.effects.get(item._id);
135
+ foundryItem.sheet.render(true);
136
+ };
137
+
138
+ const toggleEffect = async (item) => {
139
+ const update = {
140
+ _id: item._id,
141
+ disabled: !item.disabled
142
+ };
143
+ item.disabled = !item.disabled;
144
+ document.updateEmbeddedDocuments("ActiveEffect", [update]);
145
+ };
146
+
147
+ const deleteEffect = async (item) => {
148
+ const shouldDelete = await Dialog.confirm({
149
+ title: "Delete Confirmation",
150
+ content: \`<p>Are you sure you would like to delete the "\${item.name}" Effect?</p>\`,
151
+ defaultYes: false
152
+ });
153
+ if (shouldDelete) {
154
+ await document.deleteEmbeddedDocuments("ActiveEffect", [item.id]);
155
+ // Don't call updateEffects() here as the Hooks will handle it
156
+ };
157
+ };
158
+
159
+ const addNewEffect = async () => {
160
+ loading.value = true;
161
+ try {
162
+ const effects = await ActiveEffect.createDocuments([{
163
+ name: "New Effect",
164
+ icon: "icons/svg/aura.svg"
165
+ }], {parent: document});
166
+
167
+ if (effects && effects[0]) {
168
+ effects[0].sheet.render(true);
169
+ updateEffects();
170
+ }
171
+ } catch (error) {
172
+ console.error("Error creating effect:", error);
173
+ ui.notifications.error("Failed to create new effect");
174
+ } finally {
175
+ loading.value = false;
176
+ }
177
+ };
178
+
179
+ const formatDuration = (effect) => {
180
+ if (!effect.duration) return "Permanent";
181
+ if (effect.duration.type === "none") return "Permanent";
182
+ if (effect.duration.type === "turns") {
183
+ return \`\${effect.duration.remaining} turns\`;
184
+ }
185
+ if (effect.duration.type === "seconds") {
186
+ return \`\${effect.duration.remaining} seconds\`;
187
+ }
188
+ return "Temporary";
189
+ };
190
+ </script>
191
+
192
+ <template>
193
+ <v-card flat class="isdl-datatable">
194
+ <v-card-title class="d-flex align-center pe-1" style="height: 40px;">
195
+ <v-icon icon="fa-solid fa-sparkles" size="small" />
196
+ &nbsp; {{ game.i18n.localize("Effects") }}
197
+ <v-spacer></v-spacer>
198
+ <v-text-field
199
+ v-model="search"
200
+ density="compact"
201
+ label="Search"
202
+ prepend-inner-icon="fa-solid fa-magnify"
203
+ variant="outlined"
204
+ flat
205
+ hide-details
206
+ single-line
207
+ clearable
208
+ style="margin: 0; margin-right: 8px;"
209
+ ></v-text-field>
210
+ <v-btn
211
+ :color="primaryColor || 'primary'"
212
+ prepend-icon="fa-solid fa-plus"
213
+ rounded="0"
214
+ size="small"
215
+ :loading="loading"
216
+ @click="addNewEffect"
217
+ style="max-width: 80px; height: 38px;"
218
+ >
219
+ {{ game.i18n.localize("Add") }}
220
+ </v-btn>
221
+ </v-card-title>
222
+ <v-divider></v-divider>
223
+
224
+ <v-data-table
225
+ v-model:search="search"
226
+ :headers="headers"
227
+ :items="data"
228
+ :search="search"
229
+ hover
230
+ density="compact"
231
+ hide-default-footer
232
+ style="background: none;"
233
+ class="custom-datatable"
234
+ >
235
+ <!-- Image slot -->
236
+ <template v-slot:item.img="{ item }">
237
+ <v-avatar size="40" rounded="0">
238
+ <v-img :src="item.img ?? item.icon" :alt="item.name" cover></v-img>
239
+ </v-avatar>
240
+ </template>
241
+
242
+ <!-- Name slot -->
243
+ <template v-slot:item.name="{ item }">
244
+ <div class="d-flex align-center">
245
+ <div class="font-weight-medium text-truncate" style="min-width: 120px; max-width: 200px;">{{ item.name }}</div>
246
+ </div>
247
+ </template>
248
+
249
+ <!-- Source slot -->
250
+ <template v-slot:item.source="{ item }">
251
+ <v-chip
252
+ label
253
+ size="x-small"
254
+ variant="elevated"
255
+ class="text-caption text-truncate"
256
+ style="max-width: 150px;"
257
+ :data-tooltip="item.flags?.['${id}']?.source || 'Unknown'">
258
+ {{ item.flags?.['${id}']?.source || 'Unknown' }}
259
+ </v-chip>
260
+ </template>
261
+
262
+ <!-- Duration slot -->
263
+ <template v-slot:item.duration="{ item }">
264
+ <v-chip
265
+ label
266
+ size="x-small"
267
+ variant="elevated"
268
+ class="text-caption"
269
+ :color="item.duration?.type === 'none' ? 'primary' : 'secondary'"
270
+ >
271
+ {{ formatDuration(item) }}
272
+ </v-chip>
273
+ </template>
274
+
275
+ <!-- Actions slot -->
276
+ <template v-slot:item.actions="{ item }">
277
+ <div class="d-flex align-center justify-center ga-1">
278
+ <v-tooltip :text="item.disabled ? 'Enable' : 'Disable'">
279
+ <template v-slot:activator="{ props }">
280
+ <v-btn
281
+ v-bind="props"
282
+ :icon="item.disabled ? 'fa-solid fa-pause' : 'fa-solid fa-play'"
283
+ size="x-small"
284
+ variant="text"
285
+ :color="item.disabled ? 'warning' : 'success'"
286
+ @click="toggleEffect(item)"
287
+ ></v-btn>
288
+ </template>
289
+ </v-tooltip>
290
+ <v-tooltip text="Edit">
291
+ <template v-slot:activator="{ props }">
292
+ <v-btn
293
+ v-bind="props"
294
+ icon="fa-solid fa-edit"
295
+ size="x-small"
296
+ variant="text"
297
+ @click="editItem(item)"
298
+ ></v-btn>
299
+ </template>
300
+ </v-tooltip>
301
+ <v-tooltip text="Delete">
302
+ <template v-slot:activator="{ props }">
303
+ <v-btn
304
+ v-bind="props"
305
+ icon="fa-solid fa-trash"
306
+ size="x-small"
307
+ variant="text"
308
+ color="error"
309
+ @click="deleteEffect(item)"
310
+ ></v-btn>
311
+ </template>
312
+ </v-tooltip>
313
+ </div>
314
+ </template>
315
+
316
+ <!-- No data slot -->
317
+ <template v-slot:no-data>
318
+ <div class="text-center pa-4">
319
+ <v-icon size="48" color="grey-lighten-1">fa-solid fa-magic</v-icon>
320
+ <div class="text-h6 mt-2">No effects found</div>
321
+ <div class="text-body-2 text-medium-emphasis">
322
+ Add your first effect to get started
323
+ </div>
324
+ </div>
325
+ </template>
326
+ </v-data-table>
327
+ </v-card>
328
+ </template>
329
329
  `;
330
330
  fs.writeFileSync(generatedFilePath, toString(fileNode));
331
331
  }
332
332
  function importPageOfPinnedDataTable(page) {
333
333
  const pinned = getAllOfType(page.body, isPinnedField, true);
334
- return expandToNode `
335
- ${joinToNode(pinned, pinnedField => importPinnedDataTable(pinnedField), { appendNewLineIfNotEmpty: true })}
334
+ return expandToNode `
335
+ ${joinToNode(pinned, pinnedField => importPinnedDataTable(pinnedField), { appendNewLineIfNotEmpty: true })}
336
336
  `;
337
337
  }
338
338
  function importActionComponent(action) {
339
339
  generateActionComponent(entry, id, document, action, destination);
340
340
  const componentName = `${document.name.toLowerCase()}${action.name}Action`;
341
- return expandToNode `
342
- import ${componentName} from './components/actions/${componentName}.vue';
341
+ return expandToNode `
342
+ import ${componentName} from './components/actions/${componentName}.vue';
343
343
  `;
344
344
  }
345
345
  function importDocumentChoiceComponent(documentChoice) {
346
346
  generateDocumentChoiceComponent(entry, id, document, documentChoice, destination);
347
347
  const componentName = `${document.name.toLowerCase()}${documentChoice.name}DocumentChoice`;
348
- return expandToNode `
349
- import ${componentName} from './components/document-choices/${componentName}.vue';
348
+ return expandToNode `
349
+ import ${componentName} from './components/document-choices/${componentName}.vue';
350
350
  `;
351
351
  }
352
352
  function importDocumentChoicesComponent(documentChoices) {
353
353
  generateDocumentChoicesComponent(entry, id, document, documentChoices, destination);
354
354
  const componentName = `${document.name.toLowerCase()}${documentChoices.name}DocumentChoices`;
355
- return expandToNode `
356
- import ${componentName} from './components/document-choices/${componentName}.vue';
355
+ return expandToNode `
356
+ import ${componentName} from './components/document-choices/${componentName}.vue';
357
357
  `;
358
358
  }
359
359
  function paperDollSlots(element) {
@@ -368,17 +368,17 @@ function generateVueComponentScript(entry, id, document, destination) {
368
368
  top: (_c = property.top) !== null && _c !== void 0 ? _c : "0px",
369
369
  });
370
370
  }
371
- return expandToNode `
372
- const ${element.name.toLowerCase()}Slots = [
373
- ${joinToNode(slots, slot => expandToNode `
374
- {
375
- name: '${slot.name}',
376
- systemPath: '${slot.systemPath}',
377
- type: '${slot.type}',
378
- left: '${slot.left}',
379
- top: '${slot.top}'
380
- }`, { separator: ',', appendNewLineIfNotEmpty: true })}
381
- ];
371
+ return expandToNode `
372
+ const ${element.name.toLowerCase()}Slots = [
373
+ ${joinToNode(slots, slot => expandToNode `
374
+ {
375
+ name: '${slot.name}',
376
+ systemPath: '${slot.systemPath}',
377
+ type: '${slot.type}',
378
+ left: '${slot.left}',
379
+ top: '${slot.top}'
380
+ }`, { separator: ',', appendNewLineIfNotEmpty: true })}
381
+ ];
382
382
  `;
383
383
  }
384
384
  const properties = getAllOfType(document.body, isProperty, false);
@@ -404,101 +404,101 @@ function generateVueComponentScript(entry, id, document, destination) {
404
404
  });
405
405
  // If there's only a modifier and no visibility param, return the modifier
406
406
  if (element.modifier != undefined && !visibilityParam) {
407
- return expandToNode `
408
- '${element.name.toLowerCase()}': computed(() => {
409
- return '${element.modifier}';
410
- })
407
+ return expandToNode `
408
+ '${element.name.toLowerCase()}': computed(() => {
409
+ return '${element.modifier}';
410
+ })
411
411
  `;
412
412
  }
413
413
  if (visibilityParam) {
414
414
  if (isMethodBlock(visibilityParam.visibility)) {
415
415
  // If the visibility is a method block, we need to return a function that returns the visibility
416
- return expandToNode `
417
- '${element.name.toLowerCase()}': computed(() => {
418
- let editMode = editModeRef.value;
419
- let combatant = currentCombatant.value; // This will kick the recalc when changed
420
- let update = {};
421
- let embeddedUpdate = {};
422
- let parentUpdate = {};
423
- let parentEmbeddedUpdate = {};
424
- let targetUpdate = {};
425
- let targetEmbeddedUpdate = {};
426
- let selfDeleted = false;
427
- let rerender = false;
428
- const context = {
429
- object: document,
430
- target: game.user.getTargetOrNothing()
431
- };
432
- // If this is an item, attach the parent
433
- if (document.documentName === "Item" && document.parent) {
434
- context.actor = document.parent;
435
- }
436
- else {
437
- context.actor = document;
438
- }
439
- const visibility = (system) => {
440
- ${translateBodyExpressionToJavascript(entry, id, visibilityParam.visibility.body, false, element)}
441
- };
442
- const returnedVisibility = visibility(props.context.system);
443
- console.log("Returned visibility for ${element.name}: " + returnedVisibility);
444
-
445
- return returnedVisibility ?? "${(_a = element.modifier) !== null && _a !== void 0 ? _a : 'default'}";
446
- })
416
+ return expandToNode `
417
+ '${element.name.toLowerCase()}': computed(() => {
418
+ let editMode = editModeRef.value;
419
+ let combatant = currentCombatant.value; // This will kick the recalc when changed
420
+ let update = {};
421
+ let embeddedUpdate = {};
422
+ let parentUpdate = {};
423
+ let parentEmbeddedUpdate = {};
424
+ let targetUpdate = {};
425
+ let targetEmbeddedUpdate = {};
426
+ let selfDeleted = false;
427
+ let rerender = false;
428
+ const context = {
429
+ object: document,
430
+ target: game.user.getTargetOrNothing()
431
+ };
432
+ // If this is an item, attach the parent
433
+ if (document.documentName === "Item" && document.parent) {
434
+ context.actor = document.parent;
435
+ }
436
+ else {
437
+ context.actor = document;
438
+ }
439
+ const visibility = (system) => {
440
+ ${translateBodyExpressionToJavascript(entry, id, visibilityParam.visibility.body, false, element)}
441
+ };
442
+ const returnedVisibility = visibility(props.context.system);
443
+ console.log("Returned visibility for ${element.name}: " + returnedVisibility);
444
+
445
+ return returnedVisibility ?? "${(_a = element.modifier) !== null && _a !== void 0 ? _a : 'default'}";
446
+ })
447
447
  `;
448
448
  }
449
449
  // VisibilityValue is an AST node; emit its literal value (e.g. "gmOnly"),
450
450
  // not the stringified node ("[object Object]").
451
- return expandToNode `
452
- '${element.name.toLowerCase()}': computed(() => {
453
- return '${visibilityParam.visibility.visibility}';
454
- })
451
+ return expandToNode `
452
+ '${element.name.toLowerCase()}': computed(() => {
453
+ return '${visibilityParam.visibility.visibility}';
454
+ })
455
455
  `;
456
456
  }
457
457
  }
458
- return expandToNode `
459
- '${element.name.toLowerCase()}': computed(() => {
460
- return 'default';
461
- })
458
+ return expandToNode `
459
+ '${element.name.toLowerCase()}': computed(() => {
460
+ return 'default';
461
+ })
462
462
  `;
463
463
  }
464
464
  const attributes = getAllOfType(document.body, isAttributeExp, false);
465
465
  function generateAttributeRollMethod(attribute) {
466
466
  const rollParam = attribute.params.find(isAttributeRollParam);
467
467
  if (rollParam) {
468
- return expandToNode `
469
- const on${toMachineIdentifier(attribute.name)}AttributeRoll = async () => {
470
- const context = {
471
- object: document
472
- };
473
- const roll = ${translateExpression(entry, id, rollParam.roll, false, attribute)};
474
- // Create the chat message
475
- const ${attribute.name}Description = context.object.description ?? context.object.system.description;
476
- const ${attribute.name}Context = {
477
- cssClass: "${id} ${toMachineIdentifier(attribute.name)}",
478
- document: context.object,
479
- description: ${attribute.name}Description,
480
- hasDescription: ${attribute.name}Description!= "",
481
- parts: [
482
- {
483
- label: "${humanize(attribute.name)} Attribute Roll",
484
- value: roll,
485
- isRoll: true,
486
- wide: true,
487
- tooltip: await roll.getTooltip()
488
- }
489
- ],
490
- tags: []
491
- };
492
- const ${attribute.name}Content = await renderTemplate("systems/${id}/system/templates/chat/standard-card.hbs", ${attribute.name}Context);
493
- await ChatMessage.create({
494
- user: game.user._id,
495
- speaker: ChatMessage.getSpeaker(),
496
- content: ${attribute.name}Content,
497
- flavor: "",
498
- ...(${attribute.name}Context.parts.find(x => x.isRoll) ? {} : { style: CONST.CHAT_MESSAGE_STYLES.IC }),
499
- rolls: Array.from(${attribute.name}Context.parts.filter(x => x.isRoll).map(x => x.value)),
500
- });
501
- };
468
+ return expandToNode `
469
+ const on${toMachineIdentifier(attribute.name)}AttributeRoll = async () => {
470
+ const context = {
471
+ object: document
472
+ };
473
+ const roll = ${translateExpression(entry, id, rollParam.roll, false, attribute)};
474
+ // Create the chat message
475
+ const ${attribute.name}Description = context.object.description ?? context.object.system.description;
476
+ const ${attribute.name}Context = {
477
+ cssClass: "${id} ${toMachineIdentifier(attribute.name)}",
478
+ document: context.object,
479
+ description: ${attribute.name}Description,
480
+ hasDescription: ${attribute.name}Description!= "",
481
+ parts: [
482
+ {
483
+ label: "${humanize(attribute.name)} Attribute Roll",
484
+ value: roll,
485
+ isRoll: true,
486
+ wide: true,
487
+ tooltip: await roll.getTooltip()
488
+ }
489
+ ],
490
+ tags: []
491
+ };
492
+ const ${attribute.name}Content = await renderTemplate("systems/${id}/system/templates/chat/standard-card.hbs", ${attribute.name}Context);
493
+ await ChatMessage.create({
494
+ user: game.user._id,
495
+ speaker: ChatMessage.getSpeaker(),
496
+ content: ${attribute.name}Content,
497
+ flavor: "",
498
+ ...(${attribute.name}Context.parts.find(x => x.isRoll) ? {} : { style: CONST.CHAT_MESSAGE_STYLES.IC }),
499
+ rolls: Array.from(${attribute.name}Context.parts.filter(x => x.isRoll).map(x => x.value)),
500
+ });
501
+ };
502
502
  `;
503
503
  }
504
504
  return expandToNode ``;
@@ -508,235 +508,235 @@ function generateVueComponentScript(entry, id, document, destination) {
508
508
  function generateAttributeFunctionMethod(attribute) {
509
509
  const functionParam = attribute.params.find(isAttributeFunctionParam);
510
510
  if (functionParam) {
511
- return expandToNode `
512
- const on${attribute.name}AttributeFunction = async (event) => {
513
- await document.sheet._on${attribute.name}AttributeFunction(event);
514
- };
511
+ return expandToNode `
512
+ const on${attribute.name}AttributeFunction = async (event) => {
513
+ await document.sheet._on${attribute.name}AttributeFunction(event);
514
+ };
515
515
  `;
516
516
  }
517
517
  return expandToNode ``;
518
518
  }
519
- return expandToNode `
520
- <script setup>
521
- import { ref, watch, inject, computed, watchEffect } from "vue";
522
- ${joinToNode(allTables, table => importDataTable2(table), { appendNewLineIfNotEmpty: true })}
523
- ${joinToNode(pages, importPageOfPinnedDataTable, { appendNewLineIfNotEmpty: true })}
524
- ${joinToNode(actions, importActionComponent, { appendNewLineIfNotEmpty: true })}
525
- ${joinToNode(documentChoices, importDocumentChoiceComponent, { appendNewLineIfNotEmpty: true })}
526
- ${joinToNode(documentChoicesPlural, importDocumentChoicesComponent, { appendNewLineIfNotEmpty: true })}
527
- ${importEffectsDataTable()}
528
- ${joinToNode(firstPagePinned, (pinned) => importPinnedDataTable(pinned), { appendNewLineIfNotEmpty: true })}
529
- import ${entry.config.name}Roll from "../../../../rolls/roll.mjs";
530
-
531
- const document = inject('rawDocument');
532
- const props = defineProps(['context']);
533
-
534
- // Colors
535
- let storedColors = game.settings.get('${id}', 'documentColorThemes');
536
- const primaryColor = ref(storedColors[document.uuid]?.primary ?? '#1565c0');
537
- const secondaryColor = ref(storedColors[document.uuid]?.secondary ?? '#4db6ac');
538
- const tertiaryColor = ref(storedColors[document.uuid]?.tertiary ?? '#ffb74d');
539
-
540
- const setupColors = () => {
541
- const colors = {
542
- primary: primaryColor.value,
543
- secondary: secondaryColor.value,
544
- tertiary: tertiaryColor.value
545
- };
546
- game.settings.set('${id}', 'documentColorThemes', { ...storedColors, [document.uuid]: colors });
547
- };
548
- const resetColors = () => {
549
- primaryColor.value = '#1565c0';
550
- secondaryColor.value = '#4db6ac';
551
- tertiaryColor.value = '#ffb74d';
552
- setupColors();
553
- };
554
-
555
- watch(primaryColor, () => {
556
- setupColors();
557
- });
558
- watch(secondaryColor, () => {
559
- setupColors();
560
- });
561
- watch(tertiaryColor, () => {
562
- setupColors();
563
- });
564
-
565
- // Pages and Tabs
566
- const lastStates = game.settings.get('${id}', 'documentLastState');
567
- const lastState = lastStates[document.uuid] ?? {
568
- page: '${document.name.toLowerCase()}',
569
- tab: 'description'
570
- };
571
-
572
- const drawer = ref(false);
573
- const page = ref(lastState.page);
574
- const tab = ref(lastState.tab);
575
- const pageDefaultTabs = {
576
- '${document.name.toLowerCase()}': 'description'
577
- };
578
-
579
- const updateLastState = () => {
580
- const lastStates = game.settings.get('${id}', 'documentLastState');
581
- lastStates[document.uuid] = { page: page.value, tab: tab.value };
582
- game.settings.set('${id}', 'documentLastState', lastStates);
583
- };
584
-
585
- // When the page changes, reset the tab to the first tab on that page
586
- watch(page, () => {
587
- tab.value = pageDefaultTabs[page.value.toLowerCase()];
588
- document.sheet.dragDrop.forEach((d) => d.bind(document.sheet.element));
589
- // Dismiss the drawer when the page changes
590
- drawer.value = false;
591
- updateLastState();
592
- });
593
-
594
- watch(tab, () => {
595
- try {
596
- if (document.sheet?.element) {
597
- document.sheet.dragDrop.forEach((d) => d.bind(document.sheet.element));
598
- }
599
- }
600
- catch {}
601
- updateLastState();
602
- });
603
-
604
- const pageBackgrounds = {
605
- '${document.name.toLowerCase()}': 'topography',
606
- ${joinToNode(pages, getPageBackground, { separator: ',', appendNewLineIfNotEmpty: true })}
607
- };
608
-
609
- const pageBackground = computed(() => {
610
- if (editModeRef.value) {
611
- return 'edit-mode';
612
- }
613
- if (props.context.system.dead) {
614
- return 'dead';
615
- }
616
- return pageBackgrounds[page.value];
617
- });
618
-
619
- // Edit Mode
620
- const editModeRef = ref(document.getFlag('${id}', 'edit-mode') ?? true);
621
- const hovered = ref(false);
622
-
623
- const toggleEditMode = () => {
624
- editModeRef.value = !editModeRef.value;
625
- document.setFlag('${id}', 'edit-mode', editModeRef.value);
626
- };
627
-
628
- function spawnDatatableWindow(e, pageName, tabName) {
629
- if (event.button === 1) {
630
- event.preventDefault();
631
- event.stopPropagation();
632
- const tableName = \`${isActor(document) ? 'actor' : 'item'}${document.name}\${pageName}\${tabName}\`;
633
- const systemName = "system." + tabName.toLowerCase();
634
- const sheet = new game.system.datatableApp(document, tableName, systemName, tabName);
635
- sheet.render(true);
636
- }
637
- }
638
-
639
- // Effects
640
- const effects = ref([]);
641
-
642
- function updateEffects() {
643
- effects.value = Array.from(document.allApplicableEffects());
644
- }
645
-
646
- updateEffects();
647
-
648
- Hooks.on("createActiveEffect", updateEffects);
649
- Hooks.on("updateActiveEffect", updateEffects);
650
- Hooks.on("deleteActiveEffect", updateEffects);
651
-
652
- // Combat
653
- const currentCombatant = ref(game.combat?.combatant);
654
- Hooks.on("combatTurnChange", () => {
655
- currentCombatant.value = game.combat?.combatant;
656
- });
657
-
658
- // Paper Doll Slots
659
- ${joinToNode(paperDoll, paperDollSlots, { appendNewLineIfNotEmpty: true })}
660
-
661
- // Visibility states
662
- const visibilityStates = {
663
- ${joinToNode(properties, generateVisibilityState, { separator: ',', appendNewLineIfNotEmpty: true })},
664
- ${joinToNode(actions, generateVisibilityState, { separator: ',', appendNewLineIfNotEmpty: true })}
665
- };
666
-
667
- // Computed fields mapping
668
- const computedFields = {
669
- ${joinToNode(properties, prop => expandToNode `'${prop.name.toLowerCase()}': ${isComputedField(prop)}`, { separator: ',', appendNewLineIfNotEmpty: true })},
670
- ${joinToNode(actions, action => expandToNode `'${action.name.toLowerCase()}': ${isComputedField(action)}`, { separator: ',', appendNewLineIfNotEmpty: true })}
671
- };
672
-
673
-
674
- const isHidden = (type) => {
675
- const visibility = visibilityStates[type].value;
676
- if (visibility === "hidden") {
677
- return true;
678
- }
679
- if (visibility === "gmOnly") {
680
- return !game.user.isGM;
681
- }
682
- if (visibility === "secret") {
683
- const isGm = game.user.isGM;
684
- const isOwner = document.getUserLevel(game.user) === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
685
- return !isGm && !isOwner;
686
- }
687
- if (visibility === "edit") {
688
- return !editModeRef.value;
689
- }
690
- if (visibility === "play") {
691
- return editModeRef.value;
692
- }
693
-
694
- // Default to visible
695
- return false;
696
- };
697
-
698
- const isDisabled = (type) => {
699
- // Computed fields are always disabled
700
- if (computedFields[type]) {
701
- //console.log(type + " is computed and disabled");
702
- return true;
703
- }
704
-
705
- const visibility = visibilityStates[type].value;
706
- const disabledStates = ["readonly", "locked"];
707
- if (disabledStates.includes(visibility)) {
708
- //console.log(type + " is readonly / locked and disabled");
709
- return true;
710
- }
711
- if (visibility === "gmEdit") {
712
- const isGm = game.user.isGM;
713
- const isEditMode = editModeRef.value;
714
- return !isGm && !isEditMode;
715
- }
716
-
717
- if (visibility === "unlocked") {
718
- //console.log(type + " is unlocked and enabled");
719
- return false;
720
- }
721
-
722
- // Default to enabled while in editMode
723
- return !editModeRef.value;
724
- };
725
-
726
- const getLabel = (label, icon) => {
727
- const localized = game.i18n.localize(label);
728
- if (icon) {
729
- return \`<i class="\${icon}"></i> \${localized}\`;
730
- }
731
- return localized;
732
- };
733
-
734
- // Attribute roll methods
735
- ${joinToNode(attributes, generateAttributeRollMethod, { appendNewLineIfNotEmpty: true })}
736
- ${joinToNode(attributes, generateAttributeFunctionMethod, { appendNewLineIfNotEmpty: true })}
737
- </script>
738
- <style>
739
- </style>
519
+ return expandToNode `
520
+ <script setup>
521
+ import { ref, watch, inject, computed, watchEffect } from "vue";
522
+ ${joinToNode(allTables, table => importDataTable2(table), { appendNewLineIfNotEmpty: true })}
523
+ ${joinToNode(pages, importPageOfPinnedDataTable, { appendNewLineIfNotEmpty: true })}
524
+ ${joinToNode(actions, importActionComponent, { appendNewLineIfNotEmpty: true })}
525
+ ${joinToNode(documentChoices, importDocumentChoiceComponent, { appendNewLineIfNotEmpty: true })}
526
+ ${joinToNode(documentChoicesPlural, importDocumentChoicesComponent, { appendNewLineIfNotEmpty: true })}
527
+ ${importEffectsDataTable()}
528
+ ${joinToNode(firstPagePinned, (pinned) => importPinnedDataTable(pinned), { appendNewLineIfNotEmpty: true })}
529
+ import ${entry.config.name}Roll from "../../../../rolls/roll.mjs";
530
+
531
+ const document = inject('rawDocument');
532
+ const props = defineProps(['context']);
533
+
534
+ // Colors
535
+ let storedColors = game.settings.get('${id}', 'documentColorThemes');
536
+ const primaryColor = ref(storedColors[document.uuid]?.primary ?? '#1565c0');
537
+ const secondaryColor = ref(storedColors[document.uuid]?.secondary ?? '#4db6ac');
538
+ const tertiaryColor = ref(storedColors[document.uuid]?.tertiary ?? '#ffb74d');
539
+
540
+ const setupColors = () => {
541
+ const colors = {
542
+ primary: primaryColor.value,
543
+ secondary: secondaryColor.value,
544
+ tertiary: tertiaryColor.value
545
+ };
546
+ game.settings.set('${id}', 'documentColorThemes', { ...storedColors, [document.uuid]: colors });
547
+ };
548
+ const resetColors = () => {
549
+ primaryColor.value = '#1565c0';
550
+ secondaryColor.value = '#4db6ac';
551
+ tertiaryColor.value = '#ffb74d';
552
+ setupColors();
553
+ };
554
+
555
+ watch(primaryColor, () => {
556
+ setupColors();
557
+ });
558
+ watch(secondaryColor, () => {
559
+ setupColors();
560
+ });
561
+ watch(tertiaryColor, () => {
562
+ setupColors();
563
+ });
564
+
565
+ // Pages and Tabs
566
+ const lastStates = game.settings.get('${id}', 'documentLastState');
567
+ const lastState = lastStates[document.uuid] ?? {
568
+ page: '${document.name.toLowerCase()}',
569
+ tab: 'description'
570
+ };
571
+
572
+ const drawer = ref(false);
573
+ const page = ref(lastState.page);
574
+ const tab = ref(lastState.tab);
575
+ const pageDefaultTabs = {
576
+ '${document.name.toLowerCase()}': 'description'
577
+ };
578
+
579
+ const updateLastState = () => {
580
+ const lastStates = game.settings.get('${id}', 'documentLastState');
581
+ lastStates[document.uuid] = { page: page.value, tab: tab.value };
582
+ game.settings.set('${id}', 'documentLastState', lastStates);
583
+ };
584
+
585
+ // When the page changes, reset the tab to the first tab on that page
586
+ watch(page, () => {
587
+ tab.value = pageDefaultTabs[page.value.toLowerCase()];
588
+ document.sheet.dragDrop.forEach((d) => d.bind(document.sheet.element));
589
+ // Dismiss the drawer when the page changes
590
+ drawer.value = false;
591
+ updateLastState();
592
+ });
593
+
594
+ watch(tab, () => {
595
+ try {
596
+ if (document.sheet?.element) {
597
+ document.sheet.dragDrop.forEach((d) => d.bind(document.sheet.element));
598
+ }
599
+ }
600
+ catch {}
601
+ updateLastState();
602
+ });
603
+
604
+ const pageBackgrounds = {
605
+ '${document.name.toLowerCase()}': 'topography',
606
+ ${joinToNode(pages, getPageBackground, { separator: ',', appendNewLineIfNotEmpty: true })}
607
+ };
608
+
609
+ const pageBackground = computed(() => {
610
+ if (editModeRef.value) {
611
+ return 'edit-mode';
612
+ }
613
+ if (props.context.system.dead) {
614
+ return 'dead';
615
+ }
616
+ return pageBackgrounds[page.value];
617
+ });
618
+
619
+ // Edit Mode
620
+ const editModeRef = ref(document.getFlag('${id}', 'edit-mode') ?? true);
621
+ const hovered = ref(false);
622
+
623
+ const toggleEditMode = () => {
624
+ editModeRef.value = !editModeRef.value;
625
+ document.setFlag('${id}', 'edit-mode', editModeRef.value);
626
+ };
627
+
628
+ function spawnDatatableWindow(e, pageName, tabName) {
629
+ if (event.button === 1) {
630
+ event.preventDefault();
631
+ event.stopPropagation();
632
+ const tableName = \`${isActor(document) ? 'actor' : 'item'}${document.name}\${pageName}\${tabName}\`;
633
+ const systemName = "system." + tabName.toLowerCase();
634
+ const sheet = new game.system.datatableApp(document, tableName, systemName, tabName);
635
+ sheet.render(true);
636
+ }
637
+ }
638
+
639
+ // Effects
640
+ const effects = ref([]);
641
+
642
+ function updateEffects() {
643
+ effects.value = Array.from(document.allApplicableEffects());
644
+ }
645
+
646
+ updateEffects();
647
+
648
+ Hooks.on("createActiveEffect", updateEffects);
649
+ Hooks.on("updateActiveEffect", updateEffects);
650
+ Hooks.on("deleteActiveEffect", updateEffects);
651
+
652
+ // Combat
653
+ const currentCombatant = ref(game.combat?.combatant);
654
+ Hooks.on("combatTurnChange", () => {
655
+ currentCombatant.value = game.combat?.combatant;
656
+ });
657
+
658
+ // Paper Doll Slots
659
+ ${joinToNode(paperDoll, paperDollSlots, { appendNewLineIfNotEmpty: true })}
660
+
661
+ // Visibility states
662
+ const visibilityStates = {
663
+ ${joinToNode(properties, generateVisibilityState, { separator: ',', appendNewLineIfNotEmpty: true })},
664
+ ${joinToNode(actions, generateVisibilityState, { separator: ',', appendNewLineIfNotEmpty: true })}
665
+ };
666
+
667
+ // Computed fields mapping
668
+ const computedFields = {
669
+ ${joinToNode(properties, prop => expandToNode `'${prop.name.toLowerCase()}': ${isComputedField(prop)}`, { separator: ',', appendNewLineIfNotEmpty: true })},
670
+ ${joinToNode(actions, action => expandToNode `'${action.name.toLowerCase()}': ${isComputedField(action)}`, { separator: ',', appendNewLineIfNotEmpty: true })}
671
+ };
672
+
673
+
674
+ const isHidden = (type) => {
675
+ const visibility = visibilityStates[type].value;
676
+ if (visibility === "hidden") {
677
+ return true;
678
+ }
679
+ if (visibility === "gmOnly") {
680
+ return !game.user.isGM;
681
+ }
682
+ if (visibility === "secret") {
683
+ const isGm = game.user.isGM;
684
+ const isOwner = document.getUserLevel(game.user) === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
685
+ return !isGm && !isOwner;
686
+ }
687
+ if (visibility === "edit") {
688
+ return !editModeRef.value;
689
+ }
690
+ if (visibility === "play") {
691
+ return editModeRef.value;
692
+ }
693
+
694
+ // Default to visible
695
+ return false;
696
+ };
697
+
698
+ const isDisabled = (type) => {
699
+ // Computed fields are always disabled
700
+ if (computedFields[type]) {
701
+ //console.log(type + " is computed and disabled");
702
+ return true;
703
+ }
704
+
705
+ const visibility = visibilityStates[type].value;
706
+ const disabledStates = ["readonly", "locked"];
707
+ if (disabledStates.includes(visibility)) {
708
+ //console.log(type + " is readonly / locked and disabled");
709
+ return true;
710
+ }
711
+ if (visibility === "gmEdit") {
712
+ const isGm = game.user.isGM;
713
+ const isEditMode = editModeRef.value;
714
+ return !isGm && !isEditMode;
715
+ }
716
+
717
+ if (visibility === "unlocked") {
718
+ //console.log(type + " is unlocked and enabled");
719
+ return false;
720
+ }
721
+
722
+ // Default to enabled while in editMode
723
+ return !editModeRef.value;
724
+ };
725
+
726
+ const getLabel = (label, icon) => {
727
+ const localized = game.i18n.localize(label);
728
+ if (icon) {
729
+ return \`<i class="\${icon}"></i> \${localized}\`;
730
+ }
731
+ return localized;
732
+ };
733
+
734
+ // Attribute roll methods
735
+ ${joinToNode(attributes, generateAttributeRollMethod, { appendNewLineIfNotEmpty: true })}
736
+ ${joinToNode(attributes, generateAttributeFunctionMethod, { appendNewLineIfNotEmpty: true })}
737
+ </script>
738
+ <style>
739
+ </style>
740
740
  `;
741
741
  }
742
742
  function generateVueComponentTemplate(entry, id, document) {
@@ -744,138 +744,138 @@ function generateVueComponentTemplate(entry, id, document) {
744
744
  const firstPageTables = document.body.filter(isTableField); // We explicitly only want top-level tables
745
745
  const firstPagePinned = document.body.filter(isPinnedField); // We explicitly only want top-level pinned fields
746
746
  const firstPageInventories = document.body.filter(isInventoryField); // We explicitly only want top-level inventories
747
- return expandToNode `
748
- <template>
749
- <v-app>
750
- <!-- App Bar -->
751
- <v-app-bar :color="editModeRef ? 'amber-accent-3' : primaryColor" density="comfortable">
752
- <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
753
- <v-app-bar-title v-if="!editModeRef">{{ context.document.name }}</v-app-bar-title>
754
- <v-text-field name="name" v-model="context.document.name" variant="outlined" class="document-name" v-if="editModeRef" density="compact"></v-text-field>
755
- <v-alert :text="game.i18n.localize('EditModeWarning')" type="warning" density="compact" class="ga-2 ma-1" color="amber-accent-3" v-if="editModeRef"></v-alert>
756
- <template v-slot:append>
757
- <v-btn
758
- :icon="hovered ? (editModeRef ? 'fa-solid fa-dice-d20' : 'fa-solid fa-pen-to-square') : (editModeRef ? 'fa-solid fa-pen-to-square' : 'fa-solid fa-dice-d20')"
759
- @click="toggleEditMode"
760
- @mouseover="hovered = true"
761
- @mouseleave="hovered = false"
762
- :data-tooltip="editModeRef ? 'Swap to Play mode' : 'Swap to Edit mode'"
763
- ></v-btn>
764
- </template>
765
- </v-app-bar>
766
-
767
- <!-- Navigation Drawer -->
768
- <v-navigation-drawer v-model="drawer" temporary style="background-color: #dddddd">
769
- <v-img :src="context.document.img" style="background-color: lightgray" data-edit='img' data-action='onEditImage'>
770
- <template #error>
771
- <v-img src="/systems/${id}/img/missing-character.png" data-edit='img' data-action='onEditImage'></v-img>
772
- </template>
773
- </v-img>
774
- <v-tabs v-model="page" direction="vertical">
775
- <v-tab value="${document.name.toLowerCase()}" prepend-icon="fa-solid fa-circle-user">${document.name}</v-tab>
776
- ${joinToNode(pages, generateNavListItem, { appendNewLineIfNotEmpty: true })}
777
- </v-tabs>
778
- <template v-slot:append>
779
- <div class="pa-2">
780
- <v-btn block @click="setupColors" :color="secondaryColor" prepend-icon="fa-solid fa-palette">
781
- Setup Colors
782
-
783
- <v-dialog activator="parent" max-width="1000">
784
- <template v-slot:default="{ isActive }">
785
- <v-card
786
- title="Setup Colors"
787
- >
788
- <v-card-text>
789
- <div class="d-flex flex-row">
790
- <div class="d-flex flex-column">
791
- <v-label>Primary Color</v-label>
792
- <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="primaryColor" swatches-max-height="500px"></v-color-picker>
793
- </div>
794
- <v-spacer></v-spacer>
795
- <div class="d-flex flex-column">
796
- <v-label>Secondary Color</v-label>
797
- <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="secondaryColor" swatches-max-height="500px"></v-color-picker>
798
- </div>
799
- <v-spacer></v-spacer>
800
- <div class="d-flex flex-column">
801
- <v-label>Tertiary Color</v-label>
802
- <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="tertiaryColor" swatches-max-height="500px"></v-color-picker>
803
- </div>
804
- </div>
805
- <h3>Preview</h3>
806
- <div class="d-flex flex-row"style="overflow-x: scroll; padding-left: 0.5rem; padding-right: 0.5rem;">
807
- <div
808
- v-for="i in 10"
809
- :key="i"
810
- :style="{
811
- flex: 1,
812
- minWidth: '5px',
813
- flexShrink: 0,
814
- height: '30px',
815
- backgroundColor: i <= 4 ? primaryColor : (i <= 6 ? tertiaryColor : 'transparent'),
816
- border: i <= value ? 'none' : '2px solid ' + secondaryColor,
817
- transform: 'skewX(-20deg)',
818
- borderRadius: '2px'
819
- }"
820
- />
821
- </div>
822
- </v-card-text>
823
- <v-card-actions>
824
- <v-btn
825
- variant="tonal"
826
- prepend-icon="fa-solid fa-sync"
827
- text="Reset"
828
- :color="secondaryColor"
829
- @click="resetColors"
830
- ></v-btn>
831
- </v-card-actions>
832
- </v-card>
833
- </template>
834
- </v-dialog>
835
- </v-btn>
836
- </div>
837
- </template>
838
- </v-navigation-drawer>
839
-
840
- <!-- Main Content -->
841
- <v-main class="d-flex">
842
- <v-container :key="editModeRef" :class="pageBackground" fluid>
843
- <v-tabs-window v-model="page">
844
- <v-tabs-window-item value="${document.name.toLowerCase()}" data-tab="${document.name.toLowerCase()}">
845
- <v-row dense>
846
- ${joinToNode(document.body, element => generateElement(element, true), { appendNewLineIfNotEmpty: true })}
847
- </v-row>
848
- <v-divider class="mt-4 mb-2"></v-divider>
849
- <v-tabs v-model="tab" grow always-center>
850
- <v-tab value="description" prepend-icon="fa-solid fa-book">Description</v-tab>
851
- ${joinToNode(firstPageTables, table => generateSubTab(table), { appendNewLineIfNotEmpty: true })}
852
- ${joinToNode(firstPagePinned, (pinned) => generatePinnedTab(pinned), { appendNewLineIfNotEmpty: true })}
853
- ${joinToNode(firstPageInventories, inventory => generateSubTab(inventory), { appendNewLineIfNotEmpty: true })}
854
- <v-tab value="effects" prepend-icon="fa-solid fa-sparkles" @mousedown="spawnDatatableWindow($event, '${document.name}', 'effects')">Effects</v-tab>
855
- </v-tabs>
856
- <v-tabs-window v-model="tab" class="tabs-window">
857
- <v-tabs-window-item value="description" data-tab="description" class="tabs-container">
858
- <i-prosemirror :field="context.editors['system.description']" :disabled="!editModeRef"></i-prosemirror>
859
- </v-tabs-window-item>
860
- ${joinToNode(firstPageTables, table => generateVuetifyDatatable(document.name, table), { appendNewLineIfNotEmpty: true })}
861
- ${joinToNode(firstPagePinned, (pinned) => generatePinnedTabWindow(pinned), { appendNewLineIfNotEmpty: true })}
862
- ${joinToNode(firstPageInventories, inventory => generateInventoryTabWindow(document.name, inventory), { appendNewLineIfNotEmpty: true })}
863
- <v-tabs-window-item value="effects" data-tab="effects" class="tabs-container">
864
- <${document.name}EffectsVuetifyDatatable
865
- :context="context"
866
- :primaryColor="primaryColor"
867
- :secondaryColor="secondaryColor"
868
- :tertiaryColor="tertiaryColor"
869
- />
870
- </v-tabs-window-item>
871
- </v-tabs-window>
872
- </v-tabs-window-item>
873
- ${joinToNode(pages, generatePageBody, { appendNewLineIfNotEmpty: true })}
874
- </v-tabs-window>
875
- </v-container>
876
- </v-main>
877
- </v-app>
878
- </template>
747
+ return expandToNode `
748
+ <template>
749
+ <v-app>
750
+ <!-- App Bar -->
751
+ <v-app-bar :color="editModeRef ? 'amber-accent-3' : primaryColor" density="comfortable">
752
+ <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
753
+ <v-app-bar-title v-if="!editModeRef">{{ context.document.name }}</v-app-bar-title>
754
+ <v-text-field name="name" v-model="context.document.name" variant="outlined" class="document-name" v-if="editModeRef" density="compact"></v-text-field>
755
+ <v-alert :text="game.i18n.localize('EditModeWarning')" type="warning" density="compact" class="ga-2 ma-1" color="amber-accent-3" v-if="editModeRef"></v-alert>
756
+ <template v-slot:append>
757
+ <v-btn
758
+ :icon="hovered ? (editModeRef ? 'fa-solid fa-dice-d20' : 'fa-solid fa-pen-to-square') : (editModeRef ? 'fa-solid fa-pen-to-square' : 'fa-solid fa-dice-d20')"
759
+ @click="toggleEditMode"
760
+ @mouseover="hovered = true"
761
+ @mouseleave="hovered = false"
762
+ :data-tooltip="editModeRef ? 'Swap to Play mode' : 'Swap to Edit mode'"
763
+ ></v-btn>
764
+ </template>
765
+ </v-app-bar>
766
+
767
+ <!-- Navigation Drawer -->
768
+ <v-navigation-drawer v-model="drawer" temporary style="background-color: #dddddd">
769
+ <v-img :src="context.document.img" style="background-color: lightgray" data-edit='img' data-action='onEditImage'>
770
+ <template #error>
771
+ <v-img src="/systems/${id}/img/missing-character.png" data-edit='img' data-action='onEditImage'></v-img>
772
+ </template>
773
+ </v-img>
774
+ <v-tabs v-model="page" direction="vertical">
775
+ <v-tab value="${document.name.toLowerCase()}" prepend-icon="fa-solid fa-circle-user">${document.name}</v-tab>
776
+ ${joinToNode(pages, generateNavListItem, { appendNewLineIfNotEmpty: true })}
777
+ </v-tabs>
778
+ <template v-slot:append>
779
+ <div class="pa-2">
780
+ <v-btn block @click="setupColors" :color="secondaryColor" prepend-icon="fa-solid fa-palette">
781
+ Setup Colors
782
+
783
+ <v-dialog activator="parent" max-width="1000">
784
+ <template v-slot:default="{ isActive }">
785
+ <v-card
786
+ title="Setup Colors"
787
+ >
788
+ <v-card-text>
789
+ <div class="d-flex flex-row">
790
+ <div class="d-flex flex-column">
791
+ <v-label>Primary Color</v-label>
792
+ <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="primaryColor" swatches-max-height="500px"></v-color-picker>
793
+ </div>
794
+ <v-spacer></v-spacer>
795
+ <div class="d-flex flex-column">
796
+ <v-label>Secondary Color</v-label>
797
+ <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="secondaryColor" swatches-max-height="500px"></v-color-picker>
798
+ </div>
799
+ <v-spacer></v-spacer>
800
+ <div class="d-flex flex-column">
801
+ <v-label>Tertiary Color</v-label>
802
+ <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="tertiaryColor" swatches-max-height="500px"></v-color-picker>
803
+ </div>
804
+ </div>
805
+ <h3>Preview</h3>
806
+ <div class="d-flex flex-row"style="overflow-x: scroll; padding-left: 0.5rem; padding-right: 0.5rem;">
807
+ <div
808
+ v-for="i in 10"
809
+ :key="i"
810
+ :style="{
811
+ flex: 1,
812
+ minWidth: '5px',
813
+ flexShrink: 0,
814
+ height: '30px',
815
+ backgroundColor: i <= 4 ? primaryColor : (i <= 6 ? tertiaryColor : 'transparent'),
816
+ border: i <= value ? 'none' : '2px solid ' + secondaryColor,
817
+ transform: 'skewX(-20deg)',
818
+ borderRadius: '2px'
819
+ }"
820
+ />
821
+ </div>
822
+ </v-card-text>
823
+ <v-card-actions>
824
+ <v-btn
825
+ variant="tonal"
826
+ prepend-icon="fa-solid fa-sync"
827
+ text="Reset"
828
+ :color="secondaryColor"
829
+ @click="resetColors"
830
+ ></v-btn>
831
+ </v-card-actions>
832
+ </v-card>
833
+ </template>
834
+ </v-dialog>
835
+ </v-btn>
836
+ </div>
837
+ </template>
838
+ </v-navigation-drawer>
839
+
840
+ <!-- Main Content -->
841
+ <v-main class="d-flex">
842
+ <v-container :key="editModeRef" :class="pageBackground" fluid>
843
+ <v-tabs-window v-model="page">
844
+ <v-tabs-window-item value="${document.name.toLowerCase()}" data-tab="${document.name.toLowerCase()}">
845
+ <v-row dense>
846
+ ${joinToNode(document.body, element => generateElement(element, true), { appendNewLineIfNotEmpty: true })}
847
+ </v-row>
848
+ <v-divider class="mt-4 mb-2"></v-divider>
849
+ <v-tabs v-model="tab" grow always-center>
850
+ <v-tab value="description" prepend-icon="fa-solid fa-book">Description</v-tab>
851
+ ${joinToNode(firstPageTables, table => generateSubTab(table), { appendNewLineIfNotEmpty: true })}
852
+ ${joinToNode(firstPagePinned, (pinned) => generatePinnedTab(pinned), { appendNewLineIfNotEmpty: true })}
853
+ ${joinToNode(firstPageInventories, inventory => generateSubTab(inventory), { appendNewLineIfNotEmpty: true })}
854
+ <v-tab value="effects" prepend-icon="fa-solid fa-sparkles" @mousedown="spawnDatatableWindow($event, '${document.name}', 'effects')">Effects</v-tab>
855
+ </v-tabs>
856
+ <v-tabs-window v-model="tab" class="tabs-window">
857
+ <v-tabs-window-item value="description" data-tab="description" class="tabs-container">
858
+ <i-prosemirror :field="context.editors['system.description']" :disabled="!editModeRef"></i-prosemirror>
859
+ </v-tabs-window-item>
860
+ ${joinToNode(firstPageTables, table => generateVuetifyDatatable(document.name, table), { appendNewLineIfNotEmpty: true })}
861
+ ${joinToNode(firstPagePinned, (pinned) => generatePinnedTabWindow(pinned), { appendNewLineIfNotEmpty: true })}
862
+ ${joinToNode(firstPageInventories, inventory => generateInventoryTabWindow(document.name, inventory), { appendNewLineIfNotEmpty: true })}
863
+ <v-tabs-window-item value="effects" data-tab="effects" class="tabs-container">
864
+ <${document.name}EffectsVuetifyDatatable
865
+ :context="context"
866
+ :primaryColor="primaryColor"
867
+ :secondaryColor="secondaryColor"
868
+ :tertiaryColor="tertiaryColor"
869
+ />
870
+ </v-tabs-window-item>
871
+ </v-tabs-window>
872
+ </v-tabs-window-item>
873
+ ${joinToNode(pages, generatePageBody, { appendNewLineIfNotEmpty: true })}
874
+ </v-tabs-window>
875
+ </v-container>
876
+ </v-main>
877
+ </v-app>
878
+ </template>
879
879
  `;
880
880
  function generateSubTab(tab) {
881
881
  var _a, _b;
@@ -887,48 +887,48 @@ function generateVueComponentTemplate(entry, id, document) {
887
887
  // Check for label parameter
888
888
  const labelParam = params.find((p) => isLabelParam(p));
889
889
  const label = (_b = labelParam === null || labelParam === void 0 ? void 0 : labelParam.value) !== null && _b !== void 0 ? _b : `${document.name}.${tab.name}`;
890
- return expandToNode `
891
- <v-tab v-if="!isHidden('${tab.name.toLowerCase()}')" value="${tab.name.toLowerCase()}" prepend-icon="${icon}" @mousedown="spawnDatatableWindow($event, '${pageName}', '${tab.name}')">{{ game.i18n.localize('${label}') }}</v-tab>
890
+ return expandToNode `
891
+ <v-tab v-if="!isHidden('${tab.name.toLowerCase()}')" value="${tab.name.toLowerCase()}" prepend-icon="${icon}" @mousedown="spawnDatatableWindow($event, '${pageName}', '${tab.name}')">{{ game.i18n.localize('${label}') }}</v-tab>
892
892
  `;
893
893
  }
894
894
  function generateNavListItem(page) {
895
895
  var _a, _b;
896
896
  const pageIconParam = (_a = page.params) === null || _a === void 0 ? void 0 : _a.find(p => isIconParam(p));
897
897
  const icon = (_b = pageIconParam === null || pageIconParam === void 0 ? void 0 : pageIconParam.value) !== null && _b !== void 0 ? _b : "fa-solid fa-page";
898
- return expandToNode `
899
- <v-tab value="${page.name.toLowerCase()}" prepend-icon="${icon}">{{ game.i18n.localize('${page.name}') }}</v-tab>
898
+ return expandToNode `
899
+ <v-tab value="${page.name.toLowerCase()}" prepend-icon="${icon}">{{ game.i18n.localize('${page.name}') }}</v-tab>
900
900
  `;
901
901
  }
902
902
  function generatePageBody(page) {
903
903
  const tables = page.body.filter(isTableField); // We explictly only want top-level tables
904
904
  const pinned = page.body.filter(isPinnedField); // We explictly only want top-level pinned fields
905
905
  const inventories = page.body.filter(isInventoryField); // We explictly only want top-level inventories
906
- return expandToNode `
907
- <v-tabs-window-item value="${page.name.toLowerCase()}" data-tab="${page.name.toLowerCase()}">
908
- <v-row dense>
909
- ${joinToNode(page.body, element => generateElement(element, true), { appendNewLineIfNotEmpty: true })}
910
- </v-row>
911
- <v-divider class="mt-4 mb-2"></v-divider>
912
- <v-tabs v-model="tab" grow always-center>
913
- ${joinToNode(tables, table => generateSubTab(table), { appendNewLineIfNotEmpty: true })}
914
- ${joinToNode(pinned, pinnedField => generatePinnedTab(pinnedField), { appendNewLineIfNotEmpty: true })}
915
- ${joinToNode(inventories, inventory => generateSubTab(inventory), { appendNewLineIfNotEmpty: true })}
916
- </v-tabs>
917
- <v-tabs-window v-model="tab" class="tabs-window">
918
- ${joinToNode(tables, table => generateVuetifyDatatable(page.name, table), { appendNewLineIfNotEmpty: true })}
919
- ${joinToNode(pinned, pinnedField => generatePinnedTabWindow(pinnedField), { appendNewLineIfNotEmpty: true })}
920
- ${joinToNode(inventories, inventory => generateInventoryTabWindow(page.name, inventory), { appendNewLineIfNotEmpty: true })}
921
- </v-tabs-window>
922
- </v-tabs-window-item>
906
+ return expandToNode `
907
+ <v-tabs-window-item value="${page.name.toLowerCase()}" data-tab="${page.name.toLowerCase()}">
908
+ <v-row dense>
909
+ ${joinToNode(page.body, element => generateElement(element, true), { appendNewLineIfNotEmpty: true })}
910
+ </v-row>
911
+ <v-divider class="mt-4 mb-2"></v-divider>
912
+ <v-tabs v-model="tab" grow always-center>
913
+ ${joinToNode(tables, table => generateSubTab(table), { appendNewLineIfNotEmpty: true })}
914
+ ${joinToNode(pinned, pinnedField => generatePinnedTab(pinnedField), { appendNewLineIfNotEmpty: true })}
915
+ ${joinToNode(inventories, inventory => generateSubTab(inventory), { appendNewLineIfNotEmpty: true })}
916
+ </v-tabs>
917
+ <v-tabs-window v-model="tab" class="tabs-window">
918
+ ${joinToNode(tables, table => generateVuetifyDatatable(page.name, table), { appendNewLineIfNotEmpty: true })}
919
+ ${joinToNode(pinned, pinnedField => generatePinnedTabWindow(pinnedField), { appendNewLineIfNotEmpty: true })}
920
+ ${joinToNode(inventories, inventory => generateInventoryTabWindow(page.name, inventory), { appendNewLineIfNotEmpty: true })}
921
+ </v-tabs-window>
922
+ </v-tabs-window-item>
923
923
  `;
924
924
  }
925
925
  function generateVuetifyDatatable(pageName, element) {
926
926
  const systemPath = getSystemPath(element, [], undefined, false);
927
927
  let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
928
- return expandToNode `
929
- <v-tabs-window-item v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="table" class="tabs-container">
930
- <${componentName} systemPath="${systemPath}" :context="context" :primaryColor="primaryColor" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"></${componentName}>
931
- </v-tabs-window-item>
928
+ return expandToNode `
929
+ <v-tabs-window-item v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="table" class="tabs-container">
930
+ <${componentName} systemPath="${systemPath}" :context="context" :primaryColor="primaryColor" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"></${componentName}>
931
+ </v-tabs-window-item>
932
932
  `.appendNewLine();
933
933
  }
934
934
  function generateInventoryTabWindow(pageName, element) {
@@ -1014,35 +1014,35 @@ function generateVueComponentTemplate(entry, id, document) {
1014
1014
  const whereNode = translateExpression(entry, id, whereParam.value);
1015
1015
  whereExpression = whereNode ? toString(whereNode) : undefined;
1016
1016
  }
1017
- return expandToNode `
1018
- <v-tabs-window-item v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="inventory" class="tabs-container">
1019
- <i-inventory
1020
- label="${label}"
1021
- systemPath="${systemPath}"
1022
- :context="context"
1023
- :editMode="editModeRef"
1024
- ${icon ? `icon="${icon}"` : ''}
1025
- ${slots ? `:maxSlots="${slots}"` : ''}
1026
- ${rows ? `:rows="${rows}"` : ''}
1027
- :slotSize="${slotSize}"
1028
- documentType="${documentType}"
1029
- ${whereExpression ? `whereExpression="${whereExpression}"` : ''}
1030
- ${globalAllowed ? ':globalAllowed="true"' : ''}
1031
- ${quantityField ? `quantityField="${quantityField}"` : ''}
1032
- ${moneyField ? `moneyField="${moneyField}"` : ''}
1033
- ${moneyFieldLabel ? `moneyFieldLabel="${moneyFieldLabel}"` : ''}
1034
- ${moneyFieldIcon ? `moneyFieldIcon="${moneyFieldIcon}"` : ''}
1035
- ${sumProperties.length > 0 ? `:sumProperties='${JSON.stringify(sumProperties)}'` : ''}
1036
- ${sumMax ? `:sumMax="${sumMax}"` : ''}
1037
- ${sortProperty ? `sortProperty="${sortProperty}"` : ''}
1038
- sortOrder="${sortOrder}"
1039
- emptySlots="${emptySlots}"
1040
- summary="${summary}"
1041
- :primaryColor="primaryColor"
1042
- :secondaryColor="secondaryColor"
1043
- :tertiaryColor="tertiaryColor"
1044
- />
1045
- </v-tabs-window-item>
1017
+ return expandToNode `
1018
+ <v-tabs-window-item v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="inventory" class="tabs-container">
1019
+ <i-inventory
1020
+ label="${label}"
1021
+ systemPath="${systemPath}"
1022
+ :context="context"
1023
+ :editMode="editModeRef"
1024
+ ${icon ? `icon="${icon}"` : ''}
1025
+ ${slots ? `:maxSlots="${slots}"` : ''}
1026
+ ${rows ? `:rows="${rows}"` : ''}
1027
+ :slotSize="${slotSize}"
1028
+ documentType="${documentType}"
1029
+ ${whereExpression ? `whereExpression="${whereExpression}"` : ''}
1030
+ ${globalAllowed ? ':globalAllowed="true"' : ''}
1031
+ ${quantityField ? `quantityField="${quantityField}"` : ''}
1032
+ ${moneyField ? `moneyField="${moneyField}"` : ''}
1033
+ ${moneyFieldLabel ? `moneyFieldLabel="${moneyFieldLabel}"` : ''}
1034
+ ${moneyFieldIcon ? `moneyFieldIcon="${moneyFieldIcon}"` : ''}
1035
+ ${sumProperties.length > 0 ? `:sumProperties='${JSON.stringify(sumProperties)}'` : ''}
1036
+ ${sumMax ? `:sumMax="${sumMax}"` : ''}
1037
+ ${sortProperty ? `sortProperty="${sortProperty}"` : ''}
1038
+ sortOrder="${sortOrder}"
1039
+ emptySlots="${emptySlots}"
1040
+ summary="${summary}"
1041
+ :primaryColor="primaryColor"
1042
+ :secondaryColor="secondaryColor"
1043
+ :tertiaryColor="tertiaryColor"
1044
+ />
1045
+ </v-tabs-window-item>
1046
1046
  `.appendNewLine();
1047
1047
  }
1048
1048
  function generatePinnedTab(element) {
@@ -1051,54 +1051,54 @@ function generateVueComponentTemplate(entry, id, document) {
1051
1051
  const labelParam = element.params.find(p => isLabelParam(p));
1052
1052
  const icon = (_a = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value) !== null && _a !== void 0 ? _a : "fa-solid fa-thumbtack";
1053
1053
  const label = (_b = labelParam === null || labelParam === void 0 ? void 0 : labelParam.value) !== null && _b !== void 0 ? _b : `${document.name}.${element.name}`;
1054
- return expandToNode `
1055
- <v-tab v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" prepend-icon="${icon}" @mousedown="spawnDatatableWindow($event, '${document.name}', '${element.name}')">{{ game.i18n.localize("${label}") }}</v-tab>
1054
+ return expandToNode `
1055
+ <v-tab v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" prepend-icon="${icon}" @mousedown="spawnDatatableWindow($event, '${document.name}', '${element.name}')">{{ game.i18n.localize("${label}") }}</v-tab>
1056
1056
  `.appendNewLine();
1057
1057
  }
1058
1058
  function generatePinnedTabWindow(element) {
1059
1059
  const page = AstUtils.getContainerOfType(element, isPage);
1060
1060
  const pageName = page ? page.name : document.name;
1061
1061
  let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
1062
- return expandToNode `
1063
- <v-tabs-window-item v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="pinned" class="tabs-container">
1064
- <${componentName}
1065
- :context="context"
1066
- :primaryColor="primaryColor"
1067
- :secondaryColor="secondaryColor"
1068
- :tertiaryColor="tertiaryColor"
1069
- />
1070
- </v-tabs-window-item>
1062
+ return expandToNode `
1063
+ <v-tabs-window-item v-if="!isHidden('${element.name.toLowerCase()}')" value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="pinned" class="tabs-container">
1064
+ <${componentName}
1065
+ :context="context"
1066
+ :primaryColor="primaryColor"
1067
+ :secondaryColor="secondaryColor"
1068
+ :tertiaryColor="tertiaryColor"
1069
+ />
1070
+ </v-tabs-window-item>
1071
1071
  `.appendNewLine();
1072
1072
  }
1073
1073
  function generateElement(element, isTopLevel = false) {
1074
1074
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
1075
1075
  if (isSection(element)) {
1076
- return expandToNode `
1077
- <v-col class="section">
1078
- <v-card variant="outlined" elevation="4">
1079
- <v-card-title>{{ game.i18n.localize('${document.name}.${element.name}') }}</v-card-title>
1080
-
1081
- <v-card-text>
1082
- <v-row dense>
1083
- ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1084
- </v-row>
1085
- </v-card-text>
1086
- </v-card>
1087
- </v-col>
1076
+ return expandToNode `
1077
+ <v-col class="section">
1078
+ <v-card variant="outlined" elevation="4">
1079
+ <v-card-title>{{ game.i18n.localize('${document.name}.${element.name}') }}</v-card-title>
1080
+
1081
+ <v-card-text>
1082
+ <v-row dense>
1083
+ ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1084
+ </v-row>
1085
+ </v-card-text>
1086
+ </v-card>
1087
+ </v-col>
1088
1088
  `;
1089
1089
  }
1090
1090
  if (isRow(element)) {
1091
- return expandToNode `
1092
- <v-row dense>
1093
- ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1094
- </v-row>
1091
+ return expandToNode `
1092
+ <v-row dense>
1093
+ ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1094
+ </v-row>
1095
1095
  `;
1096
1096
  }
1097
1097
  if (isColumn(element)) {
1098
- return expandToNode `
1099
- <v-col>
1100
- ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1101
- </v-col>
1098
+ return expandToNode `
1099
+ <v-col>
1100
+ ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1101
+ </v-col>
1102
1102
  `;
1103
1103
  }
1104
1104
  // We don't render these elements as part of this function
@@ -1109,13 +1109,13 @@ function generateVueComponentTemplate(entry, id, document) {
1109
1109
  const componentName = `${document.name.toLowerCase()}${element.name}Action`;
1110
1110
  const colorParam = element.params.find(x => isColorParam(x));
1111
1111
  const primaryColor = colorParam ? `'${colorParam.value}'` : "primaryColor";
1112
- return expandToNode `
1113
- <${componentName}
1114
- :context="context"
1115
- :color="${primaryColor}"
1116
- :editMode="editModeRef"
1117
- :visibility="visibilityStates['${element.name.toLowerCase()}'].value">
1118
- </${componentName}>
1112
+ return expandToNode `
1113
+ <${componentName}
1114
+ :context="context"
1115
+ :color="${primaryColor}"
1116
+ :editMode="editModeRef"
1117
+ :visibility="visibilityStates['${element.name.toLowerCase()}'].value">
1118
+ </${componentName}>
1119
1119
  `;
1120
1120
  }
1121
1121
  if (!isProperty(element))
@@ -1123,11 +1123,6 @@ function generateVueComponentTemplate(entry, id, document) {
1123
1123
  if (isProperty(element)) {
1124
1124
  if (element.modifier == "hidden")
1125
1125
  return expandToNode ``;
1126
- if (element.name == "RollVisualizer") {
1127
- return expandToNode `
1128
- <i-roll-visualizer :context="context"></i-roll-visualizer>
1129
- `;
1130
- }
1131
1126
  const standardParams = element.params;
1132
1127
  const iconParam = standardParams.find(p => isIconParam(p));
1133
1128
  const colorParam = standardParams.find(p => isColorParam(p));
@@ -1135,6 +1130,21 @@ function generateVueComponentTemplate(entry, id, document) {
1135
1130
  const standardParamsFragment = colorParam ? `:disabled="isDisabled('${element.name.toLowerCase()}')" v-if="!isHidden('${element.name.toLowerCase()}')" color="${colorParam.value}"` : `:disabled="isDisabled('${element.name.toLowerCase()}')" v-if="!isHidden('${element.name.toLowerCase()}')"`;
1136
1131
  const systemPath = getSystemPath(element, [], undefined, false);
1137
1132
  const entry = AstUtils.getContainerOfType(element, isEntry);
1133
+ if (isRollVisualizerField(element)) {
1134
+ const { formula, data } = compileVisualizerFormula(entry, id, element);
1135
+ return expandToNode `
1136
+ <i-roll-visualizer
1137
+ :context="context"
1138
+ label="${label}"
1139
+ ${iconParam ? `icon="${iconParam.value}"` : ``}
1140
+ ${colorParam ? `color="${colorParam.value}"` : ``}
1141
+ systemPath="${systemPath}"
1142
+ :formula='${formula}'
1143
+ :rollData='${data}'
1144
+ v-if="!isHidden('${element.name.toLowerCase()}')">
1145
+ </i-roll-visualizer>
1146
+ `;
1147
+ }
1138
1148
  if (isParentPropertyRefExp(element)) {
1139
1149
  const choicesParam = element.params.find(p => isParentPropertyRefChoiceParam(p));
1140
1150
  let allChoices = [];
@@ -1207,15 +1217,15 @@ function generateVueComponentTemplate(entry, id, document) {
1207
1217
  });
1208
1218
  refChoices = refChoices.filter(x => x != undefined);
1209
1219
  const choices = refChoices.map(c => `{ label: '${c === null || c === void 0 ? void 0 : c.parent} - ${c === null || c === void 0 ? void 0 : c.name}', value: '${c === null || c === void 0 ? void 0 : c.path}' }`).join(", ");
1210
- return expandToNode `
1211
- <i-parent-property-reference
1212
- :context="context"
1213
- label="${label}"
1214
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1215
- systemPath="${systemPath}"
1216
- :refChoices="[${choices}]"
1217
- ${standardParamsFragment}>
1218
- </i-parent-property-reference>
1220
+ return expandToNode `
1221
+ <i-parent-property-reference
1222
+ :context="context"
1223
+ label="${label}"
1224
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1225
+ systemPath="${systemPath}"
1226
+ :refChoices="[${choices}]"
1227
+ ${standardParamsFragment}>
1228
+ </i-parent-property-reference>
1219
1229
  `;
1220
1230
  }
1221
1231
  if (isSelfPropertyRefExp(element)) {
@@ -1224,8 +1234,8 @@ function generateVueComponentTemplate(entry, id, document) {
1224
1234
  // Get the current document
1225
1235
  const currentDocument = getDocument(element);
1226
1236
  if (!currentDocument) {
1227
- return expandToNode `
1228
- <div class="error">Self property reference error: Cannot find current document</div>
1237
+ return expandToNode `
1238
+ <div class="error">Self property reference error: Cannot find current document</div>
1229
1239
  `;
1230
1240
  }
1231
1241
  switch (element.propertyType) {
@@ -1284,42 +1294,42 @@ function generateVueComponentTemplate(entry, id, document) {
1284
1294
  refChoices = refChoices.filter(x => allowedProperties.includes(x.name.toLowerCase()));
1285
1295
  }
1286
1296
  const choices = refChoices.map(c => `{ title: '${c.name}', value: '${c.path}' }`).join(", ");
1287
- return expandToNode `
1288
- <i-self-property-reference
1289
- :context="context"
1290
- label="${label}"
1291
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1292
- systemPath="${systemPath}"
1293
- propertyType="${element.propertyType}"
1294
- :choices="[${choices}]"
1295
- ${standardParamsFragment}>
1296
- </i-self-property-reference>
1297
+ return expandToNode `
1298
+ <i-self-property-reference
1299
+ :context="context"
1300
+ label="${label}"
1301
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1302
+ systemPath="${systemPath}"
1303
+ propertyType="${element.propertyType}"
1304
+ :choices="[${choices}]"
1305
+ ${standardParamsFragment}>
1306
+ </i-self-property-reference>
1297
1307
  `;
1298
1308
  }
1299
1309
  if (isStringExp(element)) {
1300
1310
  const valueParam = element.params.find(p => isStringParamValue(p));
1301
1311
  if (valueParam !== undefined) {
1302
- return expandToNode `
1303
- <i-string
1304
- :context="context"
1305
- label="${label}"
1306
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1307
- systemPath="${systemPath}"
1308
- ${standardParamsFragment}>
1309
- </i-string>
1312
+ return expandToNode `
1313
+ <i-string
1314
+ :context="context"
1315
+ label="${label}"
1316
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1317
+ systemPath="${systemPath}"
1318
+ ${standardParamsFragment}>
1319
+ </i-string>
1310
1320
  `;
1311
1321
  }
1312
- return expandToNode `
1313
- <i-text-field
1314
- label="${label}"
1315
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1316
- systemPath="${systemPath}"
1317
- ${standardParamsFragment}
1318
- :context="context"
1319
- :editMode="editModeRef"
1320
- :primaryColor="primaryColor"
1321
- :secondaryColor="secondaryColor">
1322
- </i-text-field>
1322
+ return expandToNode `
1323
+ <i-text-field
1324
+ label="${label}"
1325
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1326
+ systemPath="${systemPath}"
1327
+ ${standardParamsFragment}
1328
+ :context="context"
1329
+ :editMode="editModeRef"
1330
+ :primaryColor="primaryColor"
1331
+ :secondaryColor="secondaryColor">
1332
+ </i-text-field>
1323
1333
  `;
1324
1334
  }
1325
1335
  if (isStringChoiceField(element)) {
@@ -1360,18 +1370,18 @@ function generateVueComponentTemplate(entry, id, document) {
1360
1370
  }
1361
1371
  return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_c = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _c !== void 0 ? _c : ""}', color: '${(_d = color === null || color === void 0 ? void 0 : color.value) !== null && _d !== void 0 ? _d : ""}' }`;
1362
1372
  }
1363
- return expandToNode `
1364
- <i-string-choice
1365
- :context="context"
1366
- label="${label}.label"
1367
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1368
- systemPath="${systemPath}"
1369
- :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1370
- :isExtended="true"
1371
- :primaryColor="primaryColor"
1372
- :secondaryColor="secondaryColor"
1373
- ${standardParamsFragment}>
1374
- </i-string-choice>
1373
+ return expandToNode `
1374
+ <i-string-choice
1375
+ :context="context"
1376
+ label="${label}.label"
1377
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1378
+ systemPath="${systemPath}"
1379
+ :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1380
+ :isExtended="true"
1381
+ :primaryColor="primaryColor"
1382
+ :secondaryColor="secondaryColor"
1383
+ ${standardParamsFragment}>
1384
+ </i-string-choice>
1375
1385
  `;
1376
1386
  }
1377
1387
  if (isDamageTypeChoiceField(element)) {
@@ -1418,18 +1428,18 @@ function generateVueComponentTemplate(entry, id, document) {
1418
1428
  }
1419
1429
  return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_c = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _c !== void 0 ? _c : ""}', color: '${(_d = color === null || color === void 0 ? void 0 : color.value) !== null && _d !== void 0 ? _d : ""}' }`;
1420
1430
  }
1421
- return expandToNode `
1422
- <i-string-choice
1423
- :context="context"
1424
- label="${label}.label"
1425
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1426
- systemPath="${systemPath}"
1427
- :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1428
- :isExtended="true"
1429
- :primaryColor="primaryColor"
1430
- :secondaryColor="secondaryColor"
1431
- ${standardParamsFragment}>
1432
- </i-string-choice>
1431
+ return expandToNode `
1432
+ <i-string-choice
1433
+ :context="context"
1434
+ label="${label}.label"
1435
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1436
+ systemPath="${systemPath}"
1437
+ :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1438
+ :isExtended="true"
1439
+ :primaryColor="primaryColor"
1440
+ :secondaryColor="secondaryColor"
1441
+ ${standardParamsFragment}>
1442
+ </i-string-choice>
1433
1443
  `;
1434
1444
  }
1435
1445
  if (isStringChoicesField(element)) {
@@ -1473,106 +1483,106 @@ function generateVueComponentTemplate(entry, id, document) {
1473
1483
  // Get maxSelections parameter
1474
1484
  const maxParam = element.params.find(p => p.$type === 'StringChoicesParamMax');
1475
1485
  const maxSelections = maxParam ? maxParam.value : undefined;
1476
- return expandToNode `
1477
- <i-string-choices
1478
- :context="context"
1479
- label="${label}.label"
1480
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1481
- systemPath="${systemPath}"
1482
- :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1483
- :isExtended="true"
1484
- ${maxSelections ? `:maxSelections="${maxSelections}"` : ''}
1485
- :primaryColor="primaryColor"
1486
- :secondaryColor="secondaryColor"
1487
- ${standardParamsFragment}>
1488
- </i-string-choices>
1486
+ return expandToNode `
1487
+ <i-string-choices
1488
+ :context="context"
1489
+ label="${label}.label"
1490
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1491
+ systemPath="${systemPath}"
1492
+ :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1493
+ :isExtended="true"
1494
+ ${maxSelections ? `:maxSelections="${maxSelections}"` : ''}
1495
+ :primaryColor="primaryColor"
1496
+ :secondaryColor="secondaryColor"
1497
+ ${standardParamsFragment}>
1498
+ </i-string-choices>
1489
1499
  `;
1490
1500
  }
1491
1501
  if (isDocumentChoiceExp(element)) {
1492
1502
  const componentName = `${document.name.toLowerCase()}${element.name}DocumentChoice`;
1493
- return expandToNode `
1494
- <${componentName}
1495
- label="${label}"
1496
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1497
- :context="context"
1498
- :editMode="editModeRef"
1499
- ${standardParamsFragment}
1500
- :primaryColor="primaryColor"
1501
- :secondaryColor="secondaryColor">
1502
- </${componentName}>
1503
+ return expandToNode `
1504
+ <${componentName}
1505
+ label="${label}"
1506
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1507
+ :context="context"
1508
+ :editMode="editModeRef"
1509
+ ${standardParamsFragment}
1510
+ :primaryColor="primaryColor"
1511
+ :secondaryColor="secondaryColor">
1512
+ </${componentName}>
1503
1513
  `;
1504
1514
  }
1505
1515
  if (isDocumentChoicesExp(element)) {
1506
1516
  const componentName = `${document.name.toLowerCase()}${element.name}DocumentChoices`;
1507
- return expandToNode `
1508
- <${componentName}
1509
- label="${label}"
1510
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1511
- :context="context"
1512
- :editMode="editModeRef"
1513
- ${standardParamsFragment}
1514
- :primaryColor="primaryColor"
1515
- :secondaryColor="secondaryColor">
1516
- </${componentName}>
1517
+ return expandToNode `
1518
+ <${componentName}
1519
+ label="${label}"
1520
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1521
+ :context="context"
1522
+ :editMode="editModeRef"
1523
+ ${standardParamsFragment}
1524
+ :primaryColor="primaryColor"
1525
+ :secondaryColor="secondaryColor">
1526
+ </${componentName}>
1517
1527
  `;
1518
1528
  }
1519
1529
  if (isMacroField(element)) {
1520
- return expandToNode `
1521
- <i-macro
1522
- label="${label}"
1523
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1524
- systemPath="${systemPath}"
1525
- ${standardParamsFragment}
1526
- :context="context"
1527
- :editMode="editModeRef"
1528
- :primaryColor="primaryColor"
1529
- :secondaryColor="secondaryColor">
1530
- </i-macro>
1530
+ return expandToNode `
1531
+ <i-macro
1532
+ label="${label}"
1533
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1534
+ systemPath="${systemPath}"
1535
+ ${standardParamsFragment}
1536
+ :context="context"
1537
+ :editMode="editModeRef"
1538
+ :primaryColor="primaryColor"
1539
+ :secondaryColor="secondaryColor">
1540
+ </i-macro>
1531
1541
  `;
1532
1542
  }
1533
1543
  if (isHtmlExp(element)) {
1534
- return expandToNode `
1535
- <i-prosemirror
1536
- label="${label}"
1537
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1538
- :field="context.editors['${systemPath}']"
1539
- ${standardParamsFragment}>
1540
- </i-prosemirror>
1544
+ return expandToNode `
1545
+ <i-prosemirror
1546
+ label="${label}"
1547
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1548
+ :field="context.editors['${systemPath}']"
1549
+ ${standardParamsFragment}>
1550
+ </i-prosemirror>
1541
1551
  `;
1542
1552
  }
1543
1553
  if (isMeasuredTemplateField(element)) {
1544
- return expandToNode `
1545
- <i-measured-template
1546
- :context="context"
1547
- label="${label}"
1548
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1549
- systemPath="${systemPath}"
1550
- :primaryColor="primaryColor"
1551
- :secondaryColor="secondaryColor"
1552
- ${standardParamsFragment}>
1553
- </i-measured-template>
1554
+ return expandToNode `
1555
+ <i-measured-template
1556
+ :context="context"
1557
+ label="${label}"
1558
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1559
+ systemPath="${systemPath}"
1560
+ :primaryColor="primaryColor"
1561
+ :secondaryColor="secondaryColor"
1562
+ ${standardParamsFragment}>
1563
+ </i-measured-template>
1554
1564
  `;
1555
1565
  }
1556
1566
  if (isDamageBonusesField(element)) {
1557
- return expandToNode `
1558
- <i-bonuses
1559
- :context="context"
1560
- label="${label}"
1561
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1562
- systemPath="${systemPath}"
1563
- ${standardParamsFragment}>
1564
- </i-bonuses>
1567
+ return expandToNode `
1568
+ <i-bonuses
1569
+ :context="context"
1570
+ label="${label}"
1571
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1572
+ systemPath="${systemPath}"
1573
+ ${standardParamsFragment}>
1574
+ </i-bonuses>
1565
1575
  `;
1566
1576
  }
1567
1577
  if (isDamageResistancesField(element)) {
1568
- return expandToNode `
1569
- <i-resistances
1570
- :context="context"
1571
- label="${label}"
1572
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1573
- systemPath="${systemPath}"
1574
- ${standardParamsFragment}>
1575
- </i-resistances>
1578
+ return expandToNode `
1579
+ <i-resistances
1580
+ :context="context"
1581
+ label="${label}"
1582
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1583
+ systemPath="${systemPath}"
1584
+ ${standardParamsFragment}>
1585
+ </i-resistances>
1576
1586
  `;
1577
1587
  }
1578
1588
  if (isPinnedField(element)) {
@@ -1584,27 +1594,27 @@ function generateVueComponentTemplate(entry, id, document) {
1584
1594
  let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
1585
1595
  // Wrap in a drop zone so drag-drop works for pinned tables inside a
1586
1596
  // row/column (same reason as regular tables above).
1587
- return expandToNode `
1588
- <div class="datatable-drop-zone" v-if="!isHidden('${element.name.toLowerCase()}')">
1589
- <${componentName}
1590
- :context="context"
1591
- label="${label}"
1592
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1593
- systemPath="${systemPath}"
1594
- :primaryColor="primaryColor" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor">
1595
- </${componentName}>
1596
- </div>
1597
+ return expandToNode `
1598
+ <div class="datatable-drop-zone" v-if="!isHidden('${element.name.toLowerCase()}')">
1599
+ <${componentName}
1600
+ :context="context"
1601
+ label="${label}"
1602
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1603
+ systemPath="${systemPath}"
1604
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor">
1605
+ </${componentName}>
1606
+ </div>
1597
1607
  `;
1598
1608
  }
1599
1609
  if (isBooleanExp(element)) {
1600
- return expandToNode `
1601
- <i-boolean
1602
- :context="context"
1603
- label="${label}"
1604
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1605
- systemPath="${systemPath}"
1606
- ${standardParamsFragment}>
1607
- </i-boolean>
1610
+ return expandToNode `
1611
+ <i-boolean
1612
+ :context="context"
1613
+ label="${label}"
1614
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1615
+ systemPath="${systemPath}"
1616
+ ${standardParamsFragment}>
1617
+ </i-boolean>
1608
1618
  `;
1609
1619
  }
1610
1620
  if (isNumberExp(element)) {
@@ -1622,21 +1632,21 @@ function generateVueComponentTemplate(entry, id, document) {
1622
1632
  if (maxParam && typeof maxParam.value === 'number') {
1623
1633
  maxValue = maxParam.value;
1624
1634
  }
1625
- return expandToNode `
1626
- <i-number
1627
- :context="context"
1628
- label="${label}"
1629
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1630
- systemPath="${systemPath}"
1631
- :hasValueParam="${valueParam != undefined}"
1632
- :editMode="editModeRef"
1633
- :primaryColor="primaryColor"
1634
- :secondaryColor="secondaryColor"
1635
- ${minValue !== undefined ? `:min="${minValue}"` : ''}
1636
- ${maxValue !== undefined ? `:max="${maxValue}"` : ''}
1637
- ${calculatorParam !== undefined ? `:calculator="${calculatorParam.value}"` : ''}
1638
- ${standardParamsFragment}>
1639
- </i-number>
1635
+ return expandToNode `
1636
+ <i-number
1637
+ :context="context"
1638
+ label="${label}"
1639
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1640
+ systemPath="${systemPath}"
1641
+ :hasValueParam="${valueParam != undefined}"
1642
+ :editMode="editModeRef"
1643
+ :primaryColor="primaryColor"
1644
+ :secondaryColor="secondaryColor"
1645
+ ${minValue !== undefined ? `:min="${minValue}"` : ''}
1646
+ ${maxValue !== undefined ? `:max="${maxValue}"` : ''}
1647
+ ${calculatorParam !== undefined ? `:calculator="${calculatorParam.value}"` : ''}
1648
+ ${standardParamsFragment}>
1649
+ </i-number>
1640
1650
  `;
1641
1651
  }
1642
1652
  if (isMoneyField(element)) {
@@ -1658,22 +1668,22 @@ function generateVueComponentTemplate(entry, id, document) {
1658
1668
  }).join(', ');
1659
1669
  denominationsArray = `[${denominations}]`;
1660
1670
  }
1661
- return expandToNode `
1662
- <i-money
1663
- :context="context"
1664
- label="${label}"
1665
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1666
- systemPath="${systemPath}"
1667
- format="${format}"
1668
- :precision="${precision}"
1669
- display="${display}"
1670
- :denominations="${denominationsArray}"
1671
- :hasValueParam="${valueParam != undefined}"
1672
- :editMode="editModeRef"
1673
- :primaryColor="primaryColor"
1674
- :secondaryColor="secondaryColor"
1675
- ${standardParamsFragment}>
1676
- </i-money>
1671
+ return expandToNode `
1672
+ <i-money
1673
+ :context="context"
1674
+ label="${label}"
1675
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1676
+ systemPath="${systemPath}"
1677
+ format="${format}"
1678
+ :precision="${precision}"
1679
+ display="${display}"
1680
+ :denominations="${denominationsArray}"
1681
+ :hasValueParam="${valueParam != undefined}"
1682
+ :editMode="editModeRef"
1683
+ :primaryColor="primaryColor"
1684
+ :secondaryColor="secondaryColor"
1685
+ ${standardParamsFragment}>
1686
+ </i-money>
1677
1687
  `;
1678
1688
  }
1679
1689
  if (isAttributeExp(element)) {
@@ -1694,25 +1704,25 @@ function generateVueComponentTemplate(entry, id, document) {
1694
1704
  // roll: keeps the die icon; function: shows the attribute's own icon (or a generic
1695
1705
  // action bolt) so the overlay reflects what the click actually triggers.
1696
1706
  const clickIcon = functionParam ? ((_h = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value) !== null && _h !== void 0 ? _h : "fa-solid fa-bolt") : "fa-solid fa-dice";
1697
- return expandToNode `
1698
- <i-attribute
1699
- label="${label}"
1700
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1701
- attributeStyle="${style}"
1702
- :editMode="editModeRef"
1703
- :hasMod="${hasMod}"
1704
- :mod="context.${modSystemPath}"
1705
- systemPath="${valueSystemPath}"
1706
- :context="context"
1707
- :min="${min}"
1708
- ${standardParamsFragment}
1709
- :primaryColor="primaryColor"
1710
- :secondaryColor="secondaryColor"
1711
- :roll="${clickHandler}"
1712
- :hasRoll="${rollParam != undefined || functionParam != undefined}"
1713
- clickIcon="${clickIcon}"
1714
- >
1715
- </i-attribute>
1707
+ return expandToNode `
1708
+ <i-attribute
1709
+ label="${label}"
1710
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1711
+ attributeStyle="${style}"
1712
+ :editMode="editModeRef"
1713
+ :hasMod="${hasMod}"
1714
+ :mod="context.${modSystemPath}"
1715
+ systemPath="${valueSystemPath}"
1716
+ :context="context"
1717
+ :min="${min}"
1718
+ ${standardParamsFragment}
1719
+ :primaryColor="primaryColor"
1720
+ :secondaryColor="secondaryColor"
1721
+ :roll="${clickHandler}"
1722
+ :hasRoll="${rollParam != undefined || functionParam != undefined}"
1723
+ clickIcon="${clickIcon}"
1724
+ >
1725
+ </i-attribute>
1716
1726
  `;
1717
1727
  }
1718
1728
  // if () {
@@ -1735,17 +1745,17 @@ function generateVueComponentTemplate(entry, id, document) {
1735
1745
  const max = (_k = maxParam === null || maxParam === void 0 ? void 0 : maxParam.value) !== null && _k !== void 0 ? _k : 5;
1736
1746
  const colorParam = element.params.find(x => isColorParam(x));
1737
1747
  const primaryColor = colorParam ? `'${colorParam.value}'` : "primaryColor";
1738
- return expandToNode `
1739
- <i-damage-track
1740
- label="${label}"
1741
- systemPath="system.${element.name.toLowerCase()}"
1742
- :context="context"
1743
- :editMode="editModeRef"
1744
- :primaryColor="${primaryColor}"
1745
- :secondaryColor="secondaryColor"
1746
- :types="[${types.map(t => `'${t}'`).join(', ')}]"
1747
- :max="${max}"
1748
- ></i-damage-track>
1748
+ return expandToNode `
1749
+ <i-damage-track
1750
+ label="${label}"
1751
+ systemPath="system.${element.name.toLowerCase()}"
1752
+ :context="context"
1753
+ :editMode="editModeRef"
1754
+ :primaryColor="${primaryColor}"
1755
+ :secondaryColor="secondaryColor"
1756
+ :types="[${types.map(t => `'${t}'`).join(', ')}]"
1757
+ :max="${max}"
1758
+ ></i-damage-track>
1749
1759
  `;
1750
1760
  }
1751
1761
  if (isTrackerExp(element) || isResourceExp(element)) {
@@ -1771,75 +1781,75 @@ function generateVueComponentTemplate(entry, id, document) {
1771
1781
  isHealth = element.tag == "health";
1772
1782
  isWounds = element.tag == "wounds";
1773
1783
  }
1774
- return expandToNode `
1775
- <i-tracker
1776
- label="${label}"
1777
- systemPath="system.${element.name.toLowerCase()}" :context="context"
1778
- :visibility="visibilityStates['${element.name.toLowerCase()}'].value"
1779
- :editMode="editModeRef"
1780
- :primaryColor="${primaryColor}" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"
1781
- trackerStyle="${style}"
1782
- icon="${icon}"
1783
- :hideMin="${hideMin}"
1784
- :disableMin="${disableMin}"
1785
- :disableValue="${disableValue}"
1786
- :disableMax="${disableMax}"
1787
- :segments="${segments}"
1788
- :isHealth="${isHealth}"
1789
- :isWounds="${isWounds}"
1790
- ></i-tracker>
1784
+ return expandToNode `
1785
+ <i-tracker
1786
+ label="${label}"
1787
+ systemPath="system.${element.name.toLowerCase()}" :context="context"
1788
+ :visibility="visibilityStates['${element.name.toLowerCase()}'].value"
1789
+ :editMode="editModeRef"
1790
+ :primaryColor="${primaryColor}" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"
1791
+ trackerStyle="${style}"
1792
+ icon="${icon}"
1793
+ :hideMin="${hideMin}"
1794
+ :disableMin="${disableMin}"
1795
+ :disableValue="${disableValue}"
1796
+ :disableMax="${disableMax}"
1797
+ :segments="${segments}"
1798
+ :isHealth="${isHealth}"
1799
+ :isWounds="${isWounds}"
1800
+ ></i-tracker>
1791
1801
  `;
1792
1802
  }
1793
1803
  if (isSingleDocumentExp(element)) {
1794
- return expandToNode `
1795
- <i-document-link
1796
- label="${label}"
1797
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1798
- systemPath="system.${element.name.toLowerCase()}"
1799
- documentName="${(_p = element.document.ref) === null || _p === void 0 ? void 0 : _p.name.toLowerCase()}"
1800
- :context="context"
1801
- ${standardParamsFragment}
1802
- :secondaryColor="secondaryColor">
1803
- </i-document-link>
1804
+ return expandToNode `
1805
+ <i-document-link
1806
+ label="${label}"
1807
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1808
+ systemPath="system.${element.name.toLowerCase()}"
1809
+ documentName="${(_p = element.document.ref) === null || _p === void 0 ? void 0 : _p.name.toLowerCase()}"
1810
+ :context="context"
1811
+ ${standardParamsFragment}
1812
+ :secondaryColor="secondaryColor">
1813
+ </i-document-link>
1804
1814
  `;
1805
1815
  }
1806
1816
  if (isDateExp(element)) {
1807
- return expandToNode `
1808
- <i-datetime
1809
- type="date"
1810
- label="${label}"
1811
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1812
- systemPath="system.${element.name.toLowerCase()}"
1813
- :context="context"
1814
- ${standardParamsFragment}
1815
- :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1816
- </i-datetime>
1817
+ return expandToNode `
1818
+ <i-datetime
1819
+ type="date"
1820
+ label="${label}"
1821
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1822
+ systemPath="system.${element.name.toLowerCase()}"
1823
+ :context="context"
1824
+ ${standardParamsFragment}
1825
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1826
+ </i-datetime>
1817
1827
  `;
1818
1828
  }
1819
1829
  if (isTimeExp(element)) {
1820
- return expandToNode `
1821
- <i-datetime
1822
- type="time"
1823
- label="${label}"
1824
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1825
- systemPath="system.${element.name.toLowerCase()}"
1826
- :context="context"
1827
- ${standardParamsFragment}
1828
- :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1829
- </i-datetime>
1830
+ return expandToNode `
1831
+ <i-datetime
1832
+ type="time"
1833
+ label="${label}"
1834
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1835
+ systemPath="system.${element.name.toLowerCase()}"
1836
+ :context="context"
1837
+ ${standardParamsFragment}
1838
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1839
+ </i-datetime>
1830
1840
  `;
1831
1841
  }
1832
1842
  if (isDateTimeExp(element)) {
1833
- return expandToNode `
1834
- <i-datetime
1835
- type="datetime-local"
1836
- label="${label}"
1837
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1838
- systemPath="system.${element.name.toLowerCase()}"
1839
- :context="context"
1840
- ${standardParamsFragment}
1841
- :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1842
- </i-datetime>
1843
+ return expandToNode `
1844
+ <i-datetime
1845
+ type="datetime-local"
1846
+ label="${label}"
1847
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1848
+ systemPath="system.${element.name.toLowerCase()}"
1849
+ :context="context"
1850
+ ${standardParamsFragment}
1851
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1852
+ </i-datetime>
1843
1853
  `;
1844
1854
  }
1845
1855
  if (isPaperDollExp(element)) {
@@ -1847,17 +1857,17 @@ function generateVueComponentTemplate(entry, id, document) {
1847
1857
  let size = (_q = sizeParam === null || sizeParam === void 0 ? void 0 : sizeParam.value) !== null && _q !== void 0 ? _q : "40px";
1848
1858
  let imageParam = element.params.find(x => isImageParam(x));
1849
1859
  let image = (_r = imageParam === null || imageParam === void 0 ? void 0 : imageParam.value) !== null && _r !== void 0 ? _r : `systems/${id}/img/paperdoll_default.png`;
1850
- return expandToNode `
1851
- <i-paperdoll
1852
- label="${label}"
1853
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1854
- systemPath="system.${element.name.toLowerCase()}"
1855
- :context="context"
1856
- ${standardParamsFragment}
1857
- image="${image}"
1858
- size="${size}"
1859
- :slots="${element.name.toLowerCase()}Slots">
1860
- </i-paperdoll>
1860
+ return expandToNode `
1861
+ <i-paperdoll
1862
+ label="${label}"
1863
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1864
+ systemPath="system.${element.name.toLowerCase()}"
1865
+ :context="context"
1866
+ ${standardParamsFragment}
1867
+ image="${image}"
1868
+ size="${size}"
1869
+ :slots="${element.name.toLowerCase()}Slots">
1870
+ </i-paperdoll>
1861
1871
  `;
1862
1872
  }
1863
1873
  if (isDiceFields(element)) {
@@ -1866,32 +1876,32 @@ function generateVueComponentTemplate(entry, id, document) {
1866
1876
  let noneParam = element.params.find(x => isDieNoneParam(x));
1867
1877
  let noneAttr = (noneParam === null || noneParam === void 0 ? void 0 : noneParam.value) ? `:none="true"` : '';
1868
1878
  if (isDieField(element)) {
1869
- return expandToNode `
1870
- <i-die
1871
- :context="context"
1872
- label="${label}"
1873
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1874
- systemPath="${systemPath}"
1875
- :choices="${choices}"
1876
- ${noneAttr}
1877
- ${standardParamsFragment}>
1878
- </i-die>
1879
+ return expandToNode `
1880
+ <i-die
1881
+ :context="context"
1882
+ label="${label}"
1883
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1884
+ systemPath="${systemPath}"
1885
+ :choices="${choices}"
1886
+ ${noneAttr}
1887
+ ${standardParamsFragment}>
1888
+ </i-die>
1879
1889
  `;
1880
1890
  }
1881
1891
  if (isDiceField(element)) {
1882
- return expandToNode `
1883
- <i-dice
1884
- label="${label}"
1885
- icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1886
- systemPath="system.${element.name.toLowerCase()}"
1887
- :context="context"
1888
- :editMode="editModeRef"
1889
- :disabled="isDisabled('${element.name.toLowerCase()}')"
1890
- v-if="!isHidden('${element.name.toLowerCase()}')"
1891
- :choices="${choices}"
1892
- :primaryColor="primaryColor"
1893
- :secondaryColor="secondaryColor"
1894
- />
1892
+ return expandToNode `
1893
+ <i-dice
1894
+ label="${label}"
1895
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1896
+ systemPath="system.${element.name.toLowerCase()}"
1897
+ :context="context"
1898
+ :editMode="editModeRef"
1899
+ :disabled="isDisabled('${element.name.toLowerCase()}')"
1900
+ v-if="!isHidden('${element.name.toLowerCase()}')"
1901
+ :choices="${choices}"
1902
+ :primaryColor="primaryColor"
1903
+ :secondaryColor="secondaryColor"
1904
+ />
1895
1905
  `;
1896
1906
  }
1897
1907
  }
@@ -1907,10 +1917,10 @@ function generateVueComponentTemplate(entry, id, document) {
1907
1917
  // sheet's drop target); layout-rendered tables aren't, so without this
1908
1918
  // wrapper they have no drop target. The wrapper only exists in the layout
1909
1919
  // case (never nested inside a .tabs-container), so no double drop binding.
1910
- return expandToNode `
1911
- <div class="datatable-drop-zone" v-if="!isHidden('${element.name.toLowerCase()}')">
1912
- <${componentName} systemPath="${systemPath}" :context="context" :primaryColor="primaryColor" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"></${componentName}>
1913
- </div>
1920
+ return expandToNode `
1921
+ <div class="datatable-drop-zone" v-if="!isHidden('${element.name.toLowerCase()}')">
1922
+ <${componentName} systemPath="${systemPath}" :context="context" :primaryColor="primaryColor" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"></${componentName}>
1923
+ </div>
1914
1924
  `.appendNewLine();
1915
1925
  }
1916
1926
  if (isInventoryField(element)) {
@@ -1999,43 +2009,43 @@ function generateVueComponentTemplate(entry, id, document) {
1999
2009
  const whereNode = translateExpression(entry, id, whereParam.value);
2000
2010
  whereExpression = whereNode ? toString(whereNode) : undefined;
2001
2011
  }
2002
- return expandToNode `
2003
- <i-inventory
2004
- v-if="!isHidden('${element.name.toLowerCase()}')"
2005
- label="${label}"
2006
- systemPath="${systemPath}"
2007
- :context="context"
2008
- :editMode="editModeRef"
2009
- ${icon ? `icon="${icon}"` : ''}
2010
- ${slots ? `:maxSlots="${slots}"` : ''}
2011
- ${rows ? `:rows="${rows}"` : ''}
2012
- ${columns ? `:columns="${columns}"` : ''}
2013
- :slotSize="${slotSize}"
2014
- documentType="${documentType}"
2015
- ${whereExpression ? `whereExpression="${whereExpression}"` : ''}
2016
- ${globalAllowed ? ':globalAllowed="true"' : ''}
2017
- ${quantityField ? `quantityField="${quantityField}"` : ''}
2018
- ${moneyField ? `moneyField="${moneyField}"` : ''}
2019
- ${moneyFieldLabel ? `moneyFieldLabel="${moneyFieldLabel}"` : ''}
2020
- ${moneyFieldIcon ? `moneyFieldIcon="${moneyFieldIcon}"` : ''}
2021
- ${sumProperties.length > 0 ? `:sumProperties='${JSON.stringify(sumProperties)}'` : ''}
2022
- ${sumMax ? `:sumMax="${sumMax}"` : ''}
2023
- ${sortProperty ? `sortProperty="${sortProperty}"` : ''}
2024
- sortOrder="${sortOrder}"
2025
- emptySlots="${emptySlots}"
2026
- summary="${summary}"
2027
- :primaryColor="primaryColor"
2028
- :secondaryColor="secondaryColor"
2029
- :tertiaryColor="tertiaryColor"
2030
- />
2012
+ return expandToNode `
2013
+ <i-inventory
2014
+ v-if="!isHidden('${element.name.toLowerCase()}')"
2015
+ label="${label}"
2016
+ systemPath="${systemPath}"
2017
+ :context="context"
2018
+ :editMode="editModeRef"
2019
+ ${icon ? `icon="${icon}"` : ''}
2020
+ ${slots ? `:maxSlots="${slots}"` : ''}
2021
+ ${rows ? `:rows="${rows}"` : ''}
2022
+ ${columns ? `:columns="${columns}"` : ''}
2023
+ :slotSize="${slotSize}"
2024
+ documentType="${documentType}"
2025
+ ${whereExpression ? `whereExpression="${whereExpression}"` : ''}
2026
+ ${globalAllowed ? ':globalAllowed="true"' : ''}
2027
+ ${quantityField ? `quantityField="${quantityField}"` : ''}
2028
+ ${moneyField ? `moneyField="${moneyField}"` : ''}
2029
+ ${moneyFieldLabel ? `moneyFieldLabel="${moneyFieldLabel}"` : ''}
2030
+ ${moneyFieldIcon ? `moneyFieldIcon="${moneyFieldIcon}"` : ''}
2031
+ ${sumProperties.length > 0 ? `:sumProperties='${JSON.stringify(sumProperties)}'` : ''}
2032
+ ${sumMax ? `:sumMax="${sumMax}"` : ''}
2033
+ ${sortProperty ? `sortProperty="${sortProperty}"` : ''}
2034
+ sortOrder="${sortOrder}"
2035
+ emptySlots="${emptySlots}"
2036
+ summary="${summary}"
2037
+ :primaryColor="primaryColor"
2038
+ :secondaryColor="secondaryColor"
2039
+ :tertiaryColor="tertiaryColor"
2040
+ />
2031
2041
  `.appendNewLine();
2032
2042
  }
2033
- return expandToNode `
2034
- <v-alert text="Unknown Property ${element.name}" type="warning" density="compact" class="ga-2 ma-1" variant="outlined"></v-alert>
2043
+ return expandToNode `
2044
+ <v-alert text="Unknown Property ${element.name}" type="warning" density="compact" class="ga-2 ma-1" variant="outlined"></v-alert>
2035
2045
  `;
2036
2046
  }
2037
- return expandToNode `
2038
- <v-alert text="Unknown Element" type="warning" density="compact" class="ga-2 ma-1" variant="outlined"></v-alert>
2047
+ return expandToNode `
2048
+ <v-alert text="Unknown Element" type="warning" density="compact" class="ga-2 ma-1" variant="outlined"></v-alert>
2039
2049
  `;
2040
2050
  }
2041
2051
  }