Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into refactor/editor-to-services
Browse files Browse the repository at this point in the history
  • Loading branch information
ksenia_subbotina committed Feb 19, 2024
2 parents ba231c9 + 87f6958 commit 54592e4
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/eslint-check.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run eslint check
name: ESLint

on:
push:
Expand Down
22 changes: 14 additions & 8 deletions .github/workflows/send-test-results.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ on:

jobs:
send-message:
permissions: read-all
permissions:
actions: write
runs-on: ubuntu-22.04
env:
API_URL: "https://api.github.com/repos/${{ github.repository }}/actions/runs"
steps:
- name: Set commit_sha to pull request head sha
if: ${{ github.event_name == 'pull_request' }}
Expand All @@ -33,20 +36,23 @@ jobs:
# Find results of the actions with the same SHA as this action via github api and set them to env variable
- name: Get actions results
run: |
url="https://api.github.com/repos/${{ github.repository }}/actions/runs"
echo 'ACTIONS_RESULTS<<0x0a' >> $GITHUB_ENV
curl -s -X GET -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}"\
"$url" | jq -r '.workflow_runs[] | select(((.head_sha=="${{ env.COMMIT_SHA }}") and (.id != ${{ github.run_id }}))
"$API_URL" | jq -r '.workflow_runs[] | select(((.head_sha=="${{ env.COMMIT_SHA }}") and (.id != ${{ github.run_id }}))
and ((.conclusion == "success") or (.conclusion == "failure"))) | "\(.conclusion) [\(.name)](\(.html_url))" |
gsub("success"; "✅") | gsub("failure"; "❌")' >> $GITHUB_ENV
echo '0x0a' >> $GITHUB_ENV
# Skip if all checks were skipped/cancelled
- name: Skip this workflow if none of the results have conclusion "success" or "failure"
uses: styfle/[email protected]
# Stop if all checks were skipped/cancelled
- name: Stop this workflow if none of the results have conclusion "success" or "failure"
if: ${{ env.ACTIONS_RESULTS == '' }}
with:
workflow_id: ${{ github.run_id }}
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
${{ env.API_URL }}/${{ github.run_id }}/cancel
- name: Send a message
uses: codex-team/action-codexbot-notify@v1
Expand Down
173 changes: 95 additions & 78 deletions src/application/services/useEditor.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { onBeforeUnmount, onMounted, ref, watch, type Ref } from 'vue';
import Editor, { type OutputData, type API } from '@editorjs/editorjs';
import type EditorTool from '@/domain/entities/EditorTool';
// @ts-expect-error: we need to rewrite plugins to TS to get their types
import Header from '@editorjs/header';
import { useAppState } from './useAppState';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type GlobalEditorTool = any;

/**
* Interface describing hook props
*/
interface EditorProps {
/**
* Content displayed in Editor
*/
content?: OutputData;

/**
* Allow edit content in Editor
*/
isReadOnly?: boolean;

/**
* Handler for every content change in Editor
*/
onChange: (api: API) => void
/**
* Content displayed in Editor
*/
content?: OutputData;

/**
* Allow edit content in Editor
*/
isReadOnly?: boolean;

/**
* Handler for every content change in Editor
*/
onChange: (api: API) => void;
}

/**
* Load one tool at a time
* Add promise which is rejected after loading is complete
*
* @param src - source path to tool
*/
Expand All @@ -42,14 +45,60 @@ function loadScript(src: string): Promise<Event> {
}

