diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..214388f --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not dead diff --git a/.dockerignore b/.dockerignore index 461e021..6d01701 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,5 +2,4 @@ assets/* dockerfile *.md .git -screenshot.png -node_modules +screenshot.png \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..2ac7400 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,15 @@ +module.exports = { + root: true, + env: { + node: true, + }, + extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"], + parserOptions: { + parser: "babel-eslint", + }, + rules: { + "no-console": "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", + "vue/require-v-for-key": "off", + }, +}; diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index d2ccc03..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,6 +0,0 @@ -# These are supported funding model platforms - -# These are supported funding model platforms - -github: [bastienwirtz] -buy_me_a_coffee: bastien diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index e9fd38a..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Logs & errors** -Please include any usefull information: -- Errors in your browser console (`ctrl+shift+i` or `F12`) -- If applicable, your docker container logs. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Configuration** -If applicable, copy related homer yaml configuration here. -```yml - -``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0bb193d..d32ca78 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,11 +9,10 @@ Fixes # (issue) - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Refactoring ## Checklist: -- [ ] I've read & comply with the [contributing guidelines](https://github.com/bastienwirtz/homer/blob/main/CONTRIBUTING.md) -- [ ] I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers. -- [ ] I have made corresponding changes to the documentation (`README.md`). -- [ ] I've checked my modifications for any breaking changes, especially in the `config.yml` file +- [ ] I read & comply with the [contributing guidelines](https://github.com/bastienwirtz/homer/blob/master/CONTRIBUTING.md) +- [ ] I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers. +- [ ] I have made corresponding changes the documentation (README.md). +- [ ] I've check my modifications for any breaking change, especially in the `config.yml` file diff --git a/.github/release.yml b/.github/release.yml deleted file mode 100644 index 906d71f..0000000 --- a/.github/release.yml +++ /dev/null @@ -1,8 +0,0 @@ -changelog: - exclude: - authors: - - dependabot - categories: - - title: Main changes - labels: - - "*" \ No newline at end of file diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml deleted file mode 100644 index 4b67502..0000000 --- a/.github/workflows/dockerhub.yml +++ /dev/null @@ -1,48 +0,0 @@ -# Build & publish docker images -name: Dockerhub - -on: - push: - tags: [v*] - -jobs: - dockerhub: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Login to GHCR - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ github.token }} - - - name: Build and push - uses: docker/build-push-action@v6 - with: - push: true - tags: | - b4bz/homer:latest - b4bz/homer:${{ github.ref_name }} - ghcr.io/${{ github.repository }}:latest - ghcr.io/${{ github.repository }}:${{ github.ref_name }} - platforms: linux/amd64,linux/arm/v7,linux/arm/v6,linux/arm64 - build-args: | - VERSION_TAG=${{ github.ref_name }} diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml deleted file mode 100644 index 4f79069..0000000 --- a/.github/workflows/integration.yml +++ /dev/null @@ -1,34 +0,0 @@ -# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions - -name: Integration - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: pnpm setup - uses: pnpm/action-setup@v4 - - - name: Node.js setup - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'pnpm' - - - name: install dependencies - run: pnpm install --frozen-lockfile - - - name: Check code style & potentential issues - run: pnpm lint diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..fa346b3 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,40 @@ +# Publish pre-build release +name: Upload Release Asset + +on: + push: + branches: [master] + +jobs: + build: + name: Upload Release Asset + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build project + run: | + yarn install + yarn build + - name: Create artifact + working-directory: "dist" + run: zip -r ../homer.zip ./* + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.run_id }} + release_name: Release ${{ github.run_id }} + draft: false + prerelease: false + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./homer.zip + asset_name: homer.zip + asset_content_type: application/zip diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 9549d4d..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,43 +0,0 @@ -# Publish pre-build release -name: Create Github release - -on: - push: - tags: [v*] - -jobs: - build: - name: Upload Release Asset - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: pnpm setup - uses: pnpm/action-setup@v4 - - - name: Node.js setup - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: 'pnpm' - - - name: Build project - run: | - pnpm install --frozen-lockfile - pnpm build - - - name: Create artifact - working-directory: "dist" - run: zip -r ../homer.zip ./* - - - name: Create Release - id: create_release - uses: softprops/action-gh-release@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - generate_release_notes: true - files: | - homer.zip \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6eb9005..26547c2 100644 --- a/.gitignore +++ b/.gitignore @@ -21,10 +21,4 @@ yarn-error.log* *.sw? # App configuration -config.yml - -.drone.yml - -# Specific Agent file -CLAUDE.md -GEMINI.md +public/config.yml diff --git a/.jsconfig.json b/.jsconfig.json deleted file mode 100644 index 7c82acb..0000000 --- a/.jsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "paths": { - "@/*": ["./src/*"] - } - }, - "exclude": ["node_modules", "dist"] - } \ No newline at end of file diff --git a/.schema/config-schema.json b/.schema/config-schema.json deleted file mode 100644 index f751668..0000000 --- a/.schema/config-schema.json +++ /dev/null @@ -1,359 +0,0 @@ -{ - "$id": "https://raw.githubusercontent.com/bastienwirtz/homer/main/.schema/config-schema.json", - "$schema": "http://json-schema.org/draft-07/schema", - "description": "https://github.com/bastienwirtz/homer/blob/main/docs/configuration.md", - "examples": [], - "title": "Homer Dashboard configuration", - "type": "object", - "definitions": { - "Colors": { - "type": "object", - "additionalProperties": false, - "properties": { - "light": { - "$ref": "#/definitions/ColorSet" - }, - "dark": { - "$ref": "#/definitions/ColorSet" - } - }, - "title": "Colors" - }, - "ColorSet": { - "type": "object", - "additionalProperties": false, - "properties": { - "highlight-primary": { - "type": "string" - }, - "highlight-secondary": { - "type": "string" - }, - "highlight-hover": { - "type": "string" - }, - "background": { - "type": "string" - }, - "card-background": { - "type": "string" - }, - "text": { - "type": "string" - }, - "text-header": { - "type": "string" - }, - "text-title": { - "type": "string" - }, - "text-subtitle": { - "type": "string" - }, - "card-shadow": { - "type": "string" - }, - "link": { - "type": "string" - }, - "link-hover": { - "type": "string" - }, - "background-image": { - "type": "string" - } - } - }, - "Defaults": { - "type": "object", - "additionalProperties": false, - "properties": { - "layout": { - "enum": [ - "columns", - "list" - ], - "description": "Layout of the dashboard, either 'columns' or 'list'" - }, - "colorTheme": { - "enum": [ - "auto", - "light", - "dark" - ], - "description": "One of 'auto', 'light', or 'dark'" - } - }, - "title": "Defaults" - }, - "Hotkey": { - "type": "object", - "additionalProperties": false, - "properties": { - "search": { - "type": "string", - "description": "hotkey for search, e.g. Shift" - } - }, - "required": [ - "search" - ] - }, - "Link": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "Name as seen in the navbar" - }, - "icon": { - "type": "string", - "description": "Fontawesome icon" - }, - "url": { - "type": "string", - "description": "Url of the link. When #filename is used, it is a link to another homer page, while 'filename' is the name of the config file" - }, - "target": { - "type": "string", - "description": "html tag target attribute like _blank for a new page" - } - }, - "required": [ - "url" - ], - "title": "Link" - }, - "Message": { - "type": "object", - "additionalProperties": false, - "properties": { - "url": { - "type": "string", - "format": "uri" - }, - "mapping": { - "$ref": "#/definitions/Mapping", - "description": "Mapping for the content loaded from the URL" - }, - "refreshInterval": { - "type": "integer", - "description": "The refresh interval in milliseconds for reloading the message url" - }, - "style": { - "type": "string", - "description": "See https://bulma.io/documentation/components/message/#colors for styling options" - }, - "title": { - "type": "string", - "description": "Title of the message box" - }, - "icon": { - "type": "string", - "description": "Fontawesome icon for the message box" - }, - "content": { - "type": "string", - "description": "HTML content for the message box" - } - }, - "title": "Messagebox" - }, - "Mapping": { - "type": "object", - "additionalProperties": true, - "title": "Mapping" - }, - "Proxy": { - "type": "object", - "additionalProperties": false, - "properties": { - "useCredentials": { - "type": "boolean", - "description": "# send cookies & authorization headers when fetching service specific data. Set to `true` if you use an authentication proxy. Can be overrided on service level. " - }, - "headers": { - "$ref": "#/definitions/Headers", - "description": "send custom headers when fetching service specific data. Can also be set on a service level." - } - }, - "title": "Proxy" - }, - "Headers": { - "type": "object", - "additionalProperties": true, - "title": "Headers" - }, - "Service": { - "type": "object", - "additionalProperties": false, - "properties": { - "name": { - "type": "string", - "description": "Service name" - }, - "icon": { - "type": "string", - "description": "Fontawesome icon for the service" - }, - "logo": { - "type": "string", - "description": "A path to an image can also be provided. Note that icon take precedence if both icon and logo are set." - }, - "class": { - "type": "string", - "description": "Optional css class to add on the service group. Example 'highlight-purple'" - }, - "items": { - "type": "array", - "items": { - "$ref": "#/definitions/Item" - } - } - }, - "required": [ - "items" - ], - "title": "Service" - }, - "Item": { - "type": "object", - "additionalProperties": true, - "properties": { - "name": { - "type": "string" - }, - "logo": { - "type": "string", - "description": "Path to a logo. Alternatively a fa icon can be provided" - }, - "icon": { - "type": "string", - "description": "Fontawesome icon for the item, alternative for logo" - }, - "subtitle": { - "type": "string" - }, - "tag": { - "type": "string", - "description": "Show tag" - }, - "keywords": { - "type": "string", - "description": "Optional keyword used for searching purpose" - }, - "url": { - "type": "string", - "description": "Url of this item" - }, - "target": { - "type": "string", - "description": "html tag target attribute like _blank for a new page" - }, - "tagstyle": { - "type": "string", - "description": "Styleclass for the tag" - }, - "type": { - "type": "string", - "description": "Optional, loads a specific component that provides extra features. MUST MATCH a file name (without file extension) available in `src/components/services`" - } - }, - "title": "Item" - } - }, - "properties": { - "externalConfig": { - "type": "string", - "description": "Use external configuration file. Using this will ignore remaining config in this file externalConfig: https://example.com/server-luci/config.yaml" - }, - "title": { - "type": "string", - "description": "Title of the dashboard" - }, - "subtitle": { - "type": "string", - "description": "Subtitle of the dashboard" - }, - "documentTitle": { - "type": "string", - "description": "Title of the document. When not filled, title (and subtitle will be used)" - }, - "logo": { - "type": "string", - "description": "Path to logo image" - }, - "icon": { - "type": "string", - "description": "Dashboard icon" - }, - "header": { - "type": "boolean", - "description": "Show header, default is true" - }, - "hotkey": { - "$ref": "#/definitions/Hotkey", - "description": "Define hotkeys, for example for search" - }, - "footer": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "string" - } - ], - "description": "footer Line content. HTML is supported. Set false if you want to hide it." - }, - "columns": { - "type": "string", - "description": "'auto' or number (must be a factor of 12: 1, 2, 3, 4, 6, 12)", - "format": "integer" - }, - "connectivityCheck": { - "type": "boolean", - "description": "# whether you want to display a message when the apps are not accessible anymore (VPN disconnected for example). You should set it to true when using an authentication proxy, it also reloads the page when a redirection is detected when checking connectivity." - }, - "proxy": { - "$ref": "#/definitions/Proxy", - "description": "Optional: Proxy / hosting option" - }, - "defaults": { - "$ref": "#/definitions/Defaults" - }, - "theme": { - "type": "string", - "description": "'default' or one of the themes available in 'src/assets/themes'" - }, - "stylesheet": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Will load custom CSS files. Especially useful for custom icon sets. Entries are paths to the stylesheets" - }, - "colors": { - "$ref": "#/definitions/Colors" - }, - "message": { - "$ref": "#/definitions/Message", - "description": "Messagebox" - }, - "links": { - "description": "Links in the navigation bar", - "type": "array", - "items": { - "$ref": "#/definitions/Link" - } - }, - "services": { - "description": "Services", - "type": "array", - "items": { - "$ref": "#/definitions/Service" - } - } - } -} diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 29d7dfb..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,84 +0,0 @@ -# AGENTS Instructions - -This file provides guidance to AI Agents when working with code in this repository. - -## Development Commands - -```bash -pnpm install # Install dependencies (PNPM enforced via packageManager) -pnpm dev # Start development server on http://localhost:3000 -pnpm mock # Start mock API server for testing service integrations -pnpm build # Build for production -pnpm preview # Preview production build -pnpm lint # Run ESLint with auto-fix -``` - -## Architecture Overview - -Homer is a static Vue.js 3 PWA dashboard that loads configuration from YAML files. The architecture is service-oriented with dynamic component loading. - -### Core Application Structure - -- **Entry Point**: `src/main.js` mounts the Vue app -- **Root Component**: `src/App.vue` handles layout, configuration loading, and routing -- **Configuration System**: YAML-based with runtime merging of defaults (`src/assets/defaults.yml`) and user config (`/assets/config.yml`) -- **Service Components**: 53 specialized integrations in `src/components/services/` that extend a Generic component pattern - -### Service Integration Pattern - -All service components follow this architecture: - -- Extend `Generic.vue` using Vue slots (`