diff --git a/src/application/i18n/messages/en.json b/src/application/i18n/messages/en.json index 43c01195..4df08593 100644 --- a/src/application/i18n/messages/en.json +++ b/src/application/i18n/messages/en.json @@ -31,6 +31,8 @@ }, "marketplace": { "title": "Marketplace", - "listOfTools": "Tools" + "listOfTools": "Tools", + "uninstallTool": "Uninstall", + "installTool": "Install" } } diff --git a/src/application/services/useMarketplace.ts b/src/application/services/useMarketplace.ts index 24657cca..8c6a86ca 100644 --- a/src/application/services/useMarketplace.ts +++ b/src/application/services/useMarketplace.ts @@ -1,34 +1,65 @@ -import type EditorTool from '@/domain/entities/EditorTool'; -import { type Ref, ref, onMounted } from 'vue'; +import { type Ref, ref, watch, onMounted } from 'vue'; import { marketplaceService } from '@/domain'; +import type { EditorToolWithUserBinding } from '@/domain/entities/EditorTool'; +import { useAppState } from './useAppState'; +import type EditorTool from '@/domain/entities/EditorTool'; /** * Composable for the application state */ interface UseMarketplaceComposable { /** - * All editor tools that are used in notes creation + * List of tools with information, if they are installed by the user */ - tools: Ref; + tools: Ref; } /** * Application service for working with the Editor Tools */ export default function (): UseMarketplaceComposable { + const toolsWithUserBindings = ref([]); + const availableTools = ref([]); + /** - * All editor tools + * Create a list of tools with information, if they are installed by the user + * + * @param tools - list of all tools + * @param userTools - list of user tools */ - const tools = ref([]); + const getToolsWithUserBindings = (tools: EditorTool[], userTools: EditorTool[]): EditorToolWithUserBinding[] => { + return tools.map((tool) => { + return { + ...tool, + isInstalled: userTools.some((userTool) => userTool.id === tool.id), + }; + }); + }; /** - * Get list of all tools + * User tools */ + const { userEditorTools } = useAppState(); + onMounted(async () => { - tools.value = await marketplaceService.getAllTools(); + availableTools.value = await marketplaceService.getAllTools(); + toolsWithUserBindings.value = getToolsWithUserBindings(availableTools.value, userEditorTools.value); }); + /** + * Check if user tools are changed + */ + watch( + userEditorTools, + async (newValue) => { + toolsWithUserBindings.value = getToolsWithUserBindings(availableTools.value, newValue); + }, + { + immediate: true, + } + ); + return { - tools: tools, + tools: toolsWithUserBindings, }; } diff --git a/src/application/services/useUserSettings.ts b/src/application/services/useUserSettings.ts index 41db2ee9..031ba39c 100644 --- a/src/application/services/useUserSettings.ts +++ b/src/application/services/useUserSettings.ts @@ -7,7 +7,12 @@ interface UseUserSettingsComposableState { /** * Add tool to the user settings */ - addTool(id: string): void; + addTool(id: string): Promise; + + /** + * Remove tool from the user settings + */ + removeTool(id: string): Promise; } /** @@ -19,11 +24,21 @@ export function useUserSettings(): UseUserSettingsComposableState { * * @param id - Tool identifier */ - function addTool(id: string): void { - userService.addTool(id); + async function addTool(id: string): Promise { + await userService.addTool(id); + } + + /** + * Remove tool from the user settings + * + * @param id - Tool identifier + */ + async function removeTool(id: string): Promise { + await userService.removeTool(id); } return { addTool, + removeTool, }; } diff --git a/src/domain/entities/EditorTool.ts b/src/domain/entities/EditorTool.ts index 91d4af10..fa6a7a00 100644 --- a/src/domain/entities/EditorTool.ts +++ b/src/domain/entities/EditorTool.ts @@ -38,3 +38,13 @@ export default interface EditorTool { cdn?: string; }; } + +/** + * Editor tool with user binding + */ +export interface EditorToolWithUserBinding extends EditorTool { + /** + * Is tool included in user's editor settings + */ + isInstalled: boolean; +} diff --git a/src/domain/marketplace.service.ts b/src/domain/marketplace.service.ts index 761492aa..3c55c7f6 100644 --- a/src/domain/marketplace.service.ts +++ b/src/domain/marketplace.service.ts @@ -13,9 +13,7 @@ export default class MarketplaceService { /** * Service constructor * - * @param eventBus - Common domain event bus * @param marketplaceRepository - repository instance - * @param marketplaceRepositoryRepository */ constructor(marketplaceRepository: MarketplaceRepository) { this.repository = marketplaceRepository; diff --git a/src/domain/user.repository.interface.ts b/src/domain/user.repository.interface.ts index a248e716..026d1158 100644 --- a/src/domain/user.repository.interface.ts +++ b/src/domain/user.repository.interface.ts @@ -29,10 +29,18 @@ export default interface UserRepositoryInterface { * Returns array of editor tools */ getUserEditorTools: () => EditorTool[]; + /** * Adds a tool to the user (marketplace mock) * * @param id - tool id */ - addTool: (id: string) => void; + addTool: (id: string) => Promise; + + /** + * Removes a tool from the user (marketplace mock) + * + * @param id - tool id + */ + removeTool: (id: string) => Promise; } diff --git a/src/domain/user.service.ts b/src/domain/user.service.ts index 5839478f..5bb6d064 100644 --- a/src/domain/user.service.ts +++ b/src/domain/user.service.ts @@ -52,7 +52,16 @@ export default class UserService { * * @param id - tool id */ - public addTool(id: string): void { - this.repository.addTool(id); + public async addTool(id: string): Promise { + return await this.repository.addTool(id); + } + + /** + * Removes a tool from the user + * + * @param id - tool id + */ + public async removeTool(id: string): Promise { + return await this.repository.removeTool(id); } } diff --git a/src/infrastructure/storage/user.ts b/src/infrastructure/storage/user.ts index 02807285..2891272c 100644 --- a/src/infrastructure/storage/user.ts +++ b/src/infrastructure/storage/user.ts @@ -58,4 +58,22 @@ export class UserStore extends SubscribableStore { public setUserEditorTools(editorTools: EditorTool[]): void { this.data.editorTools = editorTools; } + + /** + * Adds a tool to the user + * + * @param editorTool - tool to add + */ + public addEditorTool(editorTool: EditorTool): void { + this.data.editorTools = [...this.data.editorTools, editorTool]; + } + + /** + * Removes a tool from the user + * + * @param id - tool id + */ + public removeEditorTool(id: EditorTool['id']): void { + this.data.editorTools = this.data.editorTools.filter((tool) => tool.id !== id); + } } diff --git a/src/infrastructure/user.repository.ts b/src/infrastructure/user.repository.ts index 724dcce6..c4296ce8 100644 --- a/src/infrastructure/user.repository.ts +++ b/src/infrastructure/user.repository.ts @@ -65,15 +65,28 @@ export default class UserRepository extends Repository } /** - * Adds a tool to the user (marketplace mock) + * Adds a tool to the user * * @param id - tool id */ public async addTool(id: string): Promise { - const response = await this.transport.post<{ toolId: string }>('/user/editor-tools', { + const res = await this.transport.post<{ addedTool: EditorTool }>('/user/editor-tools', { toolId: id, }); - console.log('Add tool response', response); + this.store.addEditorTool(res.addedTool); + } + + /** + * Removes a tool from the user + * + * @param id - tool id + */ + public async removeTool(id: string): Promise { + const res = await this.transport.delete<{ removedId: EditorTool['id'] }>('/user/editor-tools', { + toolId: id, + }); + + this.store.removeEditorTool(res.removedId); } } diff --git a/src/presentation/components/marketplace/EditorToolElement.vue b/src/presentation/components/marketplace/EditorToolElement.vue new file mode 100644 index 00000000..e2a9538c --- /dev/null +++ b/src/presentation/components/marketplace/EditorToolElement.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/presentation/pages/Marketplace.vue b/src/presentation/pages/Marketplace.vue index a3671705..f5cbeb68 100644 --- a/src/presentation/pages/Marketplace.vue +++ b/src/presentation/pages/Marketplace.vue @@ -6,15 +6,14 @@ v-for="tool in tools" :key="tool.id" > -
  • - {{ tool.title }} -
  • +