diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7fe7400..a5c6544 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,37 +12,39 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Set up Node.js 22 - uses: actions/setup-node@v4 - with: - node-version: 22.x + - name: Set up Node.js 22 + uses: actions/setup-node@v4 + with: + node-version: 22.x - - name: Install dependencies - run: npm install + - name: Install dependencies + run: npm install - - name: Run Unit Tests with Coverage - run: npx vitest run --coverage + - name: Run Unit Tests with Coverage + run: npx vitest run --coverage - - name: Analyze with SonarQube - uses: SonarSource/sonarqube-scan-action@v5 - env: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: Analyze with SonarQube + uses: SonarSource/sonarqube-scan-action@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} e2e: needs: [unit-and-component-tests] runs-on: windows-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Node.js 22 - uses: actions/setup-node@v4 - with: - node-version: '22.x' - - - name: Run E2E tests with WebdriverIO - run: npm run test:e2e -- --run \ No newline at end of file + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js 22 + uses: actions/setup-node@v4 + with: + node-version: "22.x" + + - name: Run E2E tests with WebdriverIO + env: + ENABLE_WDIO: true + run: npm run test:e2e diff --git a/.gitignore b/.gitignore index 8296128..a42c89e 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,6 @@ typings/ # Electron-Forge out/ + +# E2E tests Workspaces +test/e2e/resources/**/mock-* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ac69347 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 RaΓΊl Mera Soto + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 1274c40..dfa0abe 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,149 @@ -[](https://sonarcloud.io/summary/new_code?id=Raulms29_electron-forge-template) -### Warning π§π§ -You will need [Node.js](https://nodejs.org/en) and [npm](https://www.npmjs.com/) to be able to work with and run this project. -## What are we using? -This project is just a template. It's almost empty and contains the minimum amount of dependencies to work with the following technologies. -- [Vue.js](https://vuejs.org/) -- [WebdriverIO](https://webdriver.io/) -- [Electron Forge](https://www.electronforge.io/) -- [Vite](https://vite.dev/) -- [TypeScript](https://www.typescriptlang.org/) -- [Node.js](https://nodejs.org/en) with Node Package Manager ([npm](https://www.npmjs.com/)) -- [Vitest](https://vitest.dev/) -## Project Setup π οΈ -Clone this repo. -``` -git clone https://github.com/Raulms29/electron-forge-template.git -``` -Then access the created folder and run the following command: -``` -npm run build +
+
+
+
+
+
+A cross-platform desktop note-taking application for organizing your thoughts and projects.
+Developed as a Bachelor's Thesis project at the University of Oviedo.
+
+Built with Electron, Vue 3, and TypeScript for Windows, macOS, and Linux. +
+ +--- + ++ Quick Start Guide β’ + Running the Application β’ + Testing β’ + Scripts β’ + Project Structure +
+ +--- + +## π₯ Quick Start Guide + +Clone the repository: +```bash +git clone https://github.com/Raulms29/Slate-Note-App.git +cd Slate-Note-App ``` -This will download the necessary dependencies, compile the project and create the resources needed for the installer in the `out` folder. The installer will be located at `out/make`. -Once the build is done, to test the project without an installation use: + +Then install the dependencies: +```bash +npm ci ``` -npm start + +## βΆοΈ Running the Application + +**Development Mode** + +Start the application in development mode with hot-reload: +```bash +npm run dev ``` -Try the unit testing with: + +**Build & Package** + +Create production builds and installers: +```bash +npm run build ``` + +This will: +- Compile the project and package the application +- Create the installer in the `out/make` directory + +## π§ͺ Testing + +**Running Tests** + +Run all unit tests: +```bash npm run test ``` -Or the component testing with: -``` -npm run test:component + +Run end-to-end tests: +```bash +npm run test:e2e ``` -Try the e2e testing with: + +Generate coverage report: +```bash +npm run test:coverage ``` -npm run test:e2e + +Coverage report will be generated in the `coverage` folder. + +**Environment Variables** + +To enable E2E testing, create a `.env` file in the root directory: +```env +ENABLE_WDIO=false # Set to 'true' to enable WebDriver integration for E2E testing ``` -Based on another template by [AngusLin10](https://github.com/AngusLin10), which can be found [here](https://github.com/AngusLin10/electron-forge-vite-ts-vue/) + +## π Scripts + +| Script | Description | +|--------|-------------| +| `npm run dev` | Start development server | +| `npm run build` | Build production application | +| `npm run package` | Package application (no installer) | +| `npm run test` | Run all unit tests | +| `npm run test:e2e` | Run end-to-end tests | +| `npm run test:coverage` | Generate coverage report | +| `npm run clean` | Remove build artifacts | +| `npm run lint` | Lint TypeScript files | + + +## π Project Structure +``` +βββ src/ +β βββ main.ts # Electron main process +β βββ preload.ts # Preload script for IPC +β βββ renderer.ts # Vue app entry point +β βββ business/ # Business logic layer +β β βββ domain/ # Domain models (Note, Workspace, Settings) +β β βββ service/ # Services (NoteService, WorkspaceService, etc.) +β βββ components/ # Vue components +β β βββ editor/ # Editor components and extensions +β β βββ generic/ # Reusable UI components +β β βββ sidebar/ # Sidebar navigation +β β βββ workspace/ # Workspace management +β βββ persistence/ # Data persistence layer +β β βββ repository/ # Repository implementations +β βββ router/ # Vue Router configuration +β βββ stores/ # Pinia state management +β βββ styles/ # Global styles and themes +β βββ utils/ # Utility functions and IPC handlers +β βββ views/ # Main application views +βββ test/ # Test suites +β βββ unit/ # Unit tests +β βββ components/ # Component tests +β βββ e2e/ # End-to-end tests +βββ forge.config.ts # Electron Forge configuration +βββ vite.*.config.ts # Vite configuration files +``` \ No newline at end of file diff --git a/components.d.ts b/components.d.ts index 58f6a08..979f1bd 100644 --- a/components.d.ts +++ b/components.d.ts @@ -10,6 +10,7 @@ declare module 'vue' { export interface GlobalComponents { AddLinkDialog: typeof import('./src/components/editor/bubble-menu/AddLinkDialog.vue')['default'] BubbleMenu: typeof import('./src/components/editor/bubble-menu/BubbleMenu.vue')['default'] + ChildrenOptions: typeof import('./src/components/editor/note-children/ChildrenOptions.vue')['default'] Editor: typeof import('./src/components/editor/Editor.vue')['default'] EditorOptions: typeof import('./src/components/editor/EditorOptions.vue')['default'] EditorView: typeof import('./src/components/editor/EditorView.vue')['default'] @@ -17,15 +18,21 @@ declare module 'vue' { GenericButton: typeof import('./src/components/generic/GenericButton.vue')['default'] GenericDialog: typeof import('./src/components/generic/GenericDialog.vue')['default'] GenericErrorMessage: typeof import('./src/components/generic/GenericErrorMessage.vue')['default'] + GenericSwitch: typeof import('./src/components/generic/switch/GenericSwitch.vue')['default'] LoadingOverlay: typeof import('./src/components/loading/LoadingOverlay.vue')['default'] NewWorkspaceCard: typeof import('./src/components/workspace/NewWorkspaceCard.vue')['default'] + NoteChildren: typeof import('./src/components/editor/note-children/NoteChildren.vue')['default'] + NoteChildrenBig: typeof import('./src/components/editor/note-children/NoteChildrenBig.vue')['default'] + NoteChildrenSmall: typeof import('./src/components/editor/note-children/NoteChildrenSmall.vue')['default'] RemoveDialog: typeof import('./src/components/workspace/dialog/RemoveDialog.vue')['default'] RenameDialog: typeof import('./src/components/workspace/dialog/RenameDialog.vue')['default'] RenameErrorMessage: typeof import('./src/components/editor/error/RenameErrorMessage.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + Settings: typeof import('./src/components/settings/Settings.vue')['default'] Sidebar: typeof import('./src/components/sidebar/Sidebar.vue')['default'] SidebarButtons: typeof import('./src/components/sidebar/SidebarButtons.vue')['default'] + SidebarSettings: typeof import('./src/components/sidebar/SidebarSettings.vue')['default'] Spinner: typeof import('./src/components/loading/Spinner.vue')['default'] WorkspaceCard: typeof import('./src/components/workspace/WorkspaceCard.vue')['default'] WorkspaceMenuItem: typeof import('./src/components/workspace/WorkspaceMenuItem.vue')['default'] diff --git a/docs/resources/images/app.png b/docs/resources/images/app.png new file mode 100644 index 0000000..ccb95d5 Binary files /dev/null and b/docs/resources/images/app.png differ diff --git a/docs/resources/images/slate-title.svg b/docs/resources/images/slate-title.svg new file mode 100644 index 0000000..309018e --- /dev/null +++ b/docs/resources/images/slate-title.svg @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/forge.config.ts b/forge.config.ts index 1e4dae6..579ffb3 100644 --- a/forge.config.ts +++ b/forge.config.ts @@ -1,5 +1,6 @@ import type { ForgeConfig } from '@electron-forge/shared-types'; import { MakerSquirrel } from '@electron-forge/maker-squirrel'; +import { MakerDMG } from '@electron-forge/maker-dmg'; import { MakerZIP } from '@electron-forge/maker-zip'; import { MakerDeb } from '@electron-forge/maker-deb'; import { MakerRpm } from '@electron-forge/maker-rpm'; @@ -10,10 +11,16 @@ import { FuseV1Options, FuseVersion } from '@electron/fuses'; const config: ForgeConfig = { packagerConfig: { asar: true, - executableName: 'project-template', + executableName: 'slate', + icon: './src/assets/app-icon/icon', // Electron Forge adds extension per platform }, rebuildConfig: {}, - makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})], + makers: [ + new MakerSquirrel({ setupIcon: './src/assets/app-icon/icon.ico', }), + new MakerDMG({ icon: './src/assets/app-icon/icon.icns', }), + new MakerZIP({}, ['darwin']), + new MakerRpm({}), + new MakerDeb({ options: { icon: './src/assets/app-icon/icon.png', }, })], plugins: [ new VitePlugin({ // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc. diff --git a/index.html b/index.html index d0ced27..7501a04 100644 --- a/index.html +++ b/index.html @@ -1,12 +1,15 @@ - - - -