From 5f734708b20e62721035e7fb26c03c5690a9d3ba Mon Sep 17 00:00:00 2001 From: undergroundwires Date: Tue, 4 Jan 2022 18:41:28 +0100 Subject: [PATCH] Add unique IDs for scripts/categories $49, $59, $262, $126 TODO: After it compiles. - Check all touched stuff, write/update tests. - Check names if they're good, GPT revisions etc. Using IDs simplify planned import / export functionality. - Add ID validation in collection data with suggestions. - Add utility/helper script to generate missing IDs in collection files. Supporting changes: - Name related interfaces to drop `I` prefix to align with modern conventions. - Remove Entity from infrastructure layer to better align with DDD (domain-driven design) as it's a domain concern. - Remove EntityBase for simplicity and to avoid technical nomenclature in names. - Introduce new types for keys and identifiable objects. - Create subfolders in `src/domain` for better structure/navigatability. - Improve context on thrown error messages. TODO: - Move BaseEntity to domain layer. - Rename IScript to drop I prefix. - Rename ICategory to drop I prefix. - Change category to use string IDs. - Add IDs for every script / category. - Document IDs for nodes. - Ensure that every script / category has unique ID across collections. - Bug: Standard -> Selected _-> None, when done Standard not being higlighted. --- CHANGELOG.md | 2 +- docs/collection-files.md | 6 +- docs/development.md | 4 +- scripts/add_missing_ids.py | 126 +++ src/application/Context/ApplicationContext.ts | 4 +- .../Context/State/CategoryCollectionState.ts | 4 +- .../State/Code/Event/CodeChangedEvent.ts | 27 +- .../State/Code/Event/ICodeChangedEvent.ts | 10 +- .../State/Filter/AdaptiveFilterContext.ts | 4 +- .../Filter/Result/AppliedFilterResult.ts | 8 +- .../State/Filter/Result/FilterResult.ts | 7 +- .../State/Filter/Strategy/FilterStrategy.ts | 4 +- .../Filter/Strategy/LinearFilterStrategy.ts | 19 +- .../Context/State/ICategoryCollectionState.ts | 4 +- .../Selection/Category/CategorySelection.ts | 6 +- .../Category/CategorySelectionChange.ts | 4 +- .../ScriptToCategorySelectionMapper.ts | 20 +- .../Script/DebouncedScriptSelection.ts | 93 +- .../State/Selection/Script/ScriptSelection.ts | 7 +- .../Selection/Script/ScriptSelectionChange.ts | 4 +- .../State/Selection/Script/SelectedScript.ts | 11 +- .../Selection/Script/UserSelectedScript.ts | 16 +- .../State/Selection/UserSelectionFacade.ts | 6 +- src/application/Parser/ApplicationParser.ts | 4 +- .../Parser/CategoryCollectionParser.ts | 24 +- src/application/Parser/CategoryParser.ts | 53 +- .../Parser/NodeValidation/NodeDataError.ts | 8 +- .../Parser/NodeValidation/NodeValidator.ts | 32 +- src/application/Parser/NodeValidation/TODO.md | 2 + .../Script/CategoryCollectionParseContext.ts | 24 +- .../CategoryCollectionParseContextFacade.ts | 32 + .../Parser/Script/Compiler/IScriptCompiler.ts | 4 +- .../Parser/Script/Compiler/ScriptCompiler.ts | 12 +- .../Script/ICategoryCollectionParseContext.ts | 7 - .../CollectionExecutableKeyFactory.ts | 5 + .../PartialGuidExecutableKeyFactory.ts | 16 + src/application/Parser/Script/ScriptParser.ts | 28 +- src/application/Repository/Repository.ts | 15 +- .../collections/collection.yaml.d.ts | 8 +- src/application/collections/linux.yaml | 178 +++- src/application/collections/macos.yaml | 179 +++- src/application/collections/windows.yaml | 901 +++++++++++++++++- src/domain/Application.ts | 8 +- src/domain/Category.ts | 45 - src/domain/CategoryCollection.ts | 154 --- .../Collection/CachedCategoryCollection.ts | 181 ++++ src/domain/Collection/CategoryCollection.ts | 22 + .../Collection/Key/CategoryCollectionKey.ts | 6 + .../Collection/Key/OsCategoryCollectionKey.ts | 23 + src/domain/Executables/Category/Category.ts | 11 + .../Category/CollectionCategory.ts | 44 + .../Documentable.ts} | 2 +- src/domain/Executables/Executable.ts | 6 + .../ExecutableKey/ExecutableKey.ts | 9 + .../ExecutableKey/PartialGuidExecutableKey.ts | 31 + .../Code/DistinctReversibleScriptCode.ts} | 4 +- .../Script/Code/ScriptCode.ts} | 2 +- .../Script/CollectionScript.ts} | 14 +- .../Script}/RecommendationLevel.ts | 0 src/domain/Executables/Script/Script.ts | 12 + src/domain/IApplication.ts | 8 +- src/domain/ICategory.ts | 15 - src/domain/ICategoryCollection.ts | 19 - src/domain/IScript.ts | 12 - src/domain/Identifiable/Identifiable.ts | 5 + src/domain/Identifiable/Key.ts | 4 + src/infrastructure/Entity/BaseEntity.ts | 14 - src/infrastructure/Entity/IEntity.ts | 5 - .../Repository/InMemoryRepository.ts | 31 +- .../components/Code/TheCodeArea.vue | 4 +- .../RecommendationStatusHandler.ts | 16 +- .../TheRecommendationSelector.vue | 4 +- .../Menu/Revert/RevertStatusHandler.ts | 2 +- .../Scripts/Menu/Revert/TheRevertSelector.vue | 6 +- .../Scripts/View/Cards/CardExpansionPanel.vue | 89 ++ .../Scripts/View/Cards/CardList.vue | 9 +- .../Scripts/View/Cards/CardListItem.vue | 7 +- .../View/Cards/CardSelectionIndicator.vue | 13 +- .../View/Tree/NodeContent/RevertToggle.vue | 4 +- .../NodeContent/Reverter/CategoryReverter.ts | 24 +- .../NodeContent/Reverter/ReverterFactory.ts | 20 +- .../NodeContent/Reverter/ScriptReverter.ts | 14 +- .../Scripts/View/Tree/ScriptsTree.vue | 5 +- .../CategoryNodeMetadataConverter.ts | 56 +- .../UseCollectionSelectionStateUpdater.ts | 13 +- .../TreeViewAdapter/UseTreeViewFilterEvent.ts | 12 +- .../TreeViewAdapter/UseTreeViewNodeInput.ts | 9 +- .../CompositeMarkdownRenderer.spec.ts | 2 +- .../Context/ApplicationContextFactory.spec.ts | 4 +- .../State/CategoryCollectionState.spec.ts | 10 +- .../Filter/AdaptiveFilterContext.spec.ts | 7 +- .../Filter/Result/AppliedFilterResult.spec.ts | 21 +- .../Strategy/LinearFilterStrategy.spec.ts | 44 +- .../ScriptToCategorySelectionMapper.spec.ts | 79 +- .../Script/DebouncedScriptSelection.spec.ts | 50 +- .../Script/ExpectEqualSelectedScripts.ts | 12 +- .../Selection/UserSelectionFacade.spec.ts | 10 +- .../Parser/CategoryCollectionParser.spec.ts | 8 +- .../application/Parser/CategoryParser.spec.ts | 24 +- .../NodeValidation/NodeDataError.spec.ts | 6 +- .../NodeValidation/NodeValidator.spec.ts | 36 +- .../NodeValidation/NodeValidatorTestRunner.ts | 73 +- ...egoryCollectionParseContextFacade.spec.ts} | 10 +- .../Script/Compiler/ScriptCompiler.spec.ts | 2 +- .../Parser/Script/ScriptParser.spec.ts | 47 +- tests/unit/domain/Application.spec.ts | 6 +- .../CachedCategoryCollection.spec.ts} | 69 +- .../Category/CollectionCategory.spec.ts} | 28 +- .../DistinctReversibleScriptCode.spec.ts} | 7 +- .../Script/CollectionScript.spec.ts} | 100 +- .../infrastructure/InMemoryRepository.spec.ts | 69 +- .../RecommendationStatusHandler.spec.ts | 11 +- .../RecommendationStatusTestScenario.ts | 4 +- .../Reverter/CategoryReverter.spec.ts | 8 +- .../Reverter/ScriptReverter.spec.ts | 2 +- .../CategoryNodeMetadataConverter.spec.ts | 20 +- .../UseSelectedScriptNodeIds.spec.ts | 10 +- .../UseTreeViewFilterEvent.spec.ts | 14 +- .../UseTreeViewNodeInput.spec.ts | 8 +- tests/unit/shared/Stubs/ApplicationStub.ts | 10 +- .../shared/Stubs/CategoryCollectionKeyStub.ts | 14 + .../Stubs/CategoryCollectionParserStub.ts | 8 +- .../Stubs/CategoryCollectionStateStub.ts | 10 +- .../shared/Stubs/CategoryCollectionStub.ts | 51 +- tests/unit/shared/Stubs/CategoryDataStub.ts | 7 + .../shared/Stubs/CategorySelectionStub.ts | 5 +- tests/unit/shared/Stubs/CategoryStub.ts | 42 +- .../unit/shared/Stubs/CodeChangedEventStub.ts | 8 +- tests/unit/shared/Stubs/CollectionDataStub.ts | 3 +- tests/unit/shared/Stubs/ExecutableKeyStub.ts | 22 + tests/unit/shared/Stubs/FilterResultStub.ts | 12 +- .../shared/Stubs/NodeDataErrorContextStub.ts | 6 +- tests/unit/shared/Stubs/NumericEntityStub.ts | 14 - tests/unit/shared/Stubs/ScriptCodeStub.ts | 8 +- tests/unit/shared/Stubs/ScriptCompilerStub.ts | 10 +- tests/unit/shared/Stubs/ScriptDataStub.ts | 9 +- .../unit/shared/Stubs/ScriptSelectionStub.ts | 6 +- tests/unit/shared/Stubs/ScriptStub.ts | 37 +- tests/unit/shared/Stubs/SelectedScriptStub.ts | 13 +- .../shared/Stubs/StringIdentifiableStub.ts | 32 + 140 files changed, 3011 insertions(+), 1039 deletions(-) create mode 100644 scripts/add_missing_ids.py create mode 100644 src/application/Parser/NodeValidation/TODO.md create mode 100644 src/application/Parser/Script/CategoryCollectionParseContextFacade.ts delete mode 100644 src/application/Parser/Script/ICategoryCollectionParseContext.ts create mode 100644 src/application/Parser/Script/KeyFactory/CollectionExecutableKeyFactory.ts create mode 100644 src/application/Parser/Script/KeyFactory/PartialGuidExecutableKeyFactory.ts delete mode 100644 src/domain/Category.ts delete mode 100644 src/domain/CategoryCollection.ts create mode 100644 src/domain/Collection/CachedCategoryCollection.ts create mode 100644 src/domain/Collection/CategoryCollection.ts create mode 100644 src/domain/Collection/Key/CategoryCollectionKey.ts create mode 100644 src/domain/Collection/Key/OsCategoryCollectionKey.ts create mode 100644 src/domain/Executables/Category/Category.ts create mode 100644 src/domain/Executables/Category/CollectionCategory.ts rename src/domain/{IDocumentable.ts => Executables/Documentable.ts} (56%) create mode 100644 src/domain/Executables/Executable.ts create mode 100644 src/domain/Executables/ExecutableKey/ExecutableKey.ts create mode 100644 src/domain/Executables/ExecutableKey/PartialGuidExecutableKey.ts rename src/domain/{ScriptCode.ts => Executables/Script/Code/DistinctReversibleScriptCode.ts} (84%) rename src/domain/{IScriptCode.ts => Executables/Script/Code/ScriptCode.ts} (65%) rename src/domain/{Script.ts => Executables/Script/CollectionScript.ts} (60%) rename src/domain/{ => Executables/Script}/RecommendationLevel.ts (100%) create mode 100644 src/domain/Executables/Script/Script.ts delete mode 100644 src/domain/ICategory.ts delete mode 100644 src/domain/ICategoryCollection.ts delete mode 100644 src/domain/IScript.ts create mode 100644 src/domain/Identifiable/Identifiable.ts create mode 100644 src/domain/Identifiable/Key.ts delete mode 100644 src/infrastructure/Entity/BaseEntity.ts delete mode 100644 src/infrastructure/Entity/IEntity.ts create mode 100644 src/presentation/components/Scripts/View/Cards/CardExpansionPanel.vue rename tests/unit/application/Parser/Script/{CategoryCollectionParseContext.spec.ts => CategoryCollectionParseContextFacade.spec.ts} (84%) rename tests/unit/domain/{CategoryCollection.spec.ts => Collection/CachedCategoryCollection.spec.ts} (80%) rename tests/unit/domain/{Category.spec.ts => Executables/Category/CollectionCategory.spec.ts} (81%) rename tests/unit/domain/{ScriptCode.spec.ts => Executables/Script/Code/DistinctReversibleScriptCode.spec.ts} (91%) rename tests/unit/domain/{Script.spec.ts => Executables/Script/CollectionScript.spec.ts} (51%) create mode 100644 tests/unit/shared/Stubs/CategoryCollectionKeyStub.ts create mode 100644 tests/unit/shared/Stubs/ExecutableKeyStub.ts delete mode 100644 tests/unit/shared/Stubs/NumericEntityStub.ts create mode 100644 tests/unit/shared/Stubs/StringIdentifiableStub.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c11bd3688..8786a6f92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -465,7 +465,7 @@ * rework Cortana scripts to remove duplicates, better document and support Windows version 2004/2009 #43 | [7cc161c](https://github.com/undergroundwires/privacy.sexy/commit/7cc161c828a3fa49f6f254e31834a95a502b7aa2) * rename Application to CategoryCollection #40 | [6fe858d](https://github.com/undergroundwires/privacy.sexy/commit/6fe858d86aeb0f8b6d5ae5c2a5e3c25ff32e5f6f) * add script to clean previous windows installation #35 | [3455a2c](https://github.com/undergroundwires/privacy.sexy/commit/3455a2ca6ce13f9b0e866d88532a5c3d6de30d4d) -* refactor to allow switching ICategoryCollection context #40 | [2e40605](https://github.com/undergroundwires/privacy.sexy/commit/2e40605d59eb764768457c6af561487e7ff09777) +* refactor to allow switching CategoryCollection context #40 | [2e40605](https://github.com/undergroundwires/privacy.sexy/commit/2e40605d59eb764768457c6af561487e7ff09777) * fix typo causing uninstalling capabilities to fail #51 | [c299e95](https://github.com/undergroundwires/privacy.sexy/commit/c299e95bc6d588317b69a9efcf5752ff5c9c3926) * improve uninstalling apps to show errors and exit if taking ownership fails #51 | [72e925f](https://github.com/undergroundwires/privacy.sexy/commit/72e925fb6f908cd58fb50618f29726b3fb54a7f1) * move application.yaml to collections/windows.yaml #40 | [6b83dcb](https://github.com/undergroundwires/privacy.sexy/commit/6b83dcbf8fa08b4efe9974c7d7a667458f7c595c) diff --git a/docs/collection-files.md b/docs/collection-files.md index d58d2d1ed..1048eaa2a 100644 --- a/docs/collection-files.md +++ b/docs/collection-files.md @@ -34,6 +34,8 @@ Represents a logical group of scripts and subcategories. #### `Category` syntax +- `id:`: *string* **(required)** # TODO: Revise this docs + - Executable ID, unique across all categories and scripts in same category collection (for same operating system). - `category:` *`string`* **(required)** - Name of the category. - ❗ Must be unique throughout the [collection](#collection). @@ -45,7 +47,7 @@ Represents a logical group of scripts and subcategories. ### `Script` -Represents an individual tweak. +Represents an independently executable and reversible tweak. Types (like [functions](#function)): @@ -60,6 +62,8 @@ Types (like [functions](#function)): #### `Script` syntax +- `id:`: *string* **(required)** # TODO: Revise this docs + - Executable ID, unique across all categories and scripts in same category collection (for same operating system). - `name`: *`string`* **(required)** - Script name. - ❗ Must be unique throughout the [Collection](#collection). diff --git a/docs/development.md b/docs/development.md index b7a1f1499..75a31ff9f 100644 --- a/docs/development.md +++ b/docs/development.md @@ -80,8 +80,10 @@ See [ci-cd.md](./ci-cd.md) for more information. - [**`npm run install-deps [-- ]`**](../scripts/npm-install.js): - Manages NPM dependency installation, it offers capabilities like doing a fresh install, retries on network errors, and other features. - For example, you can run `npm run install-deps -- --fresh` to do clean installation of dependencies. -- [**`python ./scripts/configure_vscode.py`**](../scripts/configure_vscode.py): +- [**`python3 ./scripts/configure_vscode.py`**](../scripts/configure_vscode.py): - Optimizes Visual Studio Code settings and installs essential extensions, enhancing the development environment. +- [**`python3 ./scripts/add_missing_ids.py`**](../scripts/add_missing_ids.py): + - Adds unique `id` fields to scripts and categories lacking them in collection files. #### Automation scripts diff --git a/scripts/add_missing_ids.py b/scripts/add_missing_ids.py new file mode 100644 index 000000000..e6ddde759 --- /dev/null +++ b/scripts/add_missing_ids.py @@ -0,0 +1,126 @@ +""" +Description: + This script checks the existing collection files and add `id` field to missing script/categories + by generating a new unique id. + +Usage: + python3 ./scripts/add_missing_ids.py + +Note: + This command must run from the project root directory. +""" +# pylint: disable=missing-function-docstring,missing-class-docstring + +import os +from pathlib import Path +import re +import sys +from typing import List, Set +import uuid + +def main() -> None: + collections_directory = './src/application/collections' + yaml_file_paths = find_yaml_files(collections_directory) + if not yaml_file_paths: + print('No collection files found', file=sys.stderr) + sys.exit(1) + print(f'Total collection files found: {len(yaml_file_paths)}.') + + for yaml_file_path in yaml_file_paths: + print(f'Processing: {yaml_file_path}') + old_contents = read_yaml_file(yaml_file_path) + processed_yaml = add_id_to_yaml_content(old_contents) + if not processed_yaml.total_new_ids: + print('👌 No changes needed, no missing IDs.') + continue + save_yaml_file(yaml_file_path, processed_yaml.new_content) + print(f'🆕 Added missing IDs (total: {processed_yaml.total_new_ids}).') + +class YamlIdAdditionResult: + def __init__(self, new_content: str, total_new_ids: int): + self.new_content = new_content + self.total_new_ids = total_new_ids + +def add_id_to_yaml_content(content: str) -> YamlIdAdditionResult: + # Avoiding external yaml libraries to preserve YAML structure and comments. + existing_ids = find_existing_ids(content) + original_lines = content.splitlines() + new_lines = [] + total_new_ids = 0 + functions_section_reached = False + for i, line in enumerate(original_lines): + if is_functions_section_start(line): + functions_section_reached = True + if (not functions_section_reached) and \ + is_executable_name(line) and \ + (not has_line_before_defined_id(i, original_lines)): + indentation = len(line) - len(line.lstrip()) + new_id = generate_unique_id(existing_ids) + total_new_ids += 1 + existing_ids.add(new_id) + id_line_prefix = "#" if is_preceding_line_comment(i, original_lines) else "" + id_line = f'{" " * indentation}{id_line_prefix}id: {new_id}' + new_lines.append(id_line) # Insert new id line before 'name:' + new_lines.append(line) + return YamlIdAdditionResult( + new_content=os.linesep.join(new_lines), + total_new_ids=total_new_ids, + ) + +def is_functions_section_start(collection_file_line: str) -> bool: + return 'functions:' in collection_file_line + +def is_executable_name(collection_file_line: str) -> bool: + non_commented_line = get_non_commented_line(collection_file_line) + stripped_line = non_commented_line.lstrip() + return stripped_line.startswith('name:') or stripped_line.startswith('category:') + +def is_preceding_line_comment(current_line: int, all_lines: list[str]) -> bool: + return current_line > 0 and all_lines[current_line-1].strip().startswith('#') + +def has_line_before_defined_id(current_line: int, all_lines: list[str]) -> bool: + if current_line == 0: + return False + line_before = all_lines[current_line-1] + non_commented_line = get_non_commented_line(line_before) + stripped_line = non_commented_line.lstrip() + return stripped_line.startswith('id:') + +def save_yaml_file(absolute_file_path: str, new_contents: str) -> None: + with open(absolute_file_path, 'w', encoding='utf-8') as file: + file.write(new_contents) + +def read_yaml_file(absolute_file_path: str) -> str: + with open(absolute_file_path, 'r', encoding='utf-8') as file: + return file.read() + +def find_yaml_files(directory_path: str) -> List[str]: + return list(Path(directory_path).glob('**/*.yaml')) + +def find_existing_ids(content: str) -> Set[str]: + pattern = r'^\s*#?\s*id:\s*(\S+)' # Matches 'id:' lines including commented lines + return set(re.findall(pattern, content, re.MULTILINE)) + +def get_non_commented_line(yaml_line: str) -> str: + pattern = re.compile(r'^\s*#\s?(.*)$') + match = pattern.match(yaml_line) + return match.group(1) if match else yaml_line + +def generate_unique_id(generated_ids: Set[str]) -> str: + new_id = generate_new_id() + while new_id in generated_ids: + new_id = generate_new_id() + return new_id + +def generate_new_id() -> str: + partial_uuid = str(uuid.uuid4()).split('-', maxsplit=1)[0] + if is_numeric(partial_uuid): # Creates issues with yaml parsing, yaml considering it as a number + return generate_new_id() + return partial_uuid + +def is_numeric(string: str) -> bool: + numeric_pattern = re.compile(r'^\d+$|^[+-]?\d+\.?\d*[eE][+-]?\d+$') + return numeric_pattern.match(string) + +if __name__ == "__main__": + main() diff --git a/src/application/Context/ApplicationContext.ts b/src/application/Context/ApplicationContext.ts index 7829737f4..81af219c9 100644 --- a/src/application/Context/ApplicationContext.ts +++ b/src/application/Context/ApplicationContext.ts @@ -1,6 +1,6 @@ import type { IApplication } from '@/domain/IApplication'; import { OperatingSystem } from '@/domain/OperatingSystem'; -import type { ICategoryCollection } from '@/domain/ICategoryCollection'; +import type { CategoryCollection } from '@/domain/Collection/CategoryCollection'; import { EventSource } from '@/infrastructure/Events/EventSource'; import { assertInRange } from '@/application/Common/Enum'; import { CategoryCollectionState } from './State/CategoryCollectionState'; @@ -12,7 +12,7 @@ type StateMachine = Map; export class ApplicationContext implements IApplicationContext { public readonly contextChanged = new EventSource(); - public collection: ICategoryCollection; + public collection: CategoryCollection; public currentOs: OperatingSystem; diff --git a/src/application/Context/State/CategoryCollectionState.ts b/src/application/Context/State/CategoryCollectionState.ts index 253a71335..fef43d061 100644 --- a/src/application/Context/State/CategoryCollectionState.ts +++ b/src/application/Context/State/CategoryCollectionState.ts @@ -1,4 +1,4 @@ -import type { ICategoryCollection } from '@/domain/ICategoryCollection'; +import type { CategoryCollection } from '@/domain/Collection/CategoryCollection'; import { OperatingSystem } from '@/domain/OperatingSystem'; import { AdaptiveFilterContext } from './Filter/AdaptiveFilterContext'; import { ApplicationCode } from './Code/ApplicationCode'; @@ -18,7 +18,7 @@ export class CategoryCollectionState implements ICategoryCollectionState { public readonly filter: FilterContext; public constructor( - public readonly collection: ICategoryCollection, + public readonly collection: CategoryCollection, selectionFactory = DefaultSelectionFactory, codeFactory = DefaultCodeFactory, filterFactory = DefaultFilterFactory, diff --git a/src/application/Context/State/Code/Event/CodeChangedEvent.ts b/src/application/Context/State/Code/Event/CodeChangedEvent.ts index b15f0a536..6549833f9 100644 --- a/src/application/Context/State/Code/Event/CodeChangedEvent.ts +++ b/src/application/Context/State/Code/Event/CodeChangedEvent.ts @@ -1,18 +1,19 @@ -import type { IScript } from '@/domain/IScript'; +import type { Script } from '@/domain/Executables/Script/Script'; import type { ICodePosition } from '@/application/Context/State/Code/Position/ICodePosition'; import type { SelectedScript } from '@/application/Context/State/Selection/Script/SelectedScript'; +import type { ExecutableKey } from '@/domain/Executables/ExecutableKey/ExecutableKey'; import type { ICodeChangedEvent } from './ICodeChangedEvent'; export class CodeChangedEvent implements ICodeChangedEvent { public readonly code: string; - public readonly addedScripts: ReadonlyArray; + public readonly addedScripts: ReadonlyArray + + diff --git a/src/presentation/components/Scripts/View/Cards/CardList.vue b/src/presentation/components/Scripts/View/Cards/CardList.vue index faeefe257..f744aec27 100644 --- a/src/presentation/components/Scripts/View/Cards/CardList.vue +++ b/src/presentation/components/Scripts/View/Cards/CardList.vue @@ -44,6 +44,7 @@ import { } from 'vue'; import { injectKey } from '@/presentation/injectionSymbols'; import SizeObserver from '@/presentation/components/Shared/SizeObserver.vue'; +import type { ExecutableId } from '@/domain/Executables/ExecutableKey/ExecutableKey'; import { hasDirective } from './NonCollapsingDirective'; import CardListItem from './CardListItem.vue'; @@ -57,12 +58,12 @@ export default defineComponent({ const width = ref(); - const categoryIds = computed( - () => currentState.value.collection.actions.map((category) => category.id), + const categoryIds = computed( + () => currentState.value.collection.actions.map((category) => category.key.executableId), ); - const activeCategoryId = ref(undefined); + const activeCategoryId = ref(undefined); - function onSelected(categoryId: number, isExpanded: boolean) { + function onSelected(categoryId: ExecutableId, isExpanded: boolean) { activeCategoryId.value = isExpanded ? categoryId : undefined; } diff --git a/src/presentation/components/Scripts/View/Cards/CardListItem.vue b/src/presentation/components/Scripts/View/Cards/CardListItem.vue index f6a99c687..6bab994f7 100644 --- a/src/presentation/components/Scripts/View/Cards/CardListItem.vue +++ b/src/presentation/components/Scripts/View/Cards/CardListItem.vue @@ -48,13 +48,14 @@