/**
* Application service for working with Editor
* Load user editor tools
*
* @param userEditorTools User editor tools
*/
export function useEditor({ content, isReadOnly, onChange } : EditorProps): void {
function loadUserTools(
userEditorTools: Ref<Array<EditorTool>>
): Promise<Array<PromiseSettledResult<Promise<Event> | undefined>>> {
return Promise.allSettled(

Check failure on line 55 in src/application/services/useEditor.ts

View workflow job for this annotation

GitHub Actions / Build notes.web

Type 'Promise<PromiseSettledResult<Event | undefined>[]>' is not assignable to type 'Promise<PromiseSettledResult<Promise<Event> | undefined>[]>'.
userEditorTools.value.map((spec: EditorTool) => {
if (spec.source.cdn === undefined || spec.source.cdn === '') {
return undefined;
}

return loadScript(spec.source.cdn);
})
);
}

/**
* Create Editor.js tools settings from editor tools
*
* @param userEditorTools User editor tools
*/
function createToolsSettings(
userEditorTools: Ref<Array<EditorTool>>
): Record<string, GlobalEditorTool> {
return userEditorTools.value.reduce((acc, spec: EditorTool) => {
// @ts-expect-error: we need to rewrite plugins to TS to get their types
const windowPlugin = window[spec.exportName];

return {
...acc,
[spec.title]: windowPlugin,
};
}, {});
}

/**
* Application service for working with Editor
*/
export function useEditor({
content,
isReadOnly,
onChange,
}: EditorProps): void {
/**
* Editor.js instance
*/
const editor = ref<Editor | undefined>(undefined);
let editor: Editor | undefined;

/**
* Editor content instance
*/
const refContent = ref<OutputData | undefined>(content);

/**
* User notes tools
Expand All @@ -59,30 +108,13 @@ export function useEditor({ content, isReadOnly, onChange } : EditorProps): void
/**
* Function for loading and adding tools to Editor
*/
const mountEditorOnce = async (): Promise<void> => {
Promise.allSettled(userEditorTools.value.map((spec: EditorTool) => {
if (spec.source.cdn === undefined || spec.source.cdn === "") {
return undefined;
}

return loadScript(spec.source.cdn);
})).then(async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const loadedTools: {[key: string]: any } = userEditorTools.value.reduce(
(acc, spec: EditorTool) => {
// @ts-expect-error: we need to rewrite plugins to TS to get their types
const windowPlugin = window[spec.exportName];

return {
...acc,
[spec.title]: windowPlugin,
};
},
{}
);
const mountEditor = async (): Promise<void> => {
try {
await loadUserTools(userEditorTools);

const loadedTools = createToolsSettings(userEditorTools);

const editorInstance = new Editor({
editor = new Editor({
/**
* Block Tools
*/
Expand All @@ -93,72 +125,57 @@ export function useEditor({ content, isReadOnly, onChange } : EditorProps): void
placeholder: 'Title...',
},
},
// image: Image,
// code: CodeTool,
// list: List,
// delimiter: Delimiter,
// table: Table,
// warning: Warning,
// checklist: Checklist,
// linkTool: LinkTool,
// raw: RawTool,
// embed: Embed,

// /**
// * Inline Tools
// */
// inlineCode: InlineCode,
// marker: Marker,
...loadedTools,
},
data: content,
data: refContent.value,
onChange,
readOnly: isReadOnly,
});

await editorInstance.isReady;

editor.value = editorInstance;
})
.catch(console.error);
await editor.isReady;
} catch (error) {
console.error(error);
}
};

/**
* Update editor instance when user tools was changed
*/
watch(userEditorTools, mountEditorOnce);
watch(userEditorTools, mountEditor);

/**
* Set editor instance after first mount
*/
onMounted(() => {
if (userEditorTools.value.length > 0) {
mountEditorOnce().catch(console.info);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
mountEditor();
}
});

/**
* Add content to editor
*/
// eslint-disable-next-line @typescript-eslint/no-shadow
watch(() => content, (content) => {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (content === undefined) {
editor.value?.clear();
watch(
() => refContent,
(watchedRef) => {
const watchedContent = watchedRef.value;

return;
}
if (watchedContent === undefined) {
editor?.clear();

return;
}

if (editor.value) {
editor.value.render(content).catch(console.error);
editor?.render(watchedContent).catch(console.error);
}
});
);

/**
* Destroy editor instance after unmount
*/
onBeforeUnmount(() => {
editor.value?.destroy();
editor.value = undefined;
editor?.destroy();
editor = undefined;
});
}
}
13 changes: 7 additions & 6 deletions src/presentation/components/editor/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ import { useEditor } from '@/application/services/useEditor';
* Define the props for the component
*/
const props = defineProps<{
content?: OutputData,
readOnly?: boolean,
content?: OutputData;
readOnly?: boolean;
}>();
const emit = defineEmits<{
'change': [data: OutputData],
change: [data: OutputData];
}>();
/**
* Attribute containing is-empty state.
* It is updated on every change of the editor
Expand Down Expand Up @@ -74,9 +73,11 @@ async function onChange(api: API): Promise<void> {
emit('change', data);
}
useEditor({ content: props.content,
useEditor({
content: props.content,
isReadOnly: props.readOnly,
onChange });
onChange,
});
defineExpose({
/**
Expand Down

0 comments on commit 54592e4

Please sign in to comment.