Skip to content

Commit

Permalink
Merge pull request #100 from codex-team/feat/add-tool-from-markeplace
Browse files Browse the repository at this point in the history
feat(marketplace): added ability to install/uninstall tools
  • Loading branch information
slaveeks authored Feb 24, 2024
2 parents f617aec + 4e4dc11 commit 0024d4a
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 24 deletions.
4 changes: 3 additions & 1 deletion src/application/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
},
"marketplace": {
"title": "Marketplace",
"listOfTools": "Tools"
"listOfTools": "Tools",
"uninstallTool": "Uninstall",
"installTool": "Install"
}
}
49 changes: 40 additions & 9 deletions src/application/services/useMarketplace.ts
Original file line number Diff line number Diff line change
@@ -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<EditorTool[]>;
tools: Ref<EditorToolWithUserBinding[]>;
}

/**
* Application service for working with the Editor Tools
*/
export default function (): UseMarketplaceComposable {
const toolsWithUserBindings = ref<EditorToolWithUserBinding[]>([]);
const availableTools = ref<EditorTool[]>([]);

/**
* 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<EditorTool[]>([]);
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,
};
}
21 changes: 18 additions & 3 deletions src/application/services/useUserSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ interface UseUserSettingsComposableState {
/**
* Add tool to the user settings
*/
addTool(id: string): void;
addTool(id: string): Promise<void>;

/**
* Remove tool from the user settings
*/
removeTool(id: string): Promise<void>;
}

/**
Expand All @@ -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<void> {
await userService.addTool(id);
}

/**
* Remove tool from the user settings
*
* @param id - Tool identifier
*/
async function removeTool(id: string): Promise<void> {
await userService.removeTool(id);
}

return {
addTool,
removeTool,
};
}
10 changes: 10 additions & 0 deletions src/domain/entities/EditorTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 0 additions & 2 deletions src/domain/marketplace.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 9 additions & 1 deletion src/domain/user.repository.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void>;

/**
* Removes a tool from the user (marketplace mock)
*
* @param id - tool id
*/
removeTool: (id: string) => Promise<void>;
}
13 changes: 11 additions & 2 deletions src/domain/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
return await this.repository.addTool(id);
}

/**
* Removes a tool from the user
*
* @param id - tool id
*/
public async removeTool(id: string): Promise<void> {
return await this.repository.removeTool(id);
}
}
18 changes: 18 additions & 0 deletions src/infrastructure/storage/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,22 @@ export class UserStore extends SubscribableStore<UserStoreData> {
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);
}
}
19 changes: 16 additions & 3 deletions src/infrastructure/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,28 @@ export default class UserRepository extends Repository<UserStore, UserStoreData>
}

/**
* Adds a tool to the user (marketplace mock)
* Adds a tool to the user
*
* @param id - tool id
*/
public async addTool(id: string): Promise<void> {
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<void> {
const res = await this.transport.delete<{ removedId: EditorTool['id'] }>('/user/editor-tools', {
toolId: id,
});

this.store.removeEditorTool(res.removedId);
}
}
45 changes: 45 additions & 0 deletions src/presentation/components/marketplace/EditorToolElement.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<li>
<div class="marketplace__tool">
{{ tool.title }}
<Button
v-if="canBeUninstalled"
:disabled="tool.isDefault"
:text="t('marketplace.uninstallTool')"
@click="removeTool(tool.id)"
/>
<Button
v-if="canBeInstalled"
:text="t('marketplace.installTool')"
type="transparent"
@click="addTool(tool.id)"
/>
</div>
</li>
</template>

<script setup lang="ts">
import { EditorToolWithUserBinding } from '@/domain/entities/EditorTool';
import { useUserSettings } from '@/application/services/useUserSettings';
import { useI18n } from 'vue-i18n';
import { computed } from 'vue';
import Button from '../button/Button.vue';
const { addTool, removeTool } = useUserSettings();
const { t } = useI18n();
const props = defineProps<{
tool: EditorToolWithUserBinding;
}>();
const canBeUninstalled = computed(() => !props.tool.isDefault && props.tool.isInstalled);
const canBeInstalled = computed(() => !props.tool.isDefault && !props.tool.isInstalled);
</script>

<style scoped lang="postcss">
.marketplace__tool {
display: flex;
align-items: center;
gap: var(--spacing-very-x);
}
</style>
5 changes: 2 additions & 3 deletions src/presentation/pages/Marketplace.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
v-for="tool in tools"
:key="tool.id"
>
<li>
{{ tool.title }}
</li>
<EditorToolElement :tool="tool" />
</ul>
</div>
</template>

<script setup lang="ts">
import useMarketplace from '@/application/services/useMarketplace';
import EditorToolElement from '../components/marketplace/EditorToolElement.vue';
const { tools } = useMarketplace();
</script>
Expand Down

0 comments on commit 0024d4a

Please sign in to comment.