From a9580a0dd0b1bd67bb7e2278d46c3c3bebb41506 Mon Sep 17 00:00:00 2001 From: Marc-Lorenz <169900493+Marc-Lorenz@users.noreply.github.com> Date: Fri, 23 Aug 2024 11:15:30 +0200 Subject: [PATCH 01/25] add navbar and move components --- components.d.ts | 16 ++- e2e/vue.spec.js | 40 ++++++++ e2e/vue.spec.ts | 2 +- index.html | 14 --- src/App.vue | 12 ++- src/components/Main/SidebarContainer.vue | 21 ---- src/components/Main/TopNavbar.vue | 31 ++++++ .../Main/__tests__/SidebarCointainer.spec.ts | 15 --- src/components/MenuItems/ButtonWithIcon.vue | 6 +- .../Modals/WebserviceSelectModal.vue | 94 ++++++++++++++++++ src/components/Navbar/AboutSection.vue | 48 +++++++++ src/components/Navbar/EditButtons.vue | 54 ++++++++++ .../{Sidebar => Navbar}/LoadSaveActions.vue | 62 +++++++----- src/components/Sidebar/AboutSection.vue | 32 ------ src/components/Sidebar/EditButtons.vue | 98 ------------------- src/components/Sidebar/FeatureDragBar.vue | 53 ++++++++++ src/components/Sidebar/FeatureSelector.vue | 3 +- src/components/Sidebar/ModelSelector.vue | 69 +------------ src/components/Sidebar/ViewOptions.vue | 26 +++-- src/editor2d.ts | 1 + src/view/checkbox.ts | 32 ------ src/view/slider.ts | 51 ---------- 22 files changed, 403 insertions(+), 377 deletions(-) create mode 100644 e2e/vue.spec.js create mode 100644 src/components/Main/TopNavbar.vue create mode 100644 src/components/Modals/WebserviceSelectModal.vue create mode 100644 src/components/Navbar/AboutSection.vue create mode 100644 src/components/Navbar/EditButtons.vue rename src/components/{Sidebar => Navbar}/LoadSaveActions.vue (84%) delete mode 100644 src/components/Sidebar/AboutSection.vue delete mode 100644 src/components/Sidebar/EditButtons.vue create mode 100644 src/components/Sidebar/FeatureDragBar.vue delete mode 100644 src/view/checkbox.ts delete mode 100644 src/view/slider.ts diff --git a/components.d.ts b/components.d.ts index 2733c04..a5b662b 100644 --- a/components.d.ts +++ b/components.d.ts @@ -7,17 +7,27 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { - AboutSection: typeof import('./src/components/Sidebar/AboutSection.vue')['default'] + AboutSection: typeof import('./src/components/Navbar/AboutSection.vue')['default'] + BButton: typeof import('bootstrap-vue-next')['BButton'] + BDropdownDivider: typeof import('bootstrap-vue-next')['BDropdownDivider'] + BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem'] BModal: typeof import('bootstrap-vue-next')['BModal'] + BNavbarBrand: typeof import('bootstrap-vue-next')['BNavbarBrand'] + BNavbarNav: typeof import('bootstrap-vue-next')['BNavbarNav'] + BNavItem: typeof import('bootstrap-vue-next')['BNavItem'] + BNavItemDropdown: typeof import('bootstrap-vue-next')['BNavItemDropdown'] ButtonWithIcon: typeof import('./src/components/MenuItems/ButtonWithIcon.vue')['default'] CentralCanvas: typeof import('./src/components/Main/CentralCanvas.vue')['default'] - EditButtons: typeof import('./src/components/Sidebar/EditButtons.vue')['default'] + EditButtons: typeof import('./src/components/Navbar/EditButtons.vue')['default'] + FeatureDragBar: typeof import('./src/components/Sidebar/FeatureDragBar.vue')['default'] FeatureSelector: typeof import('./src/components/Sidebar/FeatureSelector.vue')['default'] - LoadSaveActions: typeof import('./src/components/Sidebar/LoadSaveActions.vue')['default'] + LoadSaveActions: typeof import('./src/components/Navbar/LoadSaveActions.vue')['default'] ModelSelector: typeof import('./src/components/Sidebar/ModelSelector.vue')['default'] SidebarContainer: typeof import('./src/components/Main/SidebarContainer.vue')['default'] ThumbnailContainer: typeof import('./src/components/ThumbnailContainer.vue')['default'] ThumbnailGallery: typeof import('./src/components/Main/ThumbnailGallery.vue')['default'] + TopNavbar: typeof import('./src/components/Main/TopNavbar.vue')['default'] ViewOptions: typeof import('./src/components/Sidebar/ViewOptions.vue')['default'] + WebserviceSelectModal: typeof import('./src/components/Modals/WebserviceSelectModal.vue')['default'] } } diff --git a/e2e/vue.spec.js b/e2e/vue.spec.js new file mode 100644 index 0000000..90c1ae4 --- /dev/null +++ b/e2e/vue.spec.js @@ -0,0 +1,40 @@ +import { test, expect } from '@playwright/test'; +// See here how to get started: +// https://playwright.dev/docs/intro +test('visits the app root url', async ({ page }) => { + await page.goto('/'); + await expect(page.locator('h3')).toHaveText('Face Mesh Editor'); +}); +test('Check Element Relative Width to Container', async ({ page }) => { + await page.goto('/'); + const containerHandle = page.locator('#app'); + const sidebar = page.locator('#sidebar'); + const canvas = page.locator('#canvas-div'); + const thumbnails = page.locator('#thumbnail-gallery'); + const containerBox = await containerHandle.boundingBox(); + expect(containerBox).not.toBe(null); + const sidebarBox = await sidebar.boundingBox(); + expect(sidebarBox).not.toBe(null); + const canvasBox = await canvas.boundingBox(); + expect(canvasBox).not.toBe(null); + const thumbnailsBox = await thumbnails.boundingBox(); + expect(thumbnailsBox).not.toBe(null); + // eslint-disable-next-line playwright/no-conditional-in-test + if (!containerBox) + return; + // eslint-disable-next-line playwright/no-conditional-in-test + if (!sidebarBox) + return; + // eslint-disable-next-line playwright/no-conditional-in-test + if (!canvasBox) + return; + // eslint-disable-next-line playwright/no-conditional-in-test + if (!thumbnailsBox) + return; + let relativeWidth = sidebarBox.width / containerBox.width; + expect(relativeWidth).toBeCloseTo(0.2, 1); + relativeWidth = canvasBox.width / containerBox.width; + expect(relativeWidth).toBeCloseTo(0.7, 1); + relativeWidth = thumbnailsBox.width / containerBox.width; + expect(relativeWidth).toBeCloseTo(0.1, 1); +}); diff --git a/e2e/vue.spec.ts b/e2e/vue.spec.ts index 5067124..9d7bce8 100644 --- a/e2e/vue.spec.ts +++ b/e2e/vue.spec.ts @@ -4,7 +4,7 @@ import { test, expect } from '@playwright/test'; // https://playwright.dev/docs/intro test('visits the app root url', async ({ page }) => { await page.goto('/'); - await expect(page.locator('h2')).toHaveText('Face Mesh Editor'); + await expect(page.locator('h3')).toHaveText('Face Mesh Editor'); }); test('Check Element Relative Width to Container', async ({ page }) => { diff --git a/index.html b/index.html index 389bcc4..eb36a6c 100644 --- a/index.html +++ b/index.html @@ -15,20 +15,6 @@
- -+ The webservice address will be used to detect a face mesh on selected images. Therefore, the + images must be transferred to the webservice for processing. The open format allows it to + create individual webservices by everyone and can be easily swapped. +
+
+ The webservice API must provide the following addresses:
+ /detect
+ This call is used to detect a single face on a provided image file inside a POST request.
+ /annotations
+ This call is used to sync the annotations inside a POST request when the user triggers the
+ download.
+
+ Insert the webservice URL in the text field below and submit with hitting the Save button. +
+ + + + +- The webservice address will be used to detect a face mesh on selected images. Therefore, the - images must be transferred to the webservice for processing. The open format allows it to - create individual webservices by everyone and can be easily swapped. -
-
- The webservice API must provide the following addresses:
- /detect
- This call is used to detect a single face on a provided image file inside a POST request.
- /annotations
- This call is used to sync the annotations inside a POST request when the user triggers the
- download.
-
- Insert the webservice URL in the text field below and submit with hitting the Save button. -
- - - - -+ The webservice address will be used to detect a face mesh on selected images. Therefore, the + images must be transferred to the webservice for processing. The open format allows it to + create individual webservices by everyone and can be easily swapped. +
+
+ The webservice API must provide the following addresses:
+ /detect
+ This call is used to detect a single face on a provided image file inside a POST request.
+ /annotations
+ This call is used to sync the annotations inside a POST request when the user triggers the
+ download.
+
+ Insert the webservice URL in the text field below and submit with hitting the Save button. +
+ + + + +- The webservice address will be used to detect a face mesh on selected images. Therefore, the - images must be transferred to the webservice for processing. The open format allows it to - create individual webservices by everyone and can be easily swapped. -
-
- The webservice API must provide the following addresses:
- /detect
- This call is used to detect a single face on a provided image file inside a POST request.
- /annotations
- This call is used to sync the annotations inside a POST request when the user triggers the
- download.
-
- Insert the webservice URL in the text field below and submit with hitting the Save button. -
- - - - -