dazscript-framework 1.0.37 → 1.0.38

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dazscript-framework",
3
- "version": "1.0.37",
3
+ "version": "1.0.38",
4
4
  "author": "Freddy Diaz",
5
5
  "license": "MPL-2.0",
6
6
  "description": "",
@@ -0,0 +1,33 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { SETUP_BULK_ACTIONS, applySetupBulkSelection } from './custom-action-installer-bulk'
3
+
4
+ describe('setup bulk actions', () => {
5
+ it('uses concise install and uninstall labels', () => {
6
+ expect(SETUP_BULK_ACTIONS.installAll.label).toBe('Install All')
7
+ expect(SETUP_BULK_ACTIONS.uninstallAll.label).toBe('Uninstall All')
8
+ })
9
+
10
+ it('selects every installer entry for install all', () => {
11
+ const entries = [
12
+ { selected: false },
13
+ { selected: true },
14
+ { selected: false }
15
+ ]
16
+
17
+ applySetupBulkSelection(entries, true)
18
+
19
+ expect(entries.map(entry => entry.selected)).toEqual([true, true, true])
20
+ })
21
+
22
+ it('deselects every installer entry for uninstall all', () => {
23
+ const entries = [
24
+ { selected: true },
25
+ { selected: false },
26
+ { selected: true }
27
+ ]
28
+
29
+ applySetupBulkSelection(entries, false)
30
+
31
+ expect(entries.map(entry => entry.selected)).toEqual([false, false, false])
32
+ })
33
+ })
@@ -0,0 +1,22 @@
1
+ type BulkSelectableEntry = {
2
+ selected: boolean
3
+ }
4
+
5
+ export const SETUP_BULK_ACTIONS = {
6
+ installAll: {
7
+ label: 'Install All',
8
+ toolTip: 'Install every setup entry, ignoring the current search filter and checkbox state.',
9
+ whatsThis: 'Installs every script action in this setup dialog. This does not depend on which rows are checked or currently visible.'
10
+ },
11
+ uninstallAll: {
12
+ label: 'Uninstall All',
13
+ toolTip: 'Uninstall every setup entry, ignoring the current search filter and checkbox state.',
14
+ whatsThis: 'Removes every script action in this setup dialog from its menu and toolbar targets. This does not depend on which rows are checked or currently visible.'
15
+ }
16
+ }
17
+
18
+ export const applySetupBulkSelection = <TEntry extends BulkSelectableEntry>(entries: TEntry[], selected: boolean): void => {
19
+ entries.forEach((entry) => {
20
+ entry.selected = selected
21
+ })
22
+ }
@@ -12,6 +12,7 @@ import { TreeNode } from '@dsf/lib/tree-node'
12
12
  import { promptKeyboardShortcut } from '@dsf/shared/set-keyboard-shortcut'
13
13
  import { readFromFile, saveToFile } from './file-helper'
14
14
  import { getCanonicalInstallerEntry, toActionKey } from './custom-action-installer-entries'
15
+ import { SETUP_BULK_ACTIONS, applySetupBulkSelection } from './custom-action-installer-bulk'
15
16
  import { canResetSetupShortcut, getDisplayedSetupShortcut, resetSetupShortcut, resetSetupShortcuts, setSetupShortcut, updateShortcutOverrideState } from './custom-action-installer-shortcuts'
16
17
  import { getScriptPath } from './script-helper'
17
18
 
@@ -192,6 +193,7 @@ class InstallerSelectionDialog extends BasicDialog {
192
193
  private readonly refreshListEvent$ = new Observable<void>()
193
194
  private listView: DzListView | null = null
194
195
  private shortcutListView: DzListView | null = null
196
+ private bulkSelectionApplied = false
195
197
 
196
198
  constructor(
197
199
  private readonly entries: InstallerEntry[],
@@ -207,6 +209,7 @@ class InstallerSelectionDialog extends BasicDialog {
207
209
  this.builder.options({ resizable: true, width: 1100, height: 700 })
208
210
  this.dialog.setAcceptButtonText('Apply')
209
211
  this.dialog.setCancelButtonText('Cancel')
212
+ this.addBulkActionButtons()
210
213
 
211
214
  if (this.shortcutEntries.length > 0) {
212
215
  const add = this.add
@@ -219,7 +222,9 @@ class InstallerSelectionDialog extends BasicDialog {
219
222
  }
220
223
 
221
224
  getSelections(): SetupSelection {
222
- this.syncSelectionsFromListView()
225
+ if (!this.bulkSelectionApplied) {
226
+ this.syncSelectionsFromListView()
227
+ }
223
228
  this.syncShortcutSelectionsFromListView()
224
229
  return {
225
230
  actions: this.entries,
@@ -227,6 +232,10 @@ class InstallerSelectionDialog extends BasicDialog {
227
232
  }
228
233
  }
229
234
 
235
+ hasBulkSelectionApplied(): boolean {
236
+ return this.bulkSelectionApplied
237
+ }
238
+
230
239
  private buildScriptsTab(): void {
231
240
  const add = this.add
232
241
 
@@ -430,6 +439,34 @@ class InstallerSelectionDialog extends BasicDialog {
430
439
  })
431
440
  }
432
441
 
442
+ private addBulkActionButtons(): void {
443
+ if (this.entries.length === 0) return
444
+
445
+ const installAllButton = this.createBulkActionButton(
446
+ SETUP_BULK_ACTIONS.installAll.label,
447
+ SETUP_BULK_ACTIONS.installAll.toolTip,
448
+ SETUP_BULK_ACTIONS.installAll.whatsThis
449
+ )
450
+ installAllButton.clicked.scriptConnect(() => this.applyBulkSelection(true))
451
+ this.dialog.addButton(installAllButton, 0)
452
+
453
+ const uninstallAllButton = this.createBulkActionButton(
454
+ SETUP_BULK_ACTIONS.uninstallAll.label,
455
+ SETUP_BULK_ACTIONS.uninstallAll.toolTip,
456
+ SETUP_BULK_ACTIONS.uninstallAll.whatsThis
457
+ )
458
+ uninstallAllButton.clicked.scriptConnect(() => this.confirmAndApplyBulkUninstall())
459
+ this.dialog.addButton(uninstallAllButton, 1)
460
+ }
461
+
462
+ private createBulkActionButton(label: string, toolTip: string, whatsThis: string): DzPushButton {
463
+ const button = new DzPushButton(this.dialog)
464
+ button.text = label
465
+ button.toolTip = toolTip
466
+ button.whatsThis = whatsThis
467
+ return button
468
+ }
469
+
433
470
  private getContextListItem(listView: DzListView, listItem: any): DzListViewItem | null {
434
471
  if (this.isListViewItem(listItem)) return listItem
435
472
 
@@ -535,6 +572,24 @@ class InstallerSelectionDialog extends BasicDialog {
535
572
  this.checkVisible(this.listView, onOff)
536
573
  }
537
574
 
575
+ private applyBulkSelection(selected: boolean): void {
576
+ applySetupBulkSelection(this.entries, selected)
577
+ this.bulkSelectionApplied = true
578
+ this.dialog.close()
579
+ }
580
+
581
+ private confirmAndApplyBulkUninstall(): void {
582
+ const response = MessageBox.question(
583
+ 'Uninstall all scripts from menu and toolbar targets?',
584
+ 'Uninstall All',
585
+ 'Uninstall All',
586
+ 'Cancel'
587
+ )
588
+ if (response !== 0) return
589
+
590
+ this.applyBulkSelection(false)
591
+ }
592
+
538
593
  private syncSelectionsFromListView() {
539
594
  if (!this.listView) return
540
595
 
@@ -609,7 +664,10 @@ const runDialog = (actions: CustomAction[], options: SetupDialogOptions): SetupS
609
664
  const entries = buildEntries(actions)
610
665
  const shortcutEntries = buildShortcutEntries(options.shortcuts)
611
666
  const dialog = new InstallerSelectionDialog(entries, shortcutEntries, options)
612
- return dialog.ok() ? dialog.getSelections() : null
667
+ const accepted = dialog.ok()
668
+ return accepted || dialog.hasBulkSelectionApplied()
669
+ ? dialog.getSelections()
670
+ : null
613
671
  }
614
672
 
615
673
  const readShortcutBackup = (backupPath: string): ShortcutBackupFile => {