diff --git a/client/e2e/pages/feedback-history.page.ts b/client/e2e/pages/feedback-history.page.ts index abbccc69..a498ca95 100644 --- a/client/e2e/pages/feedback-history.page.ts +++ b/client/e2e/pages/feedback-history.page.ts @@ -6,6 +6,7 @@ export class FeedbackHistoryPage { async goto(type: 'received' | 'given' | 'sentRequest' | 'receivedRequest') { if (type === 'receivedRequest') { + // Dedicated page to list the received requests await this.page.goto(`/fr/give-requested`); } else { await this.page.goto(`/fr/history/type/${type}`); diff --git a/client/e2e/pages/give-requested-feedback.page.ts b/client/e2e/pages/give-requested-feedback.page.ts index f83d5dba..90109a47 100644 --- a/client/e2e/pages/give-requested-feedback.page.ts +++ b/client/e2e/pages/give-requested-feedback.page.ts @@ -12,6 +12,8 @@ export class GiveRequestedFeedbackPage { constructor(private page: Page) {} async give(persona: Persona, details: Details) { + await this.page.waitForURL('/fr/give-requested/token/**'); + await expect(this.page.getByLabel('Email de votre collègue')).toHaveValue(persona); await this.page.getByText('Points positifs').fill(details.positive); diff --git a/client/e2e/pages/manager.page.ts b/client/e2e/pages/manager.page.ts new file mode 100644 index 00000000..7474e79c --- /dev/null +++ b/client/e2e/pages/manager.page.ts @@ -0,0 +1,60 @@ +import { Page, expect } from '@playwright/test'; +import { Persona } from './sign-in.page'; + +type Details = { + message?: string; // note: there's no message for spontaneous feedback + positive: string; + negative: string; + comment: string; +}; + +export class ManagerPage { + constructor(private page: Page) {} + + async goto() { + await this.page.goto('/fr/manager'); + } + + async selectManaged(persona: Persona) { + await this.page.getByLabel('Collaborateur').click(); + await this.page.getByRole('option', { name: persona }).click(); + } + + async findGiverDetailsLink(persona: Persona) { + // Wait until the the `` is rendered + await this.page.locator('tbody').waitFor(); + + return this.page + .locator('tbody > tr', { has: this.page.getByRole('cell', { name: persona }) }) + .getByLabel('Consulter'); // note: the label can be 'Consulter la demande' or 'Consulter le feedZback' + } + + async matchPendingFeedback(giver: Persona, receiver: Persona, message: string) { + await this.page.waitForURL('/fr/manager/document/**'); + + await expect(this.page.getByRole('heading', { name: 'Demande de feedZback partagé' })).toBeVisible(); + + await expect(this.page.getByText(giver)).toBeVisible(); + await expect(this.page.getByText(receiver)).toBeVisible(); + + if (message) { + await expect(this.page.getByText(message)).toBeVisible(); + } + } + + async matchDoneFeedback(giver: Persona, receiver: Persona, details: Details) { + await this.page.waitForURL('/fr/manager/document/**'); + + await expect(this.page.getByRole('heading', { name: 'FeedZback partagé' })).toBeVisible(); + + await expect(this.page.getByText(giver)).toBeVisible(); + await expect(this.page.getByText(receiver)).toBeVisible(); + + if (details.message) { + await expect(this.page.getByText(details.message)).toBeVisible(); + } + await expect(this.page.getByText(details.positive)).toBeVisible(); + await expect(this.page.getByText(details.negative)).toBeVisible(); + await expect(this.page.getByText(details.comment)).toBeVisible(); + } +} diff --git a/client/e2e/pages/settings.page.ts b/client/e2e/pages/settings.page.ts new file mode 100644 index 00000000..51240e60 --- /dev/null +++ b/client/e2e/pages/settings.page.ts @@ -0,0 +1,20 @@ +import { Page } from '@playwright/test'; +import { Persona } from './sign-in.page'; + +export class SettingsPage { + constructor(private page: Page) {} + + async goto() { + await this.page.goto('/fr/settings'); + } + + async setManager(persona: Persona) { + await this.page.getByLabel('Email de votre manager').fill(persona); + await this.page.getByRole('button', { name: 'Mettre à jour' }).click(); + } + + async gotoAndSetManager(persona: Persona) { + await this.goto(); + await this.setManager(persona); + } +} diff --git a/client/e2e/pages/user-menu.page.ts b/client/e2e/pages/user-menu.page.ts index 4f1b5dad..c91a0724 100644 --- a/client/e2e/pages/user-menu.page.ts +++ b/client/e2e/pages/user-menu.page.ts @@ -1,9 +1,11 @@ -import { Page } from '@playwright/test'; +import { expect, Page } from '@playwright/test'; export class UserMenuPage { constructor(private page: Page) {} async logout() { + expect(this.page.url()).not.toMatch(/sign-in/); + await this.page.getByLabel('Menu utilisateur').click(); await this.page.getByRole('menuitem', { name: 'Se déconnecter' }).click(); diff --git a/client/e2e/requested-feedback.spec.ts b/client/e2e/requested-feedback.spec.ts index a61c3990..a24f8405 100644 --- a/client/e2e/requested-feedback.spec.ts +++ b/client/e2e/requested-feedback.spec.ts @@ -3,7 +3,9 @@ import { FeedbackHistoryDetailsPage } from './pages/feedback-history-details.pag import { FeedbackHistoryPage } from './pages/feedback-history.page'; import { FirestorePage } from './pages/firestore.page'; import { GiveRequestedFeedbackPage } from './pages/give-requested-feedback.page'; +import { ManagerPage } from './pages/manager.page'; import { RequestFeedbackPage } from './pages/request-feedback.page'; +import { SettingsPage } from './pages/settings.page'; import { Persona, SignInPage } from './pages/sign-in.page'; import { UserMenuPage } from './pages/user-menu.page'; @@ -81,4 +83,35 @@ test('Requested feedback', async ({ page }) => { await bernardDetailsLink2.click(); await new FeedbackHistoryDetailsPage(page).matchDone('received', Persona.Bernard, feedbackDetails); + + // ====== Alfred sets Daniel as its manager ====== + + await new SettingsPage(page).gotoAndSetManager(Persona.Daniel); + await new UserMenuPage(page).logout(); + + // ====== Daniel can now view the feedbacks that Alfred has shared with him ====== + + await new SignInPage(page).gotoAndSignIn(Persona.Daniel); + + await expect(page.getByRole('link', { name: 'Manager' })).toBeVisible(); + + const managerPage = new ManagerPage(page); + managerPage.goto(); + managerPage.selectManaged(Persona.Alfred); + + // View the feedback sent by Bernard + const bernardDetailsLink3 = await managerPage.findGiverDetailsLink(Persona.Bernard); + await expect(bernardDetailsLink3).toBeVisible(); + await bernardDetailsLink3.click(); + await managerPage.matchDoneFeedback(Persona.Bernard, Persona.Alfred, feedbackDetails); + + // Go back to the list of shared feedbacks + await page.getByRole('button', { name: 'FeedZbacks partagés' }).click(); + await page.waitForURL('/fr/manager/list/**'); + + // View the feedback expected from Charles + const charlesDetailsLink2 = await managerPage.findGiverDetailsLink(Persona.Charles); + await expect(charlesDetailsLink2).toBeVisible(); + await charlesDetailsLink2.click(); + await managerPage.matchPendingFeedback(Persona.Charles, Persona.Alfred, feedbackDetails.message); }); diff --git a/client/e2e/spontaneous-feedback.spec.ts b/client/e2e/spontaneous-feedback.spec.ts index e03c877f..3a4413e6 100644 --- a/client/e2e/spontaneous-feedback.spec.ts +++ b/client/e2e/spontaneous-feedback.spec.ts @@ -3,6 +3,8 @@ import { FeedbackHistoryDetailsPage } from './pages/feedback-history-details.pag import { FeedbackHistoryPage } from './pages/feedback-history.page'; import { FirestorePage } from './pages/firestore.page'; import { GiveSpontaneousFeedbackPage } from './pages/give-spontaneous-feedback.page'; +import { ManagerPage } from './pages/manager.page'; +import { SettingsPage } from './pages/settings.page'; import { Persona, SignInPage } from './pages/sign-in.page'; import { UserMenuPage } from './pages/user-menu.page'; @@ -41,4 +43,25 @@ test('Spontaneous feedback', async ({ page }) => { await bernardDetailsLink.click(); await new FeedbackHistoryDetailsPage(page).matchDone('received', Persona.Bernard, feedbackDetails); + + // ====== Alfred sets Daniel as its manager ====== + + await new SettingsPage(page).gotoAndSetManager(Persona.Daniel); + await new UserMenuPage(page).logout(); + + // ====== Daniel can now view the feedback that Alfred has shared with him ====== + + await new SignInPage(page).gotoAndSignIn(Persona.Daniel); + + await expect(page.getByRole('link', { name: 'Manager' })).toBeVisible(); + + const managerPage = new ManagerPage(page); + managerPage.goto(); + managerPage.selectManaged(Persona.Alfred); + + const managerDetailsLink = await managerPage.findGiverDetailsLink(Persona.Bernard); + await expect(managerDetailsLink).toBeVisible(); + await managerDetailsLink.click(); + + await managerPage.matchDoneFeedback(Persona.Bernard, Persona.Alfred, feedbackDetails); }); diff --git a/client/package.json b/client/package.json index caa7764f..1901694b 100644 --- a/client/package.json +++ b/client/package.json @@ -29,10 +29,10 @@ "server:e2e": "npm --prefix ../server run start:e2e", "prestack:e2e": "npm run build:e2e", "stack:e2e": "concurrently \"npm run firebase:e2e\" \"npm run server:e2e\"", - "test:e2e": "playwright test", - "posttest:e2e": "playwright show-report", - "test-ui:e2e": "playwright test --ui", - "test:codegen": "playwright codegen" + "e2e:test": "playwright test", + "e2e:report": "playwright show-report", + "e2e:ui": "playwright test --ui", + "e2e:codegen": "playwright codegen" }, "private": true, "dependencies": { diff --git a/client/playwright.config.ts b/client/playwright.config.ts index bcb95f14..8fa5b35d 100644 --- a/client/playwright.config.ts +++ b/client/playwright.config.ts @@ -78,10 +78,10 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { - command: 'npm run e2e:app', + command: 'npm run stack:e2e', reuseExistingServer: !process.env['CI'], port: 4200, - timeout: 30 * 1000, + timeout: 60_000, stdout: 'pipe', }, }); diff --git a/docs-source/docs/installation.md b/docs-source/docs/installation.md index 7ef3a092..ce6a6206 100644 --- a/docs-source/docs/installation.md +++ b/docs-source/docs/installation.md @@ -6,13 +6,13 @@ To configure and run the application locally, you need access to the Firebase pr Once you have gained access, you will also be able to access the [Google Cloud console](https://console.cloud.google.com/?project=feedzback-v2-dev). -:::note +:::info If you don't have permission, please contact Pierre Nicoli or Stéphane Francel. ::: ## Server -- Open your IDE in `./server` directory +- Open your IDE in `/server` directory ### Configuration @@ -44,20 +44,32 @@ Retrieve these secret values from the [Google Cloud Run console](https://console ```bash npm install -npm run start:dev +npm run start:dev # Start the server in "watch" mode ``` +Visit the URL http://localhost:3000 to check that the server is running properly. + +:::tip +If you just need to start the server once (without "watch" mode), run the command `npm start` from the `/server` directory. + +Running the command `npm run server` from the `/client` directory will have the same effect. +::: + ## Client ### Installation -- Open your IDE in `./client` directory +- Open your IDE in `/client` directory - Run the following commands: ```bash npm install -npm start +npm start # Start the client in "watch" mode ``` Finally, visit the URL http://localhost:4200 and enjoy FeedZback! 🚀 + +:::info +Please refer to [Local dev environment](/docs/technical-guides/environments/local-dev) for other ways to launch the application. +::: diff --git a/docs-source/docs/technical-guides/client/i18n.md b/docs-source/docs/technical-guides/client/i18n.md index 1e095a32..eb322da4 100644 --- a/docs-source/docs/technical-guides/client/i18n.md +++ b/docs-source/docs/technical-guides/client/i18n.md @@ -19,7 +19,7 @@ Note the post-processing script `postextract-i18n`, which sorts the translations The target file [src/locales/messages.en.json](https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.en.json) was created and translated manually. -:::note +:::tip Don't forget to regenerate the source file every time you add or modify text in the source code. Then update the destination file accordingly. ::: diff --git a/docs-source/docs/technical-guides/client/styles.md b/docs-source/docs/technical-guides/client/styles.md index 25681b28..dc0aae17 100644 --- a/docs-source/docs/technical-guides/client/styles.md +++ b/docs-source/docs/technical-guides/client/styles.md @@ -75,7 +75,7 @@ And the Sass styles should looks like this: } ``` -:::note +:::info The [`src/app/app.scss`](https://github.com/Zenika/feedzback/blob/main/client/src/app/app.scss) file gives you access to the global Sass variables and mixins in the component styles. ::: diff --git a/docs-source/docs/technical-guides/e2e-testing.md b/docs-source/docs/technical-guides/e2e-testing.md new file mode 100644 index 00000000..4460c798 --- /dev/null +++ b/docs-source/docs/technical-guides/e2e-testing.md @@ -0,0 +1,83 @@ +# E2E testing + +E2E tests are performed using [Playwright](https://playwright.dev/). + +## NPM scripts + +To run the tests, open a terminal in `/client` directory and run the following command: + +```bash +npm run e2e:test +``` + +All scripts related to E2E tests start with `"e2e:*"`: + +```json title="/client/package.json" +{ + "scripts": { + "e2e:test": "playwright test", + "e2e:report": "playwright show-report", + "e2e:ui": "playwright test --ui", + "e2e:codegen": "playwright codegen" + } +} +``` + +## Playwright configuration + +Here's part of the Playwright configuration: + +```ts title="/client/playwright.config.ts" +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + // Tests are located in the following directory + testDir: './e2e', + + // Run your local dev server before starting the tests + webServer: { + command: 'npm run stack:e2e', + port: 4200, + reuseExistingServer: !process.env['CI'], + }, +}); +``` + +Before starting the tests, Playwright executes the command `npm run stack:e2e` and waits for the application to be available on port `4200`. +Due to the `reuseExistingServer` option (enabled for non-CI environment), the command will not be executed if the application is already available. + +Therefore, you can run the command `npm run stack:e2e` in one terminal, wait for the application to be available on port `4200`, and then run the command `npm run e2e:test` in another terminal. +In this case, Playwright will skip the `webServer.command`, starting the tests immediately. + +## Running Playwright + +### Method 1 + +To have Playwright start the app and the tests, run the following command: + +```bash +npm run e2e:test +``` + +:::warning +At the end of the tests, Playwright may not stop the `webServer` properly. +If this happens, look for a "ghost" process named `java` and kill it manually. + +To avoid this problem, use the method 2 instead. +::: + +### Method 2 + +To start the app once and then have Playwright only start the tests, run the following commands in two separate terminals: + +```bash +npm run stack:e2e # First terminal +``` + +```bash +npm run e2e:test # Second terminal +``` + +:::tip +As an alternative to the above command in the first terminal, run `npm run stack:emulators` instead, to start the app in "watch" mode. +::: diff --git a/docs-source/docs/technical-guides/environments/local.md b/docs-source/docs/technical-guides/environments/local-dev.md similarity index 61% rename from docs-source/docs/technical-guides/environments/local.md rename to docs-source/docs/technical-guides/environments/local-dev.md index 70bc42f2..a5abba22 100644 --- a/docs-source/docs/technical-guides/environments/local.md +++ b/docs-source/docs/technical-guides/environments/local-dev.md @@ -1,5 +1,5 @@ --- -title: Local +title: Local dev --- # Local dev environment @@ -10,26 +10,36 @@ But you are still connecting to the remote `feedzback-v2-dev` Firebase project f The good news is that you can run the entire stack locally, using the [Firebase emulator suite](https://firebase.google.com/docs/emulator-suite)! :::note +All scripts related to Firebase emulator can be found in the `/client/package.json` file. +::: + +:::info When using the Firebase emulator, the Google Auth provider is no longer available. Only the Email/Password provider is enabled. ::: ## `*:emulators` scripts -In this execution context, the _client_ and _server_ apps are running in "dev" mode (with hot-reloading). +In this execution context, the _client_ and _server_ apps are running in "watch" mode. Only the Firebase _Auth_ and _Firestore_ emulators are started. The _Hosting_ emulator is not used in this context. Here are the NPM scripts for this execution context: -```json title="/client/package.json" +```json title="/client/package.json" { "scripts": { - "start:emulators": "ng serve -c development-emulators", + // Start Firebase "Auth" and "Firestore" emulators "firebase:emulators": "firebase emulators:start --only auth:dev,firestore:dev --import ./firebase-emulators-data", + + // Start the server app in "watch" mode "server:emulators": "npm --prefix ../server run start:emulators", - // To launch the stack with a single command: + // Start the client app in "watch" mode + "start:emulators": "ng serve -c development-emulators", + + // ---------------------------------------- + // Run all the previous scripts in parallel "stack:emulators": "concurrently \"npm run firebase:emulators\" \"npm run server:emulators\" \"npm run start:emulators\"" } } @@ -37,20 +47,29 @@ Here are the NPM scripts for this execution context: ## `*:e2e` scripts -In this execution context, the _client_ and _server_ apps are running in "build" mode (no hot-reloading). +In this execution context, the _client_ and _server_ apps are built before running. + +This time, not only are the Firebase _Auth_ and _Firestore_ emulators started, but so is the _Hosting_ emulator that serves the client app. +Therefore, the client app must be built beforehand, to be available in the `/client/dist/browser` directory. -This time, not only are the Firebase _Auth_ and _Firestore_ emulators started, but so is the _Hosting_ emulator that serves the client application. +This environment is the closest to the production environment (with the exception of the authentication method) and is therefore ideal for [E2E testing](/docs/technical-guides/e2e-testing). -This environment is the closest to the production environment (with the exception of the authentication method) and is therefore ideal for e2e testing. +Here are the NPM scripts for this execution context: -```json title="/client/package.json" +```json title="/client/package.json" { "scripts": { + // Start Firebase "Auth", "Firestore" and "Hosting" emulators "firebase:e2e": "firebase emulators:start --only auth:dev,firestore:dev,hosting:dev --import ./firebase-emulators-data", + + // Build and start the server app (see "/server/package.json" scripts for details) "server:e2e": "npm --prefix ../server run start:e2e", - // To launch the stack with a single command: + // Only build the client app (it will be served by Firebase "Hosting") "prestack:e2e": "npm run build:e2e", + + // ---------------------------------------- + // Run all the previous scripts in parallel "stack:e2e": "concurrently \"npm run firebase:e2e\" \"npm run server:e2e\"" } } diff --git a/docs-source/docs/update/client.md b/docs-source/docs/update/client.md index 7bb60ea9..3ff3d509 100644 --- a/docs-source/docs/update/client.md +++ b/docs-source/docs/update/client.md @@ -192,7 +192,7 @@ Update `tsconfig.spec.json` and `tsconfig.json` files: } ``` -:::note +:::info You need to make this change even for the `tsconfig.json` file, as it is used by the IDE. ::: diff --git a/docs-source/sidebars.ts b/docs-source/sidebars.ts index 2d920c20..dadc988b 100644 --- a/docs-source/sidebars.ts +++ b/docs-source/sidebars.ts @@ -25,7 +25,7 @@ const sidebars: SidebarsConfig = { { type: 'category', label: 'Environments', - items: ['technical-guides/environments/overview', 'technical-guides/environments/local'], + items: ['technical-guides/environments/overview', 'technical-guides/environments/local-dev'], }, { type: 'category', @@ -44,6 +44,7 @@ const sidebars: SidebarsConfig = { label: 'Server', items: ['technical-guides/server/swagger'], }, + 'technical-guides/e2e-testing', ], }, { diff --git a/docs/404.html b/docs/404.html index 68ea6fd5..bd82f3f9 100644 --- a/docs/404.html +++ b/docs/404.html @@ -5,8 +5,8 @@ Page Not Found | FeedZback - - + +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/docs/assets/js/1379c009.3a22c5e5.js b/docs/assets/js/1379c009.3a22c5e5.js new file mode 100644 index 00000000..48fd45da --- /dev/null +++ b/docs/assets/js/1379c009.3a22c5e5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[8931],{6872:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>o,frontMatter:()=>i,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"business-cases/shared-feedback","title":"Shared feedback","description":"User story","source":"@site/docs/business-cases/shared-feedback.md","sourceDirName":"business-cases","slug":"/business-cases/shared-feedback","permalink":"/feedzback/docs/business-cases/shared-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/shared-feedback.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Feedback draft","permalink":"/feedzback/docs/business-cases/feedback-draft"},"next":{"title":"Archiving","permalink":"/feedzback/docs/business-cases/archiving"}}');var c=a(4848),r=a(8453);const i={},t="Shared feedback",d={},h=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"As an employee, define my manager",id:"as-an-employee-define-my-manager",level:3},{value:"As a manager, view my shared feedbacks",id:"as-a-manager-view-my-shared-feedbacks",level:3},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"shared-feedback",children:"Shared feedback"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"When I send a feedback request, I can choose whether or not to share the expected feedback with my manager."}),"\n",(0,c.jsx)(n.p,{children:"When I give spontaneous feedback to a colleague, I can choose whether or not to share it with their manager."}),"\n",(0,c.jsx)(n.p,{children:"Feedbacks are shared with the manager defined in the application settings.\nThis means that when I change manager, all my shared feedbacks are shared with my new manager."}),"\n",(0,c.jsx)(n.p,{children:"As a manager, I'd like to be able to view the feedback that the employees I manage have received and shared with me."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["A feedback is shared with the manager of the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," if the field ",(0,c.jsx)(n.code,{children:"shared"})," of the ",(0,c.jsx)(n.code,{children:"feedback"})," document is set to ",(0,c.jsx)(n.code,{children:"true"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequest: FeedbackRequest = {\n shared: true,\n ...\n};\n\nconst feedback: Feedback = {\n shared: true,\n ...\n};\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["This ",(0,c.jsx)(n.code,{children:"shared"})," field is only set when requesting a feedback or when giving a spontaneous feedback and cannot be changed thereafter."]})}),"\n",(0,c.jsx)(n.h3,{id:"as-an-employee-define-my-manager",children:"As an employee, define my manager"}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"employee"})," Firestore collection contains the manager/managed data."]}),"\n",(0,c.jsx)(n.p,{children:"When an employee defines his manager, 2 documents are updated:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const theManagedDocument: EmployeeData = {\n managerEmail: '',\n};\n\nconst theManagerDocument: EmployeeData = {\n managedEmails: [''],\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["When an employee updates his manager, a third document is updated because the ",(0,c.jsx)(n.code,{children:""})," must be deleted from the previous manager's document."]}),"\n",(0,c.jsx)(n.h3,{id:"as-a-manager-view-my-shared-feedbacks",children:"As a manager, view my shared feedbacks"}),"\n",(0,c.jsxs)(n.p,{children:["An employee is a manager if there is at least one element in its ",(0,c.jsx)(n.code,{children:"managedEmails"}),' array.\nIn this case, the "Manager" button is displayed in the header menu.\nFrom there, the manager can access the shared feedbacks.']}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/settings/settings.component.ts",children:(0,c.jsx)(n.code,{children:"SettingsComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/manager/manager-list/manager-list.component.ts",children:(0,c.jsx)(n.code,{children:"ManagerListComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/employee/employee.controller.ts",children:(0,c.jsx)(n.code,{children:"EmployeeController"})})}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"getSharedFeedbackList"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"getSharedFeedbackDocument"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>t});var s=a(6540);const c={},r=s.createContext(c);function i(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/1379c009.4b3b3df9.js b/docs/assets/js/1379c009.4b3b3df9.js deleted file mode 100644 index 0cdd9b8e..00000000 --- a/docs/assets/js/1379c009.4b3b3df9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[931],{6872:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>t,default:()=>o,frontMatter:()=>i,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"business-cases/shared-feedback","title":"Shared feedback","description":"User story","source":"@site/docs/business-cases/shared-feedback.md","sourceDirName":"business-cases","slug":"/business-cases/shared-feedback","permalink":"/feedzback/docs/business-cases/shared-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/shared-feedback.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Feedback draft","permalink":"/feedzback/docs/business-cases/feedback-draft"},"next":{"title":"Archiving","permalink":"/feedzback/docs/business-cases/archiving"}}');var c=a(4848),r=a(8453);const i={},t="Shared feedback",d={},h=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"As an employee, define my manager",id:"as-an-employee-define-my-manager",level:3},{value:"As a manager, view my shared feedbacks",id:"as-a-manager-view-my-shared-feedbacks",level:3},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"shared-feedback",children:"Shared feedback"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"When I send a feedback request, I can choose whether or not to share the expected feedback with my manager."}),"\n",(0,c.jsx)(n.p,{children:"When I give spontaneous feedback to a colleague, I can choose whether or not to share it with their manager."}),"\n",(0,c.jsx)(n.p,{children:"Feedbacks are shared with the manager defined in the application settings.\nThis means that when I change manager, all my shared feedbacks are shared with my new manager."}),"\n",(0,c.jsx)(n.p,{children:"As a manager, I'd like to be able to view the feedback that the employees I manage have received and shared with me."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["A feedback is shared with the manager of the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," if the field ",(0,c.jsx)(n.code,{children:"shared"})," of the ",(0,c.jsx)(n.code,{children:"feedback"})," document is set to ",(0,c.jsx)(n.code,{children:"true"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequest: FeedbackRequest = {\n shared: true,\n ...\n};\n\nconst feedback: Feedback = {\n shared: true,\n ...\n};\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["This ",(0,c.jsx)(n.code,{children:"shared"})," field is only set when requesting a feedback or when giving a spontaneous feedback and cannot be changed thereafter."]})}),"\n",(0,c.jsx)(n.h3,{id:"as-an-employee-define-my-manager",children:"As an employee, define my manager"}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"employee"})," Firestore collection contains the manager/managed data."]}),"\n",(0,c.jsx)(n.p,{children:"When an employee defines his manager, 2 documents are updated:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const theManagedDocument: EmployeeData = {\n managerEmail: '',\n};\n\nconst theManagerDocument: EmployeeData = {\n managedEmails: [''],\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["When an employee updates his manager, a third document is updated because the ",(0,c.jsx)(n.code,{children:""})," must be deleted from the previous manager's document."]}),"\n",(0,c.jsx)(n.h3,{id:"as-a-manager-view-my-shared-feedbacks",children:"As a manager, view my shared feedbacks"}),"\n",(0,c.jsxs)(n.p,{children:["An employee is a manager if there is at least one element in its ",(0,c.jsx)(n.code,{children:"managedEmails"}),' array.\nIn this case, the "Manager" button is displayed in the header menu.\nFrom there, the manager can access the shared feedbacks.']}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/settings/settings.component.ts",children:(0,c.jsx)(n.code,{children:"SettingsComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/manager/manager-list/manager-list.component.ts",children:(0,c.jsx)(n.code,{children:"ManagerListComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/employee/employee.controller.ts",children:(0,c.jsx)(n.code,{children:"EmployeeController"})})}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"getSharedFeedbackList"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"getSharedFeedbackDocument"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>t});var s=a(6540);const c={},r=s.createContext(c);function i(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/1531.e3de5bf9.js b/docs/assets/js/1531.e3de5bf9.js new file mode 100644 index 00000000..609ace49 --- /dev/null +++ b/docs/assets/js/1531.e3de5bf9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[1531],{4096:(e,t,a)=>{a.d(t,{in:()=>c,OU:()=>C,Ki:()=>A,kJ:()=>x,x:()=>l,e7:()=>m,J_:()=>f,Gx:()=>_});var s=a(6540),n=a(9532),i=a(6803),r=a(4848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=s.createContext(null);function c(e){let{children:t,content:a,isBlogPostPage:n=!1}=e;const i=function(e){let{content:t,isBlogPostPage:a}=e;return(0,s.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:n});return(0,r.jsx)(o.Provider,{value:i,children:t})}function m(){const e=(0,s.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var u=a(6025),h=a(4586);const d=e=>new Date(e).toISOString();function g(e){const t=e.map(v);return{author:1===t.length?t[0]:t}}function p(e,t,a){return e?{image:j({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function x(e){const{siteConfig:t}=(0,h.A)(),{withBaseUrl:a}=(0,u.hH)(),{metadata:{blogDescription:s,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:s,blogPost:e.items.map((e=>function(e,t,a){const{assets:s,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,m=s.image??n.image,u=n.keywords??[],h=`${t.url}${i.permalink}`,x=c?d(c):void 0;return{"@type":"BlogPosting","@id":h,mainEntityOfPage:h,url:h,headline:l,name:l,description:o,datePublished:r,...x?{dateModified:x}:{},...g(i.authors),...p(m,a,l),...u?{keywords:u}:{}}}(e.content,t,a)))}}function f(){const e=l(),{assets:t,metadata:a}=m(),{siteConfig:s}=(0,h.A)(),{withBaseUrl:n}=(0,u.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:x}=a,f=t.image??c.image,v=c.keywords??[],j=x?d(x):void 0,b=`${s.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":b,mainEntityOfPage:b,url:b,headline:r,name:r,description:o,datePublished:i,...j?{dateModified:j}:{},...g(a.authors),...p(f,n,r),...v?{keywords:v}:{},isPartOf:{"@type":"Blog","@id":`${s.url}${e.blogBasePath}`,name:e.blogTitle}}}function v(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function j(e){let{imageUrl:t,caption:a}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:a}}var b=a(6347),w=a(8774),N=a(1682),k=a(9169);function _(e){const{pathname:t}=(0,b.zy)();return(0,s.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,k.ys)(e.permalink,t))}(e,t)))),[e,t])}function A(e){const t=(0,N.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),a=Object.entries(t);return a.reverse(),a}function C(e){let{items:t,ulClassName:a,liClassName:s,linkClassName:n,linkActiveClassName:i}=e;return(0,r.jsx)("ul",{className:a,children:t.map((e=>(0,r.jsx)("li",{className:s,children:(0,r.jsx)(w.A,{isNavLink:!0,to:e.permalink,className:n,activeClassName:i,children:e.title})},e.permalink)))})}},6913:(e,t,a)=>{a.d(t,{A:()=>j});a(6540);var s=a(4164),n=a(8774),i=a(4848);const r="githubSvg_Uu4N";const l="xSvg_y3PF";const o=function(e){return(0,i.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...e,children:[(0,i.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,i.jsx)("path",{d:"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"}),(0,i.jsx)("path",{d:"M3.6 9h16.8"}),(0,i.jsx)("path",{d:"M3.6 15h16.8"}),(0,i.jsx)("path",{d:"M11.5 3a17 17 0 0 0 0 18"}),(0,i.jsx)("path",{d:"M12.5 3a17 17 0 0 1 0 18"})]})},c={authorSocials:"authorSocials_rSDt",authorSocialLink:"authorSocialLink_owbf",authorSocialIcon:"authorSocialIcon_XYv3"},m={twitter:{Icon:function(e){return(0,i.jsx)("svg",{viewBox:"0 0 256 209",width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",...e,children:(0,i.jsx)("path",{d:"M256 25.45c-9.42 4.177-19.542 7-30.166 8.27 10.845-6.5 19.172-16.793 23.093-29.057a105.183 105.183 0 0 1-33.351 12.745C205.995 7.201 192.346.822 177.239.822c-29.006 0-52.523 23.516-52.523 52.52 0 4.117.465 8.125 1.36 11.97-43.65-2.191-82.35-23.1-108.255-54.876-4.52 7.757-7.11 16.78-7.11 26.404 0 18.222 9.273 34.297 23.365 43.716a52.312 52.312 0 0 1-23.79-6.57c-.003.22-.003.44-.003.661 0 25.447 18.104 46.675 42.13 51.5a52.592 52.592 0 0 1-23.718.9c6.683 20.866 26.08 36.05 49.062 36.475-17.975 14.086-40.622 22.483-65.228 22.483-4.24 0-8.42-.249-12.529-.734 23.243 14.902 50.85 23.597 80.51 23.597 96.607 0 149.434-80.031 149.434-149.435 0-2.278-.05-4.543-.152-6.795A106.748 106.748 0 0 0 256 25.45",fill:"#55acee"})})},label:"Twitter"},github:{Icon:function(e){return(0,i.jsx)("svg",{viewBox:"0 0 256 250",width:"1em",height:"1em",...e,className:(0,s.A)(e.className,r),xmlns:"http://www.w3.org/2000/svg",style:{"--dark":"#000","--light":"#fff"},preserveAspectRatio:"xMidYMid",children:(0,i.jsx)("path",{d:"M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z"})})},label:"GitHub"},stackoverflow:{Icon:function(e){return(0,i.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 169.61 200",width:"1em",height:"1em",...e,children:[(0,i.jsx)("path",{d:"M140.44 178.38v-48.65h21.61V200H0v-70.27h21.61v48.65z",fill:"#bcbbbb"}),(0,i.jsx)("path",{d:"M124.24 140.54l4.32-16.22-86.97-17.83-3.78 17.83zM49.7 82.16L130.72 120l7.56-16.22-81.02-37.83zm22.68-40l68.06 57.3 11.35-13.51-68.6-57.3-11.35 13.51zM116.14 0l-14.59 10.81 53.48 71.89 14.58-10.81zM37.81 162.16h86.43v-16.21H37.81z",fill:"#f48024"})]})},label:"Stack Overflow"},linkedin:{Icon:function(e){return(0,i.jsx)("svg",{width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",...e,children:(0,i.jsx)("path",{d:"M218.123 218.127h-37.931v-59.403c0-14.165-.253-32.4-19.728-32.4-19.756 0-22.779 15.434-22.779 31.369v60.43h-37.93V95.967h36.413v16.694h.51a39.907 39.907 0 0 1 35.928-19.733c38.445 0 45.533 25.288 45.533 58.186l-.016 67.013ZM56.955 79.27c-12.157.002-22.014-9.852-22.016-22.009-.002-12.157 9.851-22.014 22.008-22.016 12.157-.003 22.014 9.851 22.016 22.008A22.013 22.013 0 0 1 56.955 79.27m18.966 138.858H37.95V95.967h37.97v122.16ZM237.033.018H18.89C8.58-.098.125 8.161-.001 18.471v219.053c.122 10.315 8.576 18.582 18.89 18.474h218.144c10.336.128 18.823-8.139 18.966-18.474V18.454c-.147-10.33-8.635-18.588-18.966-18.453",fill:"#0A66C2"})})},label:"LinkedIn"},x:{Icon:function(e){return(0,i.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",fill:"none",viewBox:"0 0 1200 1227",...e,className:(0,s.A)(e.className,l),style:{"--dark":"#000","--light":"#fff"},children:(0,i.jsx)("path",{d:"M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"})})},label:"X"}};function u(e){let{platform:t,link:a}=e;const{Icon:r,label:l}=m[u=t]??{Icon:o,label:u};var u;return(0,i.jsx)(n.A,{className:c.authorSocialLink,href:a,title:l,children:(0,i.jsx)(r,{className:(0,s.A)(c.authorSocialLink)})})}function h(e){let{author:t}=e;const a=Object.entries(t.socials??{});return(0,i.jsx)("div",{className:c.authorSocials,children:a.map((e=>{let[t,a]=e;return(0,i.jsx)(u,{platform:t,link:a},t)}))})}var d=a(1107);const g={authorImage:"authorImage_XqGP","author-as-h1":"author-as-h1_n9oJ","author-as-h2":"author-as-h2_gXvM",authorDetails:"authorDetails_lV9A",authorName:"authorName_yefp",authorTitle:"authorTitle_nd0D",authorBlogPostCount:"authorBlogPostCount_iiJ5"};function p(e){return e.href?(0,i.jsx)(n.A,{...e}):(0,i.jsx)(i.Fragment,{children:e.children})}function x(e){let{title:t}=e;return(0,i.jsx)("small",{className:g.authorTitle,title:t,children:t})}function f(e){let{name:t,as:a}=e;return a?(0,i.jsx)(d.A,{as:a,className:g.authorName,children:t}):(0,i.jsx)("span",{className:g.authorName,children:t})}function v(e){let{count:t}=e;return(0,i.jsx)("span",{className:(0,s.A)(g.authorBlogPostCount),children:t})}function j(e){let{as:t,author:a,className:n,count:r}=e;const{name:l,title:o,url:c,imageURL:m,email:u,page:d}=a,j=d?.permalink||c||u&&`mailto:${u}`||void 0;return(0,i.jsxs)("div",{className:(0,s.A)("avatar margin-bottom--sm",n,g[`author-as-${t}`]),children:[m&&(0,i.jsx)(p,{href:j,className:"avatar__photo-link",children:(0,i.jsx)("img",{className:(0,s.A)("avatar__photo",g.authorImage),src:m,alt:l})}),(l||o)&&(0,i.jsxs)("div",{className:(0,s.A)("avatar__intro",g.authorDetails),children:[(0,i.jsxs)("div",{className:"avatar__name",children:[l&&(0,i.jsx)(p,{href:j,children:(0,i.jsx)(f,{name:l,as:t})}),void 0!==r&&(0,i.jsx)(v,{count:r})]}),!!o&&(0,i.jsx)(x,{title:o}),(0,i.jsx)(h,{author:a})]})]})}},8027:(e,t,a)=>{a.d(t,{A:()=>I});var s=a(6540),n=a(4164),i=a(781),r=a(4581),l=a(1312),o=a(4096),c=a(6342),m=a(1107),u=a(4848);function h(e){let{year:t,yearGroupHeadingClassName:a,children:s}=e;return(0,u.jsxs)("div",{role:"group",children:[(0,u.jsx)(m.A,{as:"h3",className:a,children:t}),s]})}function d(e){let{items:t,yearGroupHeadingClassName:a,ListComponent:s}=e;if((0,c.p)().blog.sidebar.groupByYear){const e=(0,o.Ki)(t);return(0,u.jsx)(u.Fragment,{children:e.map((e=>{let[t,n]=e;return(0,u.jsx)(h,{year:t,yearGroupHeadingClassName:a,children:(0,u.jsx)(s,{items:n})},t)}))})}return(0,u.jsx)(s,{items:t})}const g=(0,s.memo)(d),p="sidebar_re4s",x="sidebarItemTitle_pO2u",f="sidebarItemList_Yudw",v="sidebarItem__DBe",j="sidebarItemLink_mo7H",b="sidebarItemLinkActive_I1ZP",w="yearGroupHeading_rMGB",N=e=>{let{items:t}=e;return(0,u.jsx)(o.OU,{items:t,ulClassName:(0,n.A)(f,"clean-list"),liClassName:v,linkClassName:j,linkActiveClassName:b})};function k(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,u.jsx)("aside",{className:"col col--3",children:(0,u.jsxs)("nav",{className:(0,n.A)(p,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,u.jsx)("div",{className:(0,n.A)(x,"margin-bottom--md"),children:t.title}),(0,u.jsx)(g,{items:a,ListComponent:N,yearGroupHeadingClassName:w})]})})}const _=(0,s.memo)(k);var A=a(5600);const C={yearGroupHeading:"yearGroupHeading_QT03"},M=e=>{let{items:t}=e;return(0,u.jsx)(o.OU,{items:t,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"})};function y(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,u.jsx)(g,{items:a,ListComponent:M,yearGroupHeadingClassName:C.yearGroupHeading})}function P(e){return(0,u.jsx)(A.GX,{component:y,props:e})}const B=(0,s.memo)(P);function L(e){let{sidebar:t}=e;const a=(0,r.l)();return t?.items.length?"mobile"===a?(0,u.jsx)(B,{sidebar:t}):(0,u.jsx)(_,{sidebar:t}):null}function I(e){const{sidebar:t,toc:a,children:s,...r}=e,l=t&&t.items.length>0;return(0,u.jsx)(i.A,{...r,children:(0,u.jsx)("div",{className:"container margin-vert--lg",children:(0,u.jsxs)("div",{className:"row",children:[(0,u.jsx)(L,{sidebar:t}),(0,u.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:s}),a&&(0,u.jsx)("div",{className:"col col--2",children:a})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/15415093.41ddc5d5.js b/docs/assets/js/15415093.41ddc5d5.js new file mode 100644 index 00000000..1d1f5bee --- /dev/null +++ b/docs/assets/js/15415093.41ddc5d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[7595],{2607:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"audience","title":"Audience","description":"This documentation is aimed at developers who need to participate in the project.","source":"@site/docs/audience.md","sourceDirName":".","slug":"/audience","permalink":"/feedzback/docs/audience","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/audience.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","next":{"title":"Technical stack","permalink":"/feedzback/docs/technical-stack"}}');var c=t(4848),s=t(8453);const r={},o="Audience",a={},d=[{value:"Contacts",id:"contacts",level:2},{value:"Contributors",id:"contributors",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"audience",children:"Audience"})}),"\n",(0,c.jsx)(n.p,{children:"This documentation is aimed at developers who need to participate in the project."}),"\n",(0,c.jsx)(n.h2,{id:"contacts",children:"Contacts"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client:"})," Augustin Grimprel"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Product owner:"})," Lise Quesnel"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Technical lead for client and server apps:"})," St\xe9phane Francel"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Technical lead for CI/CD piplines:"})," Pierre Nicoli"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Technical lead for usage analytics:"})," Noan Cloarec"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"contributors",children:"Contributors"}),"\n",(0,c.jsxs)(n.p,{children:["The full list of contributors is available on ",(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback",children:"GitHub"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(6540);const c={},s=i.createContext(c);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/15415093.5f39a1a3.js b/docs/assets/js/15415093.5f39a1a3.js deleted file mode 100644 index a031bb50..00000000 --- a/docs/assets/js/15415093.5f39a1a3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[595],{2607:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"audience","title":"Audience","description":"This documentation is aimed at developers who need to participate in the project.","source":"@site/docs/audience.md","sourceDirName":".","slug":"/audience","permalink":"/feedzback/docs/audience","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/audience.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","next":{"title":"Technical stack","permalink":"/feedzback/docs/technical-stack"}}');var c=t(4848),s=t(8453);const r={},o="Audience",a={},d=[{value:"Contacts",id:"contacts",level:2},{value:"Contributors",id:"contributors",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"audience",children:"Audience"})}),"\n",(0,c.jsx)(n.p,{children:"This documentation is aimed at developers who need to participate in the project."}),"\n",(0,c.jsx)(n.h2,{id:"contacts",children:"Contacts"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client:"})," Augustin Grimprel"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Product owner:"})," Lise Quesnel"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Technical lead for client and server apps:"})," St\xe9phane Francel"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Technical lead for CI/CD piplines:"})," Pierre Nicoli"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Technical lead for usage analytics:"})," Noan Cloarec"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"contributors",children:"Contributors"}),"\n",(0,c.jsxs)(n.p,{children:["The full list of contributors is available on ",(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback",children:"GitHub"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(6540);const c={},s=i.createContext(c);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/17896441.adbc8438.js b/docs/assets/js/17896441.adbc8438.js new file mode 100644 index 00000000..353f45a5 --- /dev/null +++ b/docs/assets/js/17896441.adbc8438.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[8401],{6896:(e,t,n)=>{n.d(t,{A:()=>f});n(6540);var s=n(4164),a=n(1312),i=n(5260),o=n(4848);function l(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function r(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,o.jsx)(i.A,{children:(0,o.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function d(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function u(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}var m=n(7559),h=n(7293);function b(e){let{className:t}=e;return(0,o.jsx)(h.A,{type:"caution",title:(0,o.jsx)(d,{}),className:(0,s.A)(t,m.G.common.draftBanner),children:(0,o.jsx)(u,{})})}function v(e){let{className:t}=e;return(0,o.jsx)(h.A,{type:"caution",title:(0,o.jsx)(l,{}),className:(0,s.A)(t,m.G.common.unlistedBanner),children:(0,o.jsx)(r,{})})}function x(e){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(c,{}),(0,o.jsx)(v,{...e})]})}function f(e){let{metadata:t}=e;const{unlisted:n,frontMatter:s}=t;return(0,o.jsxs)(o.Fragment,{children:[(n||s.unlisted)&&(0,o.jsx)(x,{}),s.draft&&(0,o.jsx)(b,{})]})}},575:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ae});var s=n(6540),a=n(1213),i=n(9532),o=n(4848);const l=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,o.jsx)(l.Provider,{value:a,children:t})}function c(){const e=(0,s.useContext)(l);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,o.jsx)(a.be,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(4164),m=n(4581),h=n(1312),b=n(9022);function v(e){const{previous:t,next:n}=e;return(0,o.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,h.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,o.jsx)(b.A,{...t,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,o.jsx)(b.A,{...n,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}function x(){const{metadata:e}=c();return(0,o.jsx)(v,{previous:e.previous,next:e.next})}var f=n(4586),p=n(8774),g=n(4070),j=n(7559),A=n(3886),L=n(3025);const C={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function N(e){const t=C[e.versionMetadata.banner];return(0,o.jsx)(t,{...e})}function _(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,o.jsx)("b",{children:(0,o.jsx)(p.A,{to:n,onClick:s,children:(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function T(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:s}}=(0,f.A)(),{pluginId:a}=(0,g.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,A.g1)(a),{latestDocSuggestion:l,latestVersionSuggestion:r}=(0,g.HW)(a),c=l??(d=r).docs.find((e=>e.id===d.mainDocId));var d;return(0,o.jsxs)("div",{className:(0,u.A)(t,j.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,o.jsx)("div",{children:(0,o.jsx)(N,{siteTitle:s,versionMetadata:n})}),(0,o.jsx)("div",{className:"margin-top--md",children:(0,o.jsx)(_,{versionLabel:r.label,to:c.path,onClick:()=>i(r.name)})})]})}function k(e){let{className:t}=e;const n=(0,L.r)();return n.banner?(0,o.jsx)(T,{className:t,versionMetadata:n}):null}function H(e){let{className:t}=e;const n=(0,L.r)();return n.badge?(0,o.jsx)("span",{className:(0,u.A)(t,j.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(h.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}var M=n(8046),y=n(4336);function B(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,tags:a}=e,i=a.length>0,l=!!(t||n||s);return i||l?(0,o.jsxs)("footer",{className:(0,u.A)(j.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",j.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(M.A,{tags:a})})}),l&&(0,o.jsx)(y.A,{className:(0,u.A)("margin-top--sm",j.G.docs.docFooterEditMetaRow),editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s})]}):null}var I=n(1422),w=n(5195);const E={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function V(e){let{collapsed:t,...n}=e;return(0,o.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",E.tocCollapsibleButton,!t&&E.tocCollapsibleButtonExpanded,n.className),children:(0,o.jsx)(h.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const O={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function G(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:l}=(0,I.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(O.tocCollapsible,!i&&O.tocCollapsibleExpanded,n),children:[(0,o.jsx)(V,{collapsed:i,onClick:l}),(0,o.jsx)(I.N,{lazy:!0,className:O.tocCollapsibleContent,collapsed:i,children:(0,o.jsx)(w.A,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const S={tocMobile:"tocMobile_ITEo"};function P(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(G,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.A)(j.G.docs.docTocMobile,S.tocMobile)})}var F=n(7763);function R(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(F.A,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:j.G.docs.docTocDesktop})}var U=n(1107),D=n(5533);function z(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,o.jsxs)("div",{className:(0,u.A)(j.G.docs.docMarkdown,"markdown"),children:[n&&(0,o.jsx)("header",{children:(0,o.jsx)(U.A,{as:"h1",children:n})}),(0,o.jsx)(D.A,{children:t})]})}var q=n(6972),$=n(9169),W=n(6025);function Y(e){return(0,o.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,o.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const Z={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function J(){const e=(0,W.Ay)("/");return(0,o.jsx)("li",{className:"breadcrumbs__item",children:(0,o.jsx)(p.A,{"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,o.jsx)(Y,{className:Z.breadcrumbHomeIcon})})})}const K={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function Q(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,o.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,o.jsx)(p.A,{className:a,href:n,itemProp:"item",children:(0,o.jsx)("span",{itemProp:"name",children:t})}):(0,o.jsx)("span",{className:a,children:t})}function X(e){let{children:t,active:n,index:s,addMicrodata:a}=e;return(0,o.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,u.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,o.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function ee(){const e=(0,q.OF)(),t=(0,$.Dt)();return e?(0,o.jsx)("nav",{className:(0,u.A)(j.G.docs.docBreadcrumbs,K.breadcrumbsContainer),"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,o.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,o.jsx)(J,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,o.jsx)(X,{active:s,index:n,addMicrodata:!!a,children:(0,o.jsx)(Q,{href:a,isLast:s,children:t.label})},n)}))]})}):null}var te=n(6896);const ne={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function se(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,o.jsx)(P,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,o.jsx)(R,{})}}(),{metadata:s}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&ne.docItemCol),children:[(0,o.jsx)(te.A,{metadata:s}),(0,o.jsx)(k,{}),(0,o.jsxs)("div",{className:ne.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(ee,{}),(0,o.jsx)(H,{}),n.mobile,(0,o.jsx)(z,{children:t}),(0,o.jsx)(B,{})]}),(0,o.jsx)(x,{})]})]}),n.desktop&&(0,o.jsx)("div",{className:"col col--3",children:n.desktop})]})}function ae(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,o.jsx)(r,{content:e.content,children:(0,o.jsxs)(a.e3,{className:t,children:[(0,o.jsx)(d,{}),(0,o.jsx)(se,{children:(0,o.jsx)(n,{})})]})})}},7763:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var s=n(4164),a=n(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var o=n(4848);const l="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,o.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",t),children:(0,o.jsx)(a.A,{...n,linkClassName:l,linkActiveClassName:r})})}},5195:(e,t,n)=>{n.d(t,{A:()=>v});var s=n(6540),a=n(6342);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function o(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=o({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function r(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>l(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:o}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:o}),c=r(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var u=n(8774),m=n(4848);function h(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const b=s.memo(h);function v(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const v=(0,a.p)(),x=c??v.tableOfContents.minHeadingLevel,f=u??v.tableOfContents.maxHeadingLevel,p=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>o({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:x,maxHeadingLevel:f});return d((0,s.useMemo)((()=>{if(l&&r)return{linkClassName:l,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:f}}),[l,r,x,f])),(0,m.jsx)(b,{toc:p,className:n,linkClassName:l,...h})}}}]); \ No newline at end of file diff --git a/docs/assets/js/17896441.ae89dba9.js b/docs/assets/js/17896441.ae89dba9.js deleted file mode 100644 index 6c5710ab..00000000 --- a/docs/assets/js/17896441.ae89dba9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[401],{6896:(e,t,n)=>{n.d(t,{A:()=>f});n(6540);var s=n(4164),a=n(1312),i=n(5260),o=n(4848);function l(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function r(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,o.jsx)(i.A,{children:(0,o.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function d(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function u(){return(0,o.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}var m=n(7559),h=n(7293);function b(e){let{className:t}=e;return(0,o.jsx)(h.A,{type:"caution",title:(0,o.jsx)(d,{}),className:(0,s.A)(t,m.G.common.draftBanner),children:(0,o.jsx)(u,{})})}function v(e){let{className:t}=e;return(0,o.jsx)(h.A,{type:"caution",title:(0,o.jsx)(l,{}),className:(0,s.A)(t,m.G.common.unlistedBanner),children:(0,o.jsx)(r,{})})}function x(e){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(c,{}),(0,o.jsx)(v,{...e})]})}function f(e){let{metadata:t}=e;const{unlisted:n,frontMatter:s}=t;return(0,o.jsxs)(o.Fragment,{children:[(n||s.unlisted)&&(0,o.jsx)(x,{}),s.draft&&(0,o.jsx)(b,{})]})}},575:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ae});var s=n(6540),a=n(1213),i=n(9532),o=n(4848);const l=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,o.jsx)(l.Provider,{value:a,children:t})}function c(){const e=(0,s.useContext)(l);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,o.jsx)(a.be,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(4164),m=n(4581),h=n(1312),b=n(9022);function v(e){const{previous:t,next:n}=e;return(0,o.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,h.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,o.jsx)(b.A,{...t,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,o.jsx)(b.A,{...n,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}function x(){const{metadata:e}=c();return(0,o.jsx)(v,{previous:e.previous,next:e.next})}var f=n(4586),p=n(8774),g=n(4070),j=n(7559),A=n(3886),L=n(3025);const C={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function N(e){const t=C[e.versionMetadata.banner];return(0,o.jsx)(t,{...e})}function _(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,o.jsx)("b",{children:(0,o.jsx)(p.A,{to:n,onClick:s,children:(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function T(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:s}}=(0,f.A)(),{pluginId:a}=(0,g.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,A.g1)(a),{latestDocSuggestion:l,latestVersionSuggestion:r}=(0,g.HW)(a),c=l??(d=r).docs.find((e=>e.id===d.mainDocId));var d;return(0,o.jsxs)("div",{className:(0,u.A)(t,j.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,o.jsx)("div",{children:(0,o.jsx)(N,{siteTitle:s,versionMetadata:n})}),(0,o.jsx)("div",{className:"margin-top--md",children:(0,o.jsx)(_,{versionLabel:r.label,to:c.path,onClick:()=>i(r.name)})})]})}function k(e){let{className:t}=e;const n=(0,L.r)();return n.banner?(0,o.jsx)(T,{className:t,versionMetadata:n}):null}function H(e){let{className:t}=e;const n=(0,L.r)();return n.badge?(0,o.jsx)("span",{className:(0,u.A)(t,j.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(h.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}var M=n(8046),y=n(4336);function B(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,tags:a}=e,i=a.length>0,l=!!(t||n||s);return i||l?(0,o.jsxs)("footer",{className:(0,u.A)(j.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",j.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(M.A,{tags:a})})}),l&&(0,o.jsx)(y.A,{className:(0,u.A)("margin-top--sm",j.G.docs.docFooterEditMetaRow),editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s})]}):null}var I=n(1422),w=n(5195);const E={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function V(e){let{collapsed:t,...n}=e;return(0,o.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",E.tocCollapsibleButton,!t&&E.tocCollapsibleButtonExpanded,n.className),children:(0,o.jsx)(h.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const O={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function G(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:l}=(0,I.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(O.tocCollapsible,!i&&O.tocCollapsibleExpanded,n),children:[(0,o.jsx)(V,{collapsed:i,onClick:l}),(0,o.jsx)(I.N,{lazy:!0,className:O.tocCollapsibleContent,collapsed:i,children:(0,o.jsx)(w.A,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const S={tocMobile:"tocMobile_ITEo"};function P(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(G,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.A)(j.G.docs.docTocMobile,S.tocMobile)})}var F=n(7763);function R(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(F.A,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:j.G.docs.docTocDesktop})}var U=n(1107),D=n(5533);function z(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,o.jsxs)("div",{className:(0,u.A)(j.G.docs.docMarkdown,"markdown"),children:[n&&(0,o.jsx)("header",{children:(0,o.jsx)(U.A,{as:"h1",children:n})}),(0,o.jsx)(D.A,{children:t})]})}var q=n(6972),$=n(9169),W=n(6025);function Y(e){return(0,o.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,o.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const Z={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function J(){const e=(0,W.Ay)("/");return(0,o.jsx)("li",{className:"breadcrumbs__item",children:(0,o.jsx)(p.A,{"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,o.jsx)(Y,{className:Z.breadcrumbHomeIcon})})})}const K={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function Q(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,o.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,o.jsx)(p.A,{className:a,href:n,itemProp:"item",children:(0,o.jsx)("span",{itemProp:"name",children:t})}):(0,o.jsx)("span",{className:a,children:t})}function X(e){let{children:t,active:n,index:s,addMicrodata:a}=e;return(0,o.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,u.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,o.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function ee(){const e=(0,q.OF)(),t=(0,$.Dt)();return e?(0,o.jsx)("nav",{className:(0,u.A)(j.G.docs.docBreadcrumbs,K.breadcrumbsContainer),"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,o.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,o.jsx)(J,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,o.jsx)(X,{active:s,index:n,addMicrodata:!!a,children:(0,o.jsx)(Q,{href:a,isLast:s,children:t.label})},n)}))]})}):null}var te=n(6896);const ne={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function se(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,o.jsx)(P,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,o.jsx)(R,{})}}(),{metadata:s}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&ne.docItemCol),children:[(0,o.jsx)(te.A,{metadata:s}),(0,o.jsx)(k,{}),(0,o.jsxs)("div",{className:ne.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(ee,{}),(0,o.jsx)(H,{}),n.mobile,(0,o.jsx)(z,{children:t}),(0,o.jsx)(B,{})]}),(0,o.jsx)(x,{})]})]}),n.desktop&&(0,o.jsx)("div",{className:"col col--3",children:n.desktop})]})}function ae(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,o.jsx)(r,{content:e.content,children:(0,o.jsxs)(a.e3,{className:t,children:[(0,o.jsx)(d,{}),(0,o.jsx)(se,{children:(0,o.jsx)(n,{})})]})})}},7763:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var s=n(4164),a=n(5195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var o=n(4848);const l="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,o.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",t),children:(0,o.jsx)(a.A,{...n,linkClassName:l,linkActiveClassName:r})})}},5195:(e,t,n)=>{n.d(t,{A:()=>v});var s=n(6540),a=n(6342);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function o(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=o({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function r(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>l(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:o}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:o}),c=r(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var u=n(8774),m=n(4848);function h(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const b=s.memo(h);function v(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const v=(0,a.p)(),x=c??v.tableOfContents.minHeadingLevel,f=u??v.tableOfContents.maxHeadingLevel,p=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>o({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:x,maxHeadingLevel:f});return d((0,s.useMemo)((()=>{if(l&&r)return{linkClassName:l,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:f}}),[l,r,x,f])),(0,m.jsx)(b,{toc:p,className:n,linkClassName:l,...h})}}}]); \ No newline at end of file diff --git a/docs/assets/js/182d926d.bfd39890.js b/docs/assets/js/182d926d.bfd39890.js new file mode 100644 index 00000000..d296d136 --- /dev/null +++ b/docs/assets/js/182d926d.bfd39890.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[6089],{7193:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"business-cases/give-spontaneous-feedback","title":"Give spontaneous feedback","description":"User story","source":"@site/docs/business-cases/give-spontaneous-feedback.md","sourceDirName":"business-cases","slug":"/business-cases/give-spontaneous-feedback","permalink":"/feedzback/docs/business-cases/give-spontaneous-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/give-spontaneous-feedback.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Reply to feedback request","permalink":"/feedzback/docs/business-cases/reply-to-feedback-request"},"next":{"title":"Feedback draft","permalink":"/feedzback/docs/business-cases/feedback-draft"}}');var c=s(4848),i=s(8453);const a={},r="Give spontaneous feedback",o={},d=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"give-spontaneous-feedback",children:"Give spontaneous feedback"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"As an internal member of the Zenika organisation, I'd like to be able to send spontaneous feedback to a colleague I've worked with.\nIf I can't complete my feedback in one go, I'd like to be able to save it as a draft and continue later."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["Be sure to read ",(0,c.jsx)(n.a,{href:"./request-feedback",children:"Request feedback"})," and ",(0,c.jsx)(n.a,{href:"./reply-to-feedback-request",children:"Reply to feedback request"})," first.\nTo learn more about draft, read the ",(0,c.jsx)(n.a,{href:"./feedback-draft",children:"Feedback draft"})," documentation."]}),"\n",(0,c.jsx)(n.p,{children:"This workflow is much simpler than the feedback request workflow."}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"giverEmail"})," must be authenticated."]}),"\n",(0,c.jsx)(n.p,{children:"Once the feedback is complete, only 1 Firestore document is added:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedback: Feedback = {\n giverEmail: 'gimini@zenika.com',\n receiverEmail: 'pinocchio@zenika.com',\n\n // --------------------------------------\n // In reality, the contents are encrypted\n positive: 'You did great...',\n negative: 'Youd should improve...',\n comment: 'See you...',\n // --------------------------------------\n\n message: '',\n shared: true,\n requested: false, // Meaning it's a spontaneous feedback\n status: 'done',\n createdAt: 1711403799463,\n updatedAt: 1711712182618,\n archived: 0,\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["An email is sent to the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," inviting them to consult the feedback they have just received."]}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"give"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(6540);const c={},i=t.createContext(c);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/182d926d.dd80e658.js b/docs/assets/js/182d926d.dd80e658.js deleted file mode 100644 index b392a0c8..00000000 --- a/docs/assets/js/182d926d.dd80e658.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[89],{7193:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>u,frontMatter:()=>a,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"business-cases/give-spontaneous-feedback","title":"Give spontaneous feedback","description":"User story","source":"@site/docs/business-cases/give-spontaneous-feedback.md","sourceDirName":"business-cases","slug":"/business-cases/give-spontaneous-feedback","permalink":"/feedzback/docs/business-cases/give-spontaneous-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/give-spontaneous-feedback.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Reply to feedback request","permalink":"/feedzback/docs/business-cases/reply-to-feedback-request"},"next":{"title":"Feedback draft","permalink":"/feedzback/docs/business-cases/feedback-draft"}}');var c=s(4848),i=s(8453);const a={},r="Give spontaneous feedback",o={},d=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"give-spontaneous-feedback",children:"Give spontaneous feedback"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"As an internal member of the Zenika organisation, I'd like to be able to send spontaneous feedback to a colleague I've worked with.\nIf I can't complete my feedback in one go, I'd like to be able to save it as a draft and continue later."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["Be sure to read ",(0,c.jsx)(n.a,{href:"./request-feedback",children:"Request feedback"})," and ",(0,c.jsx)(n.a,{href:"./reply-to-feedback-request",children:"Reply to feedback request"})," first.\nTo learn more about draft, read the ",(0,c.jsx)(n.a,{href:"./feedback-draft",children:"Feedback draft"})," documentation."]}),"\n",(0,c.jsx)(n.p,{children:"This workflow is much simpler than the feedback request workflow."}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"giverEmail"})," must be authenticated."]}),"\n",(0,c.jsx)(n.p,{children:"Once the feedback is complete, only 1 Firestore document is added:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedback: Feedback = {\n giverEmail: 'gimini@zenika.com',\n receiverEmail: 'pinocchio@zenika.com',\n\n // --------------------------------------\n // In reality, the contents are encrypted\n positive: 'You did great...',\n negative: 'Youd should improve...',\n comment: 'See you...',\n // --------------------------------------\n\n message: '',\n shared: true,\n requested: false, // Meaning it's a spontaneous feedback\n status: 'done',\n createdAt: 1711403799463,\n updatedAt: 1711712182618,\n archived: 0,\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["An email is sent to the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," inviting them to consult the feedback they have just received."]}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"give"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(6540);const c={},i=t.createContext(c);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/184f8cc3.5c5e9e23.js b/docs/assets/js/184f8cc3.5c5e9e23.js new file mode 100644 index 00000000..27a993f5 --- /dev/null +++ b/docs/assets/js/184f8cc3.5c5e9e23.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[9135],{1504:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"business-cases/request-feedback","title":"Request feedback","description":"User story","source":"@site/docs/business-cases/request-feedback.md","sourceDirName":"business-cases","slug":"/business-cases/request-feedback","permalink":"/feedzback/docs/business-cases/request-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/request-feedback.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Installation","permalink":"/feedzback/docs/installation"},"next":{"title":"Reply to feedback request","permalink":"/feedzback/docs/business-cases/reply-to-feedback-request"}}');var c=s(4848),i=s(8453);const d={},r="Request feedback",a={},l=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"request-feedback",children:"Request feedback"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"As a Zenika employee, I would like to request feedback from colleagues I have worked with, whether they are internal or external to my organisation."}),"\n",(0,c.jsx)(n.p,{children:"Each colleague then receives an email containing a link enabling them to reply to my feedback request."}),"\n",(0,c.jsx)(n.p,{children:"For external colleagues, this link is the only way for them to reply.\nWhereas internal colleagues can also connect to the application and view the list of feedback requests they have received."}),"\n",(0,c.jsx)(n.p,{children:"Once my request has been sent, I would like to view the list of my pending feedback requests."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsx)(n.p,{children:"The requester must be authenticated."}),"\n",(0,c.jsx)(n.p,{children:"The request can be sent to one or more recipients."}),"\n",(0,c.jsx)(n.p,{children:"For each recipient, 2 documents are added to the database:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["A document is added to the ",(0,c.jsx)(n.code,{children:"feedback"})," collection.\nIt contains the details of the request (",(0,c.jsx)(n.code,{children:"giverEmail"}),", ",(0,c.jsx)(n.code,{children:"receiverEmail"}),", ...).\nThe ID of this document is called the ",(0,c.jsx)(n.code,{children:"feedbackId"}),"."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["A document is added to the ",(0,c.jsx)(n.code,{children:"feedbackRequestToken"})," collection.\nIt contains a reference to the ",(0,c.jsx)(n.code,{children:"feedbackId"}),".\nThe ID of this document is called the ",(0,c.jsx)(n.code,{children:"tokenId"}),"."]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"For example, if Pinocchio sends a feedback request to Gimini, the first added document should look like this:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequest: FeedbackRequest = {\n giverEmail: 'gimini@zenika.com',\n receiverEmail: 'pinocchio@zenika.com',\n message: 'Hi Gimini, give me some feedback please.', // In reality, the content is encrypted.\n shared: true,\n requested: true, // Indicates that the feedback was initiated by a request.\n status: 'pending',\n createdAt: 1711403799463,\n updatedAt: 1711403799463,\n archived: 0,\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["From a feedback point of view, the requester is the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," (who will receive the feedback) and the recipient of the request is the ",(0,c.jsx)(n.code,{children:"giverEmail"})," (who will give the feedback)."]}),"\n",(0,c.jsx)(n.p,{children:"The second added document should look like this:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequestToken: FeedbackRequestToken = {\n feedbackId: '123secret';\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"feedbackId"})," is shared between the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," and the ",(0,c.jsx)(n.code,{children:"giverEmail"}),".\nBoth have access to the page:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-txt",children:"/history/id/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"tokenId"}),", on the other hand, is a secret value known only to the ",(0,c.jsx)(n.code,{children:"giverEmail"}),", who can reply to the feedback request by visiting the page:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-txt",children:"/give-requested/token/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Each ",(0,c.jsx)(n.code,{children:"giverEmail"})," receives an email with a link to this page, based on their own ",(0,c.jsx)(n.code,{children:"tokenId"})," allowing them to reply."]}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/request-feedback/request-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"RequestFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"request"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(6540);const c={},i=t.createContext(c);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/184f8cc3.aeef3f35.js b/docs/assets/js/184f8cc3.aeef3f35.js deleted file mode 100644 index 7943e55c..00000000 --- a/docs/assets/js/184f8cc3.aeef3f35.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[135],{1504:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"business-cases/request-feedback","title":"Request feedback","description":"User story","source":"@site/docs/business-cases/request-feedback.md","sourceDirName":"business-cases","slug":"/business-cases/request-feedback","permalink":"/feedzback/docs/business-cases/request-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/request-feedback.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Installation","permalink":"/feedzback/docs/installation"},"next":{"title":"Reply to feedback request","permalink":"/feedzback/docs/business-cases/reply-to-feedback-request"}}');var c=s(4848),i=s(8453);const d={},r="Request feedback",a={},l=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"request-feedback",children:"Request feedback"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"As a Zenika employee, I would like to request feedback from colleagues I have worked with, whether they are internal or external to my organisation."}),"\n",(0,c.jsx)(n.p,{children:"Each colleague then receives an email containing a link enabling them to reply to my feedback request."}),"\n",(0,c.jsx)(n.p,{children:"For external colleagues, this link is the only way for them to reply.\nWhereas internal colleagues can also connect to the application and view the list of feedback requests they have received."}),"\n",(0,c.jsx)(n.p,{children:"Once my request has been sent, I would like to view the list of my pending feedback requests."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsx)(n.p,{children:"The requester must be authenticated."}),"\n",(0,c.jsx)(n.p,{children:"The request can be sent to one or more recipients."}),"\n",(0,c.jsx)(n.p,{children:"For each recipient, 2 documents are added to the database:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["A document is added to the ",(0,c.jsx)(n.code,{children:"feedback"})," collection.\nIt contains the details of the request (",(0,c.jsx)(n.code,{children:"giverEmail"}),", ",(0,c.jsx)(n.code,{children:"receiverEmail"}),", ...).\nThe ID of this document is called the ",(0,c.jsx)(n.code,{children:"feedbackId"}),"."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["A document is added to the ",(0,c.jsx)(n.code,{children:"feedbackRequestToken"})," collection.\nIt contains a reference to the ",(0,c.jsx)(n.code,{children:"feedbackId"}),".\nThe ID of this document is called the ",(0,c.jsx)(n.code,{children:"tokenId"}),"."]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"For example, if Pinocchio sends a feedback request to Gimini, the first added document should look like this:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequest: FeedbackRequest = {\n giverEmail: 'gimini@zenika.com',\n receiverEmail: 'pinocchio@zenika.com',\n message: 'Hi Gimini, give me some feedback please.', // In reality, the content is encrypted.\n shared: true,\n requested: true, // Indicates that the feedback was initiated by a request.\n status: 'pending',\n createdAt: 1711403799463,\n updatedAt: 1711403799463,\n archived: 0,\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["From a feedback point of view, the requester is the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," (who will receive the feedback) and the recipient of the request is the ",(0,c.jsx)(n.code,{children:"giverEmail"})," (who will give the feedback)."]}),"\n",(0,c.jsx)(n.p,{children:"The second added document should look like this:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequestToken: FeedbackRequestToken = {\n feedbackId: '123secret';\n};\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"feedbackId"})," is shared between the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," and the ",(0,c.jsx)(n.code,{children:"giverEmail"}),".\nBoth have access to the page:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-txt",children:"/history/id/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"tokenId"}),", on the other hand, is a secret value known only to the ",(0,c.jsx)(n.code,{children:"giverEmail"}),", who can reply to the feedback request by visiting the page:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-txt",children:"/give-requested/token/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Each ",(0,c.jsx)(n.code,{children:"giverEmail"})," receives an email with a link to this page, based on their own ",(0,c.jsx)(n.code,{children:"tokenId"})," allowing them to reply."]}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/request-feedback/request-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"RequestFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"request"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(6540);const c={},i=t.createContext(c);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/1ccd811d.20587b14.js b/docs/assets/js/1ccd811d.20587b14.js new file mode 100644 index 00000000..dc3cebfd --- /dev/null +++ b/docs/assets/js/1ccd811d.20587b14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[3464],{5528:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"ubiquitous-language","title":"Ubiquitous language","description":"anonymous user","source":"@site/docs/ubiquitous-language.md","sourceDirName":".","slug":"/ubiquitous-language","permalink":"/feedzback/docs/ubiquitous-language","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/ubiquitous-language.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Archiving","permalink":"/feedzback/docs/business-cases/archiving"},"next":{"title":"Overview","permalink":"/feedzback/docs/technical-guides/environments/overview"}}');var i=t(4848),r=t(8453);const d={},a="Ubiquitous language",o={},c=[];function l(e){const n={dd:"dd",dl:"dl",dt:"dt",em:"em",h1:"h1",header:"header",strong:"strong",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"ubiquitous-language",children:"Ubiquitous language"})}),"\n",(0,i.jsxs)(n.dl,{children:[(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"anonymous user"})}),(0,i.jsx)(n.dd,{children:"A user (external or internal to the Zenika organisation) who is authenticated but anonymously. Typically, he/she replies to a feedback request by clicking on the secret link received by email."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"authenticated user"})}),(0,i.jsx)(n.dd,{children:"A user who has authenticated with his Zenika email."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"feedbackId"})}),(0,i.jsxs)(n.dd,{children:["The identifier shared between the ",(0,i.jsx)(n.em,{children:"giverEmail"})," and the ",(0,i.jsx)(n.em,{children:"receiverEmail"})," which provides access to the feedback details."]}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"giverEmail"})}),(0,i.jsx)(n.dd,{children:"The email address of the person giving the feedback (or by extension the person themselves). This person can be internal or external to the Zenika organisation."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"guest user"})}),(0,i.jsx)(n.dd,{children:"A user who is neither authenticated nor anonymous. Typically, they can only access the sign-in page."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"tokenId"})}),(0,i.jsxs)(n.dd,{children:["The secret identifier that enables the ",(0,i.jsx)(n.em,{children:"giverEmail"})," to reply to a feedback request."]}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"receiverEmail"})}),(0,i.jsx)(n.dd,{children:"The email address of the person receiving the feedback (or by extension the person themselves). This person must be internal to the Zenika organisation."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"recipient"})}),(0,i.jsxs)(n.dd,{children:["The recipient of a feedback request. From the feedback point of view, it is the ",(0,i.jsx)(n.em,{children:"giverEmail"}),"."]}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"requester"})}),(0,i.jsxs)(n.dd,{children:["The requester of a feedback request. From the feedback point of view, it is the ",(0,i.jsx)(n.em,{children:"receiverEmail"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>a});var s=t(6540);const i={},r=s.createContext(i);function d(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/1ccd811d.e8123711.js b/docs/assets/js/1ccd811d.e8123711.js deleted file mode 100644 index 615fd4fa..00000000 --- a/docs/assets/js/1ccd811d.e8123711.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[464],{5528:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>d,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"ubiquitous-language","title":"Ubiquitous language","description":"anonymous user","source":"@site/docs/ubiquitous-language.md","sourceDirName":".","slug":"/ubiquitous-language","permalink":"/feedzback/docs/ubiquitous-language","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/ubiquitous-language.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Archiving","permalink":"/feedzback/docs/business-cases/archiving"},"next":{"title":"Overview","permalink":"/feedzback/docs/technical-guides/environments/overview"}}');var i=t(4848),r=t(8453);const d={},a="Ubiquitous language",o={},c=[];function l(e){const n={dd:"dd",dl:"dl",dt:"dt",em:"em",h1:"h1",header:"header",strong:"strong",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"ubiquitous-language",children:"Ubiquitous language"})}),"\n",(0,i.jsxs)(n.dl,{children:[(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"anonymous user"})}),(0,i.jsx)(n.dd,{children:"A user (external or internal to the Zenika organisation) who is authenticated but anonymously. Typically, he/she replies to a feedback request by clicking on the secret link received by email."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"authenticated user"})}),(0,i.jsx)(n.dd,{children:"A user who has authenticated with his Zenika email."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"feedbackId"})}),(0,i.jsxs)(n.dd,{children:["The identifier shared between the ",(0,i.jsx)(n.em,{children:"giverEmail"})," and the ",(0,i.jsx)(n.em,{children:"receiverEmail"})," which provides access to the feedback details."]}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"giverEmail"})}),(0,i.jsx)(n.dd,{children:"The email address of the person giving the feedback (or by extension the person themselves). This person can be internal or external to the Zenika organisation."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"guest user"})}),(0,i.jsx)(n.dd,{children:"A user who is neither authenticated nor anonymous. Typically, they can only access the sign-in page."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"tokenId"})}),(0,i.jsxs)(n.dd,{children:["The secret identifier that enables the ",(0,i.jsx)(n.em,{children:"giverEmail"})," to reply to a feedback request."]}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"receiverEmail"})}),(0,i.jsx)(n.dd,{children:"The email address of the person receiving the feedback (or by extension the person themselves). This person must be internal to the Zenika organisation."}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"recipient"})}),(0,i.jsxs)(n.dd,{children:["The recipient of a feedback request. From the feedback point of view, it is the ",(0,i.jsx)(n.em,{children:"giverEmail"}),"."]}),(0,i.jsx)(n.dt,{children:(0,i.jsx)(n.strong,{children:"requester"})}),(0,i.jsxs)(n.dd,{children:["The requester of a feedback request. From the feedback point of view, it is the ",(0,i.jsx)(n.em,{children:"receiverEmail"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>a});var s=t(6540);const i={},r=s.createContext(i);function d(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/2237.8ed950a7.js b/docs/assets/js/2237.8ed950a7.js new file mode 100644 index 00000000..3e4c3791 --- /dev/null +++ b/docs/assets/js/2237.8ed950a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2237],{3363:(e,t,n)=>{n.d(t,{A:()=>r});n(6540);var i=n(4164),o=n(1312),s=n(1107),a=n(4848);function r(e){let{className:t}=e;return(0,a.jsx)("main",{className:(0,i.A)("container margin-vert--xl",t),children:(0,a.jsx)("div",{className:"row",children:(0,a.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,a.jsx)(s.A,{as:"h1",className:"hero__title",children:(0,a.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,a.jsx)("p",{children:(0,a.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,a.jsx)("p",{children:(0,a.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},2237:(e,t,n)=>{n.r(t),n.d(t,{default:()=>d});n(6540);var i=n(1312),o=n(1213),s=n(781),a=n(3363),r=n(4848);function d(){const e=(0,i.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.be,{title:e}),(0,r.jsx)(s.A,{children:(0,r.jsx)(a.A,{})})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/237.9ce44cb4.js b/docs/assets/js/237.9ce44cb4.js deleted file mode 100644 index bea59048..00000000 --- a/docs/assets/js/237.9ce44cb4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[237],{3363:(e,t,n)=>{n.d(t,{A:()=>r});n(6540);var i=n(4164),o=n(1312),s=n(1107),a=n(4848);function r(e){let{className:t}=e;return(0,a.jsx)("main",{className:(0,i.A)("container margin-vert--xl",t),children:(0,a.jsx)("div",{className:"row",children:(0,a.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,a.jsx)(s.A,{as:"h1",className:"hero__title",children:(0,a.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,a.jsx)("p",{children:(0,a.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,a.jsx)("p",{children:(0,a.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},2237:(e,t,n)=>{n.r(t),n.d(t,{default:()=>d});n(6540);var i=n(1312),o=n(1213),s=n(781),a=n(3363),r=n(4848);function d(){const e=(0,i.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(o.be,{title:e}),(0,r.jsx)(s.A,{children:(0,r.jsx)(a.A,{})})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/296d963c.184ad58c.js b/docs/assets/js/296d963c.184ad58c.js deleted file mode 100644 index 7641e939..00000000 --- a/docs/assets/js/296d963c.184ad58c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[429],{4624:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>r});const c=JSON.parse('{"id":"technical-guides/client/demo","title":"Demo","description":"Some components of the design system are presented in a demo available here:","source":"@site/docs/technical-guides/client/demo.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/demo","permalink":"/feedzback/docs/technical-guides/client/demo","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/demo.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Icons","permalink":"/feedzback/docs/technical-guides/client/icons"},"next":{"title":"Cookies","permalink":"/feedzback/docs/technical-guides/client/cookies"}}');var s=t(4848),o=t(8453);const i={},d="Demo",a={},r=[];function l(e){const n={a:"a",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"demo",children:"Demo"})}),"\n",(0,s.jsx)(n.p,{children:"Some components of the design system are presented in a demo available here:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://feedzback.znk.io/demo",children:"https://feedzback.znk.io/demo"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var c=t(6540);const s={},o=c.createContext(s);function i(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/296d963c.ef2e0318.js b/docs/assets/js/296d963c.ef2e0318.js new file mode 100644 index 00000000..af279c88 --- /dev/null +++ b/docs/assets/js/296d963c.ef2e0318.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[8429],{4624:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>r});const c=JSON.parse('{"id":"technical-guides/client/demo","title":"Demo","description":"Some components of the design system are presented in a demo available here:","source":"@site/docs/technical-guides/client/demo.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/demo","permalink":"/feedzback/docs/technical-guides/client/demo","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/demo.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Icons","permalink":"/feedzback/docs/technical-guides/client/icons"},"next":{"title":"Cookies","permalink":"/feedzback/docs/technical-guides/client/cookies"}}');var s=t(4848),o=t(8453);const i={},d="Demo",a={},r=[];function l(e){const n={a:"a",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"demo",children:"Demo"})}),"\n",(0,s.jsx)(n.p,{children:"Some components of the design system are presented in a demo available here:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://feedzback.znk.io/demo",children:"https://feedzback.znk.io/demo"})}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var c=t(6540);const s={},o=c.createContext(s);function i(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/33a49de8.84b800da.js b/docs/assets/js/33a49de8.84b800da.js deleted file mode 100644 index 18a63a79..00000000 --- a/docs/assets/js/33a49de8.84b800da.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[842],{4479:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"technical-guides/server/swagger","title":"Swagger","description":"Discover the server API via Swagger dev or Swagger staging.","source":"@site/docs/technical-guides/server/swagger.md","sourceDirName":"technical-guides/server","slug":"/technical-guides/server/swagger","permalink":"/feedzback/docs/technical-guides/server/swagger","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/server/swagger.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"i18n","permalink":"/feedzback/docs/technical-guides/client/i18n"},"next":{"title":"Quick start","permalink":"/feedzback/docs/ci-cd/quick-start"}}');var n=t(4848),c=t(8453);const a={},i="Swagger",o={},d=[];function g(e){const r={a:"a",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.header,{children:(0,n.jsx)(r.h1,{id:"swagger",children:"Swagger"})}),"\n",(0,n.jsxs)(r.p,{children:["Discover the server API via ",(0,n.jsx)(r.a,{href:"https://server.dev.feedzback.znk.io/swagger",children:"Swagger dev"})," or ",(0,n.jsx)(r.a,{href:"https://server.staging.feedzback.znk.io/swagger",children:"Swagger staging"}),"."]})]})}function u(e={}){const{wrapper:r}={...(0,c.R)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(g,{...e})}):g(e)}},8453:(e,r,t)=>{t.d(r,{R:()=>a,x:()=>i});var s=t(6540);const n={},c=s.createContext(n);function a(e){const r=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),s.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/33a49de8.d4f6986d.js b/docs/assets/js/33a49de8.d4f6986d.js new file mode 100644 index 00000000..5ce81497 --- /dev/null +++ b/docs/assets/js/33a49de8.d4f6986d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[3842],{4479:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"technical-guides/server/swagger","title":"Swagger","description":"Discover the server API via Swagger dev or Swagger staging.","source":"@site/docs/technical-guides/server/swagger.md","sourceDirName":"technical-guides/server","slug":"/technical-guides/server/swagger","permalink":"/feedzback/docs/technical-guides/server/swagger","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/server/swagger.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"i18n","permalink":"/feedzback/docs/technical-guides/client/i18n"},"next":{"title":"E2E testing","permalink":"/feedzback/docs/technical-guides/e2e-testing"}}');var n=t(4848),c=t(8453);const a={},i="Swagger",o={},d=[];function g(e){const r={a:"a",h1:"h1",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.header,{children:(0,n.jsx)(r.h1,{id:"swagger",children:"Swagger"})}),"\n",(0,n.jsxs)(r.p,{children:["Discover the server API via ",(0,n.jsx)(r.a,{href:"https://server.dev.feedzback.znk.io/swagger",children:"Swagger dev"})," or ",(0,n.jsx)(r.a,{href:"https://server.staging.feedzback.znk.io/swagger",children:"Swagger staging"}),"."]})]})}function l(e={}){const{wrapper:r}={...(0,c.R)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(g,{...e})}):g(e)}},8453:(e,r,t)=>{t.d(r,{R:()=>a,x:()=>i});var s=t(6540);const n={},c=s.createContext(n);function a(e){const r=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),s.createElement(c.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/36994c47.0540eaf1.js b/docs/assets/js/36994c47.0540eaf1.js new file mode 100644 index 00000000..2ef50b8a --- /dev/null +++ b/docs/assets/js/36994c47.0540eaf1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[9858],{5516:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/36994c47.1001b645.js b/docs/assets/js/36994c47.1001b645.js deleted file mode 100644 index 89020781..00000000 --- a/docs/assets/js/36994c47.1001b645.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[858],{5516:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/36f2e543.2e2a5c95.js b/docs/assets/js/36f2e543.2e2a5c95.js new file mode 100644 index 00000000..6900f014 --- /dev/null +++ b/docs/assets/js/36f2e543.2e2a5c95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2137],{1572:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"ci-cd/quick-start","title":"Quick start","description":"This repository includes a fully integrated CI/CD script that works with CircleCI (see .circleci/config.yml).","source":"@site/docs/ci-cd/quick-start.md","sourceDirName":"ci-cd","slug":"/ci-cd/quick-start","permalink":"/feedzback/docs/ci-cd/quick-start","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/ci-cd/quick-start.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"E2E testing","permalink":"/feedzback/docs/technical-guides/e2e-testing"},"next":{"title":"CircleCI","permalink":"/feedzback/docs/ci-cd/circle-ci"}}');var c=i(4848),s=i(8453);const r={},d="Quick start",l={},o=[{value:"On every push to any branch",id:"on-every-push-to-any-branch",level:2},{value:"Dev deployment",id:"dev-deployment",level:2},{value:"Staging deployment",id:"staging-deployment",level:2},{value:"Production deployment",id:"production-deployment",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"quick-start",children:"Quick start"})}),"\n",(0,c.jsxs)(n.p,{children:["This repository includes a fully integrated CI/CD script that works with CircleCI (see ",(0,c.jsx)(n.code,{children:".circleci/config.yml"}),")."]}),"\n",(0,c.jsx)(n.h2,{id:"on-every-push-to-any-branch",children:"On every push to any branch"}),"\n",(0,c.jsx)(n.p,{children:"The CI is configured to check that:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\u2705 ",(0,c.jsx)(n.code,{children:"npm ci"})," works properly"]}),"\n",(0,c.jsx)(n.li,{children:"\u2705 tests are all passing"}),"\n",(0,c.jsx)(n.li,{children:"\u2705 linting has been applied"}),"\n",(0,c.jsx)(n.li,{children:"\u2705 the server and clients build properly"}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"dev-deployment",children:"Dev deployment"}),"\n",(0,c.jsxs)(n.p,{children:["Tagging a revision ",(0,c.jsx)(n.code,{children:"dev-X.Y.Z"})," where ",(0,c.jsx)(n.code,{children:"X"}),", ",(0,c.jsx)(n.code,{children:"Y"}),", and ",(0,c.jsx)(n.code,{children:"Z"})," are integers, the full stack is then deployed to dev:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Server on Google cloud run: ",(0,c.jsx)(n.a,{href:"https://server.dev.feedzback.znk.io/health",children:"dev server health check"})]}),"\n",(0,c.jsxs)(n.li,{children:["Client on Firebase hosting: ",(0,c.jsx)(n.a,{href:"https://dev.feedzback.znk.io",children:"dev client app"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"staging-deployment",children:"Staging deployment"}),"\n",(0,c.jsxs)(n.p,{children:["Tagging a revision ",(0,c.jsx)(n.code,{children:"staging-X.Y.Z"})," where ",(0,c.jsx)(n.code,{children:"X"}),", ",(0,c.jsx)(n.code,{children:"Y"}),", and ",(0,c.jsx)(n.code,{children:"Z"})," are integers, the full stack is then deployed to staging:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Server on Google cloud run: ",(0,c.jsx)(n.a,{href:"https://server.staging.feedzback.znk.io/health",children:"staging server health check"})]}),"\n",(0,c.jsxs)(n.li,{children:["Client on Firebase hosting: ",(0,c.jsx)(n.a,{href:"https://staging.feedzback.znk.io",children:"staging client app"})]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"info",children:(0,c.jsxs)(n.p,{children:["The full stack is also deployed in staging when a commit is pushed on the ",(0,c.jsx)(n.code,{children:"main"})," branch (typically when a pull request is merged)."]})}),"\n",(0,c.jsx)(n.h2,{id:"production-deployment",children:"Production deployment"}),"\n",(0,c.jsxs)(n.p,{children:["On creating a release on ",(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/releases",children:"Github"})," and tagging a revision ",(0,c.jsx)(n.code,{children:"vX.Y.Z"})," where ",(0,c.jsx)(n.code,{children:"X"}),", ",(0,c.jsx)(n.code,{children:"Y"}),", and ",(0,c.jsx)(n.code,{children:"Z"})," are integers), the full stack is then deployed to production:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Server on Google cloud run: ",(0,c.jsx)(n.a,{href:"https://server.feedzback.znk.io/health",children:"production server health check"})]}),"\n",(0,c.jsxs)(n.li,{children:["Client on Firebase hosting: ",(0,c.jsx)(n.a,{href:"https://feedzback.znk.io",children:"production client app"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>d});var t=i(6540);const c={},s=t.createContext(c);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/36f2e543.b576c299.js b/docs/assets/js/36f2e543.b576c299.js deleted file mode 100644 index cea7e0ec..00000000 --- a/docs/assets/js/36f2e543.b576c299.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[137],{1572:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"ci-cd/quick-start","title":"Quick start","description":"This repository includes a fully integrated CI/CD script that works with CircleCI (see .circleci/config.yml).","source":"@site/docs/ci-cd/quick-start.md","sourceDirName":"ci-cd","slug":"/ci-cd/quick-start","permalink":"/feedzback/docs/ci-cd/quick-start","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/ci-cd/quick-start.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Swagger","permalink":"/feedzback/docs/technical-guides/server/swagger"},"next":{"title":"CircleCI","permalink":"/feedzback/docs/ci-cd/circle-ci"}}');var c=i(4848),s=i(8453);const r={},d="Quick start",l={},o=[{value:"On every push to any branch",id:"on-every-push-to-any-branch",level:2},{value:"Dev deployment",id:"dev-deployment",level:2},{value:"Staging deployment",id:"staging-deployment",level:2},{value:"Production deployment",id:"production-deployment",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"quick-start",children:"Quick start"})}),"\n",(0,c.jsxs)(n.p,{children:["This repository includes a fully integrated CI/CD script that works with CircleCI (see ",(0,c.jsx)(n.code,{children:".circleci/config.yml"}),")."]}),"\n",(0,c.jsx)(n.h2,{id:"on-every-push-to-any-branch",children:"On every push to any branch"}),"\n",(0,c.jsx)(n.p,{children:"The CI is configured to check that:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\u2705 ",(0,c.jsx)(n.code,{children:"npm ci"})," works properly"]}),"\n",(0,c.jsx)(n.li,{children:"\u2705 tests are all passing"}),"\n",(0,c.jsx)(n.li,{children:"\u2705 linting has been applied"}),"\n",(0,c.jsx)(n.li,{children:"\u2705 the server and clients build properly"}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"dev-deployment",children:"Dev deployment"}),"\n",(0,c.jsxs)(n.p,{children:["Tagging a revision ",(0,c.jsx)(n.code,{children:"dev-X.Y.Z"})," where ",(0,c.jsx)(n.code,{children:"X"}),", ",(0,c.jsx)(n.code,{children:"Y"}),", and ",(0,c.jsx)(n.code,{children:"Z"})," are integers, the full stack is then deployed to dev:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Server on Google cloud run: ",(0,c.jsx)(n.a,{href:"https://server.dev.feedzback.znk.io/health",children:"dev server health check"})]}),"\n",(0,c.jsxs)(n.li,{children:["Client on Firebase hosting: ",(0,c.jsx)(n.a,{href:"https://dev.feedzback.znk.io",children:"dev client app"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"staging-deployment",children:"Staging deployment"}),"\n",(0,c.jsxs)(n.p,{children:["Tagging a revision ",(0,c.jsx)(n.code,{children:"staging-X.Y.Z"})," where ",(0,c.jsx)(n.code,{children:"X"}),", ",(0,c.jsx)(n.code,{children:"Y"}),", and ",(0,c.jsx)(n.code,{children:"Z"})," are integers, the full stack is then deployed to staging:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Server on Google cloud run: ",(0,c.jsx)(n.a,{href:"https://server.staging.feedzback.znk.io/health",children:"staging server health check"})]}),"\n",(0,c.jsxs)(n.li,{children:["Client on Firebase hosting: ",(0,c.jsx)(n.a,{href:"https://staging.feedzback.znk.io",children:"staging client app"})]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"info",children:(0,c.jsxs)(n.p,{children:["The full stack is also deployed in staging when a commit is pushed on the ",(0,c.jsx)(n.code,{children:"main"})," branch (typically when a pull request is merged)."]})}),"\n",(0,c.jsx)(n.h2,{id:"production-deployment",children:"Production deployment"}),"\n",(0,c.jsxs)(n.p,{children:["On creating a release on ",(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/releases",children:"Github"})," and tagging a revision ",(0,c.jsx)(n.code,{children:"vX.Y.Z"})," where ",(0,c.jsx)(n.code,{children:"X"}),", ",(0,c.jsx)(n.code,{children:"Y"}),", and ",(0,c.jsx)(n.code,{children:"Z"})," are integers), the full stack is then deployed to production:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Server on Google cloud run: ",(0,c.jsx)(n.a,{href:"https://server.feedzback.znk.io/health",children:"production server health check"})]}),"\n",(0,c.jsxs)(n.li,{children:["Client on Firebase hosting: ",(0,c.jsx)(n.a,{href:"https://feedzback.znk.io",children:"production client app"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>d});var t=i(6540);const c={},s=t.createContext(c);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/3b8c55ea.9642f8eb.js b/docs/assets/js/3b8c55ea.9642f8eb.js new file mode 100644 index 00000000..d45281af --- /dev/null +++ b/docs/assets/js/3b8c55ea.9642f8eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[6803],{7248:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"installation","title":"Installation","description":"Permissions","source":"@site/docs/installation.md","sourceDirName":".","slug":"/installation","permalink":"/feedzback/docs/installation","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/installation.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Technical stack","permalink":"/feedzback/docs/technical-stack"},"next":{"title":"Request feedback","permalink":"/feedzback/docs/business-cases/request-feedback"}}');var i=t(4848),l=t(8453);const o={},r="Installation",c={},a=[{value:"Permissions",id:"permissions",level:2},{value:"Server",id:"server",level:2},{value:"Configuration",id:"configuration",level:3},{value:"Installation",id:"installation-1",level:3},{value:"Client",id:"client",level:2},{value:"Installation",id:"installation-2",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"installation",children:"Installation"})}),"\n",(0,i.jsx)(n.h2,{id:"permissions",children:"Permissions"}),"\n",(0,i.jsxs)(n.p,{children:["To configure and run the application locally, you need access to the Firebase project ",(0,i.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-dev",children:"feedzback-v2-dev"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Once you have gained access, you will also be able to access the ",(0,i.jsx)(n.a,{href:"https://console.cloud.google.com/?project=feedzback-v2-dev",children:"Google Cloud console"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"If you don't have permission, please contact Pierre Nicoli or St\xe9phane Francel."})}),"\n",(0,i.jsx)(n.h2,{id:"server",children:"Server"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Open your IDE in ",(0,i.jsx)(n.code,{children:"/server"})," directory"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a ",(0,i.jsx)(n.code,{children:".env"})," file with the following environment variables:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SERVER_PORT=3000\n\nCLIENT_URL=http://localhost:4200\n\nFIREBASE_PROJECT_ID=feedzback-v2-dev\nFIREBASE_PRIVATE_KEY=\nFIREBASE_CLIENT_EMAIL=\n\nMAILGUN_USERNAME=\nMAILGUN_KEY=\nMAILGUN_URL=\nMAILGUN_DOMAIN=\n\nCRYPTO_SECRET_IV=feedzback\nCRYPTO_SECRET_KEY=feedzback\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Retrieve these secret values from the ",(0,i.jsx)(n.a,{href:"https://console.cloud.google.com/run/deploy/europe-west1/feedzback-server?project=feedzback-v2-dev",children:"Google Cloud Run console"}),' (tab "Variables and Secrets").']}),"\n",(0,i.jsx)(n.h3,{id:"installation-1",children:"Installation"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Run the following commands:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'npm install\nnpm run start:dev # Start the server in "watch" mode\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Visit the URL ",(0,i.jsx)(n.a,{href:"http://localhost:3000",children:"http://localhost:3000"})," to check that the server is running properly."]}),"\n",(0,i.jsxs)(n.admonition,{type:"tip",children:[(0,i.jsxs)(n.p,{children:['If you just need to start the server once (without "watch" mode), run the command ',(0,i.jsx)(n.code,{children:"npm start"})," from the ",(0,i.jsx)(n.code,{children:"/server"})," directory."]}),(0,i.jsxs)(n.p,{children:["Running the command ",(0,i.jsx)(n.code,{children:"npm run server"})," from the ",(0,i.jsx)(n.code,{children:"/client"})," directory will have the same effect."]})]}),"\n",(0,i.jsx)(n.h2,{id:"client",children:"Client"}),"\n",(0,i.jsx)(n.h3,{id:"installation-2",children:"Installation"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Open your IDE in ",(0,i.jsx)(n.code,{children:"/client"})," directory"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run the following commands:"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'npm install\nnpm start # Start the client in "watch" mode\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Finally, visit the URL ",(0,i.jsx)(n.a,{href:"http://localhost:4200",children:"http://localhost:4200"})," and enjoy FeedZback! \ud83d\ude80"]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Please refer to ",(0,i.jsx)(n.a,{href:"/docs/technical-guides/environments/local-dev",children:"Local dev environment"})," for other ways to launch the application."]})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(6540);const i={},l=s.createContext(i);function o(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/3b8c55ea.fe0f4690.js b/docs/assets/js/3b8c55ea.fe0f4690.js deleted file mode 100644 index 89a5cbf6..00000000 --- a/docs/assets/js/3b8c55ea.fe0f4690.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[803],{7248:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>r});const l=JSON.parse('{"id":"installation","title":"Installation","description":"Permissions","source":"@site/docs/installation.md","sourceDirName":".","slug":"/installation","permalink":"/feedzback/docs/installation","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/installation.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Technical stack","permalink":"/feedzback/docs/technical-stack"},"next":{"title":"Request feedback","permalink":"/feedzback/docs/business-cases/request-feedback"}}');var i=s(4848),t=s(8453);const o={},a="Installation",c={},r=[{value:"Permissions",id:"permissions",level:2},{value:"Server",id:"server",level:2},{value:"Configuration",id:"configuration",level:3},{value:"Installation",id:"installation-1",level:3},{value:"Client",id:"client",level:2},{value:"Installation",id:"installation-2",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"installation",children:"Installation"})}),"\n",(0,i.jsx)(n.h2,{id:"permissions",children:"Permissions"}),"\n",(0,i.jsxs)(n.p,{children:["To configure and run the application locally, you need access to the Firebase project ",(0,i.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-dev",children:"feedzback-v2-dev"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Once you have gained access, you will also be able to access the ",(0,i.jsx)(n.a,{href:"https://console.cloud.google.com/?project=feedzback-v2-dev",children:"Google Cloud console"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"If you don't have permission, please contact Pierre Nicoli or St\xe9phane Francel."})}),"\n",(0,i.jsx)(n.h2,{id:"server",children:"Server"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Open your IDE in ",(0,i.jsx)(n.code,{children:"./server"})," directory"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create a ",(0,i.jsx)(n.code,{children:".env"})," file with the following environment variables:"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SERVER_PORT=3000\n\nCLIENT_URL=http://localhost:4200\n\nFIREBASE_PROJECT_ID=feedzback-v2-dev\nFIREBASE_PRIVATE_KEY=\nFIREBASE_CLIENT_EMAIL=\n\nMAILGUN_USERNAME=\nMAILGUN_KEY=\nMAILGUN_URL=\nMAILGUN_DOMAIN=\n\nCRYPTO_SECRET_IV=feedzback\nCRYPTO_SECRET_KEY=feedzback\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Retrieve these secret values from the ",(0,i.jsx)(n.a,{href:"https://console.cloud.google.com/run/deploy/europe-west1/feedzback-server?project=feedzback-v2-dev",children:"Google Cloud Run console"}),' (tab "Variables and Secrets").']}),"\n",(0,i.jsx)(n.h3,{id:"installation-1",children:"Installation"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Run the following commands:"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"npm install\nnpm run start:dev\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client",children:"Client"}),"\n",(0,i.jsx)(n.h3,{id:"installation-2",children:"Installation"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Open your IDE in ",(0,i.jsx)(n.code,{children:"./client"})," directory"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Run the following commands:"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"npm install\nnpm start\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Finally, visit the URL ",(0,i.jsx)(n.a,{href:"http://localhost:4200",children:"http://localhost:4200"})," and enjoy FeedZback! \ud83d\ude80"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var l=s(6540);const i={},t=l.createContext(i);function o(e){const n=l.useContext(t);return l.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),l.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/470ecfa7.54c33973.js b/docs/assets/js/470ecfa7.54c33973.js deleted file mode 100644 index bc232405..00000000 --- a/docs/assets/js/470ecfa7.54c33973.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[238],{8280:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"technical-guides/environments/overview","title":"Overview","description":"There are 3 remote environments: production, staging and development.","source":"@site/docs/technical-guides/environments/overview.md","sourceDirName":"technical-guides/environments","slug":"/technical-guides/environments/overview","permalink":"/feedzback/docs/technical-guides/environments/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/environments/overview.md","tags":[],"version":"current","frontMatter":{"title":"Overview"},"sidebar":"default","previous":{"title":"Ubiquitous language","permalink":"/feedzback/docs/ubiquitous-language"},"next":{"title":"Local","permalink":"/feedzback/docs/technical-guides/environments/local"}}');var r=s(4848),t=s(8453);const o={title:"Overview"},c="Environments",l={},d=[{value:"Auth providers",id:"auth-providers",level:2},{value:"MailGun",id:"mailgun",level:2},{value:"URLs",id:"urls",level:2},{value:"Production",id:"production",level:3},{value:"Staging",id:"staging",level:3},{value:"Development",id:"development",level:3}];function a(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"environments",children:"Environments"})}),"\n",(0,r.jsxs)(n.p,{children:["There are 3 remote environments: ",(0,r.jsx)(n.code,{children:"production"}),", ",(0,r.jsx)(n.code,{children:"staging"})," and ",(0,r.jsx)(n.code,{children:"development"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"auth-providers",children:"Auth providers"}),"\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.em,{children:"production"})," and ",(0,r.jsx)(n.em,{children:"staging"})," environments, only ",(0,r.jsx)(n.strong,{children:"Google Auth"})," provider is enabled."]}),"\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.em,{children:"development"})," environment, both ",(0,r.jsx)(n.strong,{children:"Google Auth"})," and ",(0,r.jsx)(n.strong,{children:"Email/Password"})," providers are enabled.\nThis lets you create users on the fly (from the Firebase console) to test easily the sending and receiving of feedZbacks."]}),"\n",(0,r.jsx)(n.h2,{id:"mailgun",children:"MailGun"}),"\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.em,{children:"staging"})," and ",(0,r.jsx)(n.em,{children:"development"})," environments, MailGun service sends all emails to a unique recipient.\nThese emails can be viewed from the following mailing list:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://groups.google.com/a/zenika.com/g/feedzback",children:"https://groups.google.com/a/zenika.com/g/feedzback"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"urls",children:"URLs"}),"\n",(0,r.jsx)(n.h3,{id:"production",children:"Production"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Client app:"})," ",(0,r.jsx)(n.a,{href:"https://feedzback.znk.io",children:"https://feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Server app:"})," ",(0,r.jsx)(n.a,{href:"https://server.feedzback.znk.io",children:"https://server.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Firebase console:"})," ",(0,r.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2",children:"https://console.firebase.google.com/project/feedzback-v2"})]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"staging",children:"Staging"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Client app:"})," ",(0,r.jsx)(n.a,{href:"https://staging.feedzback.znk.io",children:"https://staging.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Server app:"})," ",(0,r.jsx)(n.a,{href:"https://server.staging.feedzback.znk.io",children:"https://server.staging.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Firebase console:"})," ",(0,r.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-staging",children:"https://console.firebase.google.com/project/feedzback-v2-staging"})]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"development",children:"Development"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Client app:"})," ",(0,r.jsx)(n.a,{href:"https://dev.feedzback.znk.io",children:"https://dev.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Server app:"})," ",(0,r.jsx)(n.a,{href:"https://server.dev.feedzback.znk.io",children:"https://server.dev.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Firebase console:"})," ",(0,r.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-dev",children:"https://console.firebase.google.com/project/feedzback-v2-dev"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var i=s(6540);const r={},t=i.createContext(r);function o(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/470ecfa7.b8082308.js b/docs/assets/js/470ecfa7.b8082308.js new file mode 100644 index 00000000..27b1f230 --- /dev/null +++ b/docs/assets/js/470ecfa7.b8082308.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[238],{8280:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"technical-guides/environments/overview","title":"Overview","description":"There are 3 remote environments: production, staging and development.","source":"@site/docs/technical-guides/environments/overview.md","sourceDirName":"technical-guides/environments","slug":"/technical-guides/environments/overview","permalink":"/feedzback/docs/technical-guides/environments/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/environments/overview.md","tags":[],"version":"current","frontMatter":{"title":"Overview"},"sidebar":"default","previous":{"title":"Ubiquitous language","permalink":"/feedzback/docs/ubiquitous-language"},"next":{"title":"Local dev","permalink":"/feedzback/docs/technical-guides/environments/local-dev"}}');var r=s(4848),t=s(8453);const o={title:"Overview"},c="Environments",l={},d=[{value:"Auth providers",id:"auth-providers",level:2},{value:"MailGun",id:"mailgun",level:2},{value:"URLs",id:"urls",level:2},{value:"Production",id:"production",level:3},{value:"Staging",id:"staging",level:3},{value:"Development",id:"development",level:3}];function a(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"environments",children:"Environments"})}),"\n",(0,r.jsxs)(n.p,{children:["There are 3 remote environments: ",(0,r.jsx)(n.code,{children:"production"}),", ",(0,r.jsx)(n.code,{children:"staging"})," and ",(0,r.jsx)(n.code,{children:"development"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"auth-providers",children:"Auth providers"}),"\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.em,{children:"production"})," and ",(0,r.jsx)(n.em,{children:"staging"})," environments, only ",(0,r.jsx)(n.strong,{children:"Google Auth"})," provider is enabled."]}),"\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.em,{children:"development"})," environment, both ",(0,r.jsx)(n.strong,{children:"Google Auth"})," and ",(0,r.jsx)(n.strong,{children:"Email/Password"})," providers are enabled.\nThis lets you create users on the fly (from the Firebase console) to test easily the sending and receiving of feedZbacks."]}),"\n",(0,r.jsx)(n.h2,{id:"mailgun",children:"MailGun"}),"\n",(0,r.jsxs)(n.p,{children:["In ",(0,r.jsx)(n.em,{children:"staging"})," and ",(0,r.jsx)(n.em,{children:"development"})," environments, MailGun service sends all emails to a unique recipient.\nThese emails can be viewed from the following mailing list:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://groups.google.com/a/zenika.com/g/feedzback",children:"https://groups.google.com/a/zenika.com/g/feedzback"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"urls",children:"URLs"}),"\n",(0,r.jsx)(n.h3,{id:"production",children:"Production"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Client app:"})," ",(0,r.jsx)(n.a,{href:"https://feedzback.znk.io",children:"https://feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Server app:"})," ",(0,r.jsx)(n.a,{href:"https://server.feedzback.znk.io",children:"https://server.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Firebase console:"})," ",(0,r.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2",children:"https://console.firebase.google.com/project/feedzback-v2"})]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"staging",children:"Staging"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Client app:"})," ",(0,r.jsx)(n.a,{href:"https://staging.feedzback.znk.io",children:"https://staging.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Server app:"})," ",(0,r.jsx)(n.a,{href:"https://server.staging.feedzback.znk.io",children:"https://server.staging.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Firebase console:"})," ",(0,r.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-staging",children:"https://console.firebase.google.com/project/feedzback-v2-staging"})]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"development",children:"Development"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Client app:"})," ",(0,r.jsx)(n.a,{href:"https://dev.feedzback.znk.io",children:"https://dev.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Server app:"})," ",(0,r.jsx)(n.a,{href:"https://server.dev.feedzback.znk.io",children:"https://server.dev.feedzback.znk.io"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Firebase console:"})," ",(0,r.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-dev",children:"https://console.firebase.google.com/project/feedzback-v2-dev"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var i=s(6540);const r={},t=i.createContext(r);function o(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/4a707512.6d9ace13.js b/docs/assets/js/4a707512.6d9ace13.js deleted file mode 100644 index 01b789dc..00000000 --- a/docs/assets/js/4a707512.6d9ace13.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[102],{5931:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>t});const c=JSON.parse('{"id":"ci-cd/circle-ci","title":"CircleCI","description":"Pre-requisites","source":"@site/docs/ci-cd/circle-ci.md","sourceDirName":"ci-cd","slug":"/ci-cd/circle-ci","permalink":"/feedzback/docs/ci-cd/circle-ci","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/ci-cd/circle-ci.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Quick start","permalink":"/feedzback/docs/ci-cd/quick-start"},"next":{"title":"Usage analytics","permalink":"/feedzback/docs/usage-analytics"}}');var l=i(4848),o=i(8453);const d={},s="CircleCI",r={},t=[{value:"Pre-requisites",id:"pre-requisites",level:2},{value:"Firebase & co",id:"firebase--co",level:3},{value:"GCP APIs to enable",id:"gcp-apis-to-enable",level:3},{value:"Service account setup",id:"service-account-setup",level:3},{value:"Google artifact repository",id:"google-artifact-repository",level:3},{value:"Domain mapping",id:"domain-mapping",level:3},{value:"IAM",id:"iam",level:3},{value:"Environment variables",id:"environment-variables",level:2},{value:"Google Cloud Platform",id:"google-cloud-platform",level:3},{value:"GCLOUD_SERVICE_KEY",id:"gcloud_service_key",level:4},{value:"GOOGLE_COMPUTE_ZONE",id:"google_compute_zone",level:4},{value:"GOOGLE_PROJECT_ID",id:"google_project_id",level:4},{value:"Firebase",id:"firebase",level:3},{value:"FIREBASE_TOKEN",id:"firebase_token",level:4},{value:"FIREBASE_PROJECT_ID",id:"firebase_project_id",level:4},{value:"FIREBASE_CLIENT_EMAIL",id:"firebase_client_email",level:4},{value:"FIREBASE_PRIVATE_KEY",id:"firebase_private_key",level:4},{value:"Mailgun",id:"mailgun",level:3},{value:"MAILGUN_URL",id:"mailgun_url",level:4},{value:"MAILGUN_USERNAME",id:"mailgun_username",level:4},{value:"MAILGUN_KEY",id:"mailgun_key",level:4},{value:"MAILGUN_DOMAIN",id:"mailgun_domain",level:4},{value:"Crypto",id:"crypto",level:3},{value:"CRYPTO_SECRET_KEY & CRYPTO_SECRET_IV",id:"crypto_secret_key--crypto_secret_iv",level:4},{value:"Node",id:"node",level:3},{value:"NODE_ENV",id:"node_env",level:4},{value:"App",id:"app",level:3},{value:"SERVER_PORT",id:"server_port",level:4},{value:"CLIENT_URL",id:"client_url",level:4},{value:"Usage analytics",id:"usage-analytics",level:2},{value:"Links",id:"links",level:2},{value:"Development (feedzback-v2-dev) \ud83d\udea7",id:"development-feedzback-v2-dev-",level:3},{value:"Staging (feedzback-v2-staging) \ud83d\ude80",id:"staging-feedzback-v2-staging-",level:3},{value:"Production (feedzback-v2) \ud83c\udfac",id:"production-feedzback-v2-",level:3}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"circleci",children:"CircleCI"})}),"\n",(0,l.jsx)(n.h2,{id:"pre-requisites",children:"Pre-requisites"}),"\n",(0,l.jsx)(n.h3,{id:"firebase--co",children:"Firebase & co"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"The Firebase project must be created"}),"\n",(0,l.jsx)(n.li,{children:"A Firestore database must be defined in the project"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"gcp-apis-to-enable",children:"GCP APIs to enable"}),"\n",(0,l.jsx)(n.p,{children:"The following APIs must be enabled on the linked GCP Project (which is automatically created when you create a Firebase project):"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/cloudbuild.googleapis.com",children:"Cloud Build API"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/run.googleapis.com",children:"Cloud Run API"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"service-account-setup",children:"Service account setup"}),"\n",(0,l.jsxs)(n.p,{children:["A specific service account to build and deploy needs to exist on the project (used ",(0,l.jsx)(n.a,{href:"#gcloud_service_key",children:"here"}),")."]}),"\n",(0,l.jsx)(n.h3,{id:"google-artifact-repository",children:"Google artifact repository"}),"\n",(0,l.jsxs)(n.p,{children:["The GCP Project needs to have a Docker ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/artifacts",children:"Google Artifact Repository"})," created named ",(0,l.jsx)(n.code,{children:"builds"})," for the CI to work properly."]}),"\n",(0,l.jsx)(n.h3,{id:"domain-mapping",children:"Domain mapping"}),"\n",(0,l.jsxs)(n.p,{children:["This can be done after a first deployment: through ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/run/domains",children:"Domain mappings in GCP"})," (for the server), and Firebase console (for the client)."]}),"\n",(0,l.jsx)(n.h3,{id:"iam",children:"IAM"}),"\n",(0,l.jsx)(n.p,{children:"It requires a few privileges as well:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Artifact Registry Writer"}),"\n",(0,l.jsx)(n.li,{children:"Cloud Build Service Account"}),"\n",(0,l.jsx)(n.li,{children:"Cloud Run Admin"}),"\n",(0,l.jsx)(n.li,{children:"Firebase Hosting Admin"}),"\n",(0,l.jsx)(n.li,{children:"Project Editor (aka Basic > Editor)"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"environment-variables",children:"Environment variables"}),"\n",(0,l.jsx)(n.p,{children:"Environment variables are provided by a CircleCI Context (feedzback-dev for dev, feedzback-staging for staging, feedzback-production for production)."}),"\n",(0,l.jsx)(n.h3,{id:"google-cloud-platform",children:"Google Cloud Platform"}),"\n",(0,l.jsx)(n.p,{children:"These settings are used to build and deploy the server on the GCP Project as a Google Cloud Run managed service."}),"\n",(0,l.jsx)(n.h4,{id:"gcloud_service_key",children:(0,l.jsx)(n.code,{children:"GCLOUD_SERVICE_KEY"})}),"\n",(0,l.jsxs)(n.p,{children:["Full JSON service key linked to the Service Account allowed to build and run the server on the GCP Project.\nIt is also used as the main authentication method for the Firebase CLI during client deployment as ",(0,l.jsx)(n.a,{href:"#firebase_token",children:"FIREBASE_TOKEN"})," usage will be decomissioned in the next major version."]}),"\n",(0,l.jsx)(n.h4,{id:"google_compute_zone",children:(0,l.jsx)(n.code,{children:"GOOGLE_COMPUTE_ZONE"})}),"\n",(0,l.jsx)(n.p,{children:"Default compute zone to use (europe-west1 usually)."}),"\n",(0,l.jsx)(n.h4,{id:"google_project_id",children:(0,l.jsx)(n.code,{children:"GOOGLE_PROJECT_ID"})}),"\n",(0,l.jsx)(n.p,{children:"Self-reference to the Project (used by the CircleCI orb to properly handle resources)."}),"\n",(0,l.jsx)(n.h3,{id:"firebase",children:"Firebase"}),"\n",(0,l.jsx)(n.h4,{id:"firebase_token",children:(0,l.jsx)(n.code,{children:"FIREBASE_TOKEN"})}),"\n",(0,l.jsxs)(n.p,{children:["Token used only by CI to connect to Firebase and deploy the client. Was generated following this ",(0,l.jsx)(n.a,{href:"https://firebase.google.com/docs/cli?authuser=0#cli-ci-systems",children:"documentation"})]}),"\n",(0,l.jsx)(n.h4,{id:"firebase_project_id",children:(0,l.jsx)(n.code,{children:"FIREBASE_PROJECT_ID"})}),"\n",(0,l.jsx)(n.p,{children:"Identifier of the Firebase project."}),"\n",(0,l.jsx)(n.h4,{id:"firebase_client_email",children:(0,l.jsx)(n.code,{children:"FIREBASE_CLIENT_EMAIL"})}),"\n",(0,l.jsx)(n.p,{children:"Identifier used to authenticate against the Firebase stack. Found in the Firebase console."}),"\n",(0,l.jsx)(n.h4,{id:"firebase_private_key",children:(0,l.jsx)(n.code,{children:"FIREBASE_PRIVATE_KEY"})}),"\n",(0,l.jsx)(n.p,{children:"A Service Account must be defined with the proper key. The private key used in the FIREBASE_PRIVATE_KEY environment variable needs to be base64 encoded."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Using bash:"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'echo "content_of_private_key_field_in_json_key" | base64\n'})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Using Node.js:"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-js",children:"Buffer.from('content_of_private_key_field_in_json_key').toString('base64');\n"})}),"\n",(0,l.jsx)(n.h3,{id:"mailgun",children:"Mailgun"}),"\n",(0,l.jsxs)(n.p,{children:["These are injected in the Cloud Run container in order to properly use Mailgun to send emails and notifications.\nOn dev and staging, a sandbox account is used that redirects any sent email to ",(0,l.jsx)(n.a,{href:"mailto:feedzback@zenika.com",children:"feedzback@zenika.com"}),"."]}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_url",children:(0,l.jsx)(n.code,{children:"MAILGUN_URL"})}),"\n",(0,l.jsx)(n.p,{children:"The mailgun endpoint to use to connect to mailgun sending server."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["for sandbox mailgun account: ",(0,l.jsx)(n.code,{children:"https://api.mailgun.net"})]}),"\n",(0,l.jsxs)(n.li,{children:["for production account (which is in EU): ",(0,l.jsx)(n.code,{children:"https://api.eu.mailgun.net"})]}),"\n"]}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_username",children:(0,l.jsx)(n.code,{children:"MAILGUN_USERNAME"})}),"\n",(0,l.jsx)(n.p,{children:"The Mailgun API username (needs to match the domain of the key)."}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_key",children:(0,l.jsx)(n.code,{children:"MAILGUN_KEY"})}),"\n",(0,l.jsx)(n.p,{children:"An API secret defined on the mailgun platform that allows to send email."}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_domain",children:(0,l.jsx)(n.code,{children:"MAILGUN_DOMAIN"})}),"\n",(0,l.jsxs)(n.p,{children:["The domain associated with the account.\nUse the sandbox username as the domain (",(0,l.jsx)(n.code,{children:"sandbox8d21179029774bb29c92557ea6ab0d88.mailgun.org"}),").\nIn production should be ",(0,l.jsx)(n.code,{children:"feedzback.znk.io"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"crypto",children:"Crypto"}),"\n",(0,l.jsxs)(n.h4,{id:"crypto_secret_key--crypto_secret_iv",children:[(0,l.jsx)(n.code,{children:"CRYPTO_SECRET_KEY"})," & ",(0,l.jsx)(n.code,{children:"CRYPTO_SECRET_IV"})]}),"\n",(0,l.jsx)(n.p,{children:"Used to encrypt/decrypt sensitives data in the Firestore database."}),"\n",(0,l.jsxs)(n.p,{children:["In dev and staging set their values to: ",(0,l.jsx)(n.code,{children:"feedzback"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"node",children:"Node"}),"\n",(0,l.jsx)(n.h4,{id:"node_env",children:(0,l.jsx)(n.code,{children:"NODE_ENV"})}),"\n",(0,l.jsxs)(n.p,{children:["Should be ",(0,l.jsx)(n.code,{children:"production"})," for production environment, otherwise all mails will be sent to ",(0,l.jsx)(n.code,{children:"feedzback@zenika.com"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"app",children:"App"}),"\n",(0,l.jsx)(n.h4,{id:"server_port",children:(0,l.jsx)(n.code,{children:"SERVER_PORT"})}),"\n",(0,l.jsx)(n.p,{children:"The port on which the server is listening."}),"\n",(0,l.jsx)(n.h4,{id:"client_url",children:(0,l.jsx)(n.code,{children:"CLIENT_URL"})}),"\n",(0,l.jsx)(n.p,{children:"This helps the server compose URLs to include in emails."}),"\n",(0,l.jsx)(n.h2,{id:"usage-analytics",children:"Usage analytics"}),"\n",(0,l.jsxs)(n.p,{children:["Usage analytics can be set up using ",(0,l.jsx)(n.a,{href:"/docs/usage-analytics",children:"these instructions"})]}),"\n",(0,l.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,l.jsx)(n.h3,{id:"development-feedzback-v2-dev-",children:"Development (feedzback-v2-dev) \ud83d\udea7"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-dev",children:"Firebase console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/home/dashboard?hl=en&project=feedzback-v2-dev",children:"GCP console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://app.circleci.com/settings/organization/github/Zenika/contexts/686ad410-3bba-4c59-a904-da3fe737eaa3?return-to=%2F",children:"CircleCI context"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"staging-feedzback-v2-staging-",children:"Staging (feedzback-v2-staging) \ud83d\ude80"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-staging",children:"Firebase console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/home/dashboard?hl=en&project=feedzback-v2-staging",children:"GCP console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://app.circleci.com/settings/organization/github/Zenika/contexts/489bddb3-fe2e-465e-91f9-b9ba7a155e0d?return-to=%2F",children:"CircleCI context"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"production-feedzback-v2-",children:"Production (feedzback-v2) \ud83c\udfac"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2",children:"Firebase console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/home/dashboard?hl=en&project=feedzback-v2",children:"GCP console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://app.circleci.com/settings/organization/github/Zenika/contexts/3b5ca05f-7180-479e-9225-9902e29cde9b?return-to=%2F",children:"CircleCI context"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>s});var c=i(6540);const l={},o=c.createContext(l);function d(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:d(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/4a707512.8b3cf068.js b/docs/assets/js/4a707512.8b3cf068.js new file mode 100644 index 00000000..762acdba --- /dev/null +++ b/docs/assets/js/4a707512.8b3cf068.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[6102],{5931:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>t});const c=JSON.parse('{"id":"ci-cd/circle-ci","title":"CircleCI","description":"Pre-requisites","source":"@site/docs/ci-cd/circle-ci.md","sourceDirName":"ci-cd","slug":"/ci-cd/circle-ci","permalink":"/feedzback/docs/ci-cd/circle-ci","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/ci-cd/circle-ci.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Quick start","permalink":"/feedzback/docs/ci-cd/quick-start"},"next":{"title":"Usage analytics","permalink":"/feedzback/docs/usage-analytics"}}');var l=i(4848),o=i(8453);const d={},s="CircleCI",r={},t=[{value:"Pre-requisites",id:"pre-requisites",level:2},{value:"Firebase & co",id:"firebase--co",level:3},{value:"GCP APIs to enable",id:"gcp-apis-to-enable",level:3},{value:"Service account setup",id:"service-account-setup",level:3},{value:"Google artifact repository",id:"google-artifact-repository",level:3},{value:"Domain mapping",id:"domain-mapping",level:3},{value:"IAM",id:"iam",level:3},{value:"Environment variables",id:"environment-variables",level:2},{value:"Google Cloud Platform",id:"google-cloud-platform",level:3},{value:"GCLOUD_SERVICE_KEY",id:"gcloud_service_key",level:4},{value:"GOOGLE_COMPUTE_ZONE",id:"google_compute_zone",level:4},{value:"GOOGLE_PROJECT_ID",id:"google_project_id",level:4},{value:"Firebase",id:"firebase",level:3},{value:"FIREBASE_TOKEN",id:"firebase_token",level:4},{value:"FIREBASE_PROJECT_ID",id:"firebase_project_id",level:4},{value:"FIREBASE_CLIENT_EMAIL",id:"firebase_client_email",level:4},{value:"FIREBASE_PRIVATE_KEY",id:"firebase_private_key",level:4},{value:"Mailgun",id:"mailgun",level:3},{value:"MAILGUN_URL",id:"mailgun_url",level:4},{value:"MAILGUN_USERNAME",id:"mailgun_username",level:4},{value:"MAILGUN_KEY",id:"mailgun_key",level:4},{value:"MAILGUN_DOMAIN",id:"mailgun_domain",level:4},{value:"Crypto",id:"crypto",level:3},{value:"CRYPTO_SECRET_KEY & CRYPTO_SECRET_IV",id:"crypto_secret_key--crypto_secret_iv",level:4},{value:"Node",id:"node",level:3},{value:"NODE_ENV",id:"node_env",level:4},{value:"App",id:"app",level:3},{value:"SERVER_PORT",id:"server_port",level:4},{value:"CLIENT_URL",id:"client_url",level:4},{value:"Usage analytics",id:"usage-analytics",level:2},{value:"Links",id:"links",level:2},{value:"Development (feedzback-v2-dev) \ud83d\udea7",id:"development-feedzback-v2-dev-",level:3},{value:"Staging (feedzback-v2-staging) \ud83d\ude80",id:"staging-feedzback-v2-staging-",level:3},{value:"Production (feedzback-v2) \ud83c\udfac",id:"production-feedzback-v2-",level:3}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"circleci",children:"CircleCI"})}),"\n",(0,l.jsx)(n.h2,{id:"pre-requisites",children:"Pre-requisites"}),"\n",(0,l.jsx)(n.h3,{id:"firebase--co",children:"Firebase & co"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"The Firebase project must be created"}),"\n",(0,l.jsx)(n.li,{children:"A Firestore database must be defined in the project"}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"gcp-apis-to-enable",children:"GCP APIs to enable"}),"\n",(0,l.jsx)(n.p,{children:"The following APIs must be enabled on the linked GCP Project (which is automatically created when you create a Firebase project):"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/cloudbuild.googleapis.com",children:"Cloud Build API"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/apis/library/run.googleapis.com",children:"Cloud Run API"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"service-account-setup",children:"Service account setup"}),"\n",(0,l.jsxs)(n.p,{children:["A specific service account to build and deploy needs to exist on the project (used ",(0,l.jsx)(n.a,{href:"#gcloud_service_key",children:"here"}),")."]}),"\n",(0,l.jsx)(n.h3,{id:"google-artifact-repository",children:"Google artifact repository"}),"\n",(0,l.jsxs)(n.p,{children:["The GCP Project needs to have a Docker ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/artifacts",children:"Google Artifact Repository"})," created named ",(0,l.jsx)(n.code,{children:"builds"})," for the CI to work properly."]}),"\n",(0,l.jsx)(n.h3,{id:"domain-mapping",children:"Domain mapping"}),"\n",(0,l.jsxs)(n.p,{children:["This can be done after a first deployment: through ",(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/run/domains",children:"Domain mappings in GCP"})," (for the server), and Firebase console (for the client)."]}),"\n",(0,l.jsx)(n.h3,{id:"iam",children:"IAM"}),"\n",(0,l.jsx)(n.p,{children:"It requires a few privileges as well:"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Artifact Registry Writer"}),"\n",(0,l.jsx)(n.li,{children:"Cloud Build Service Account"}),"\n",(0,l.jsx)(n.li,{children:"Cloud Run Admin"}),"\n",(0,l.jsx)(n.li,{children:"Firebase Hosting Admin"}),"\n",(0,l.jsx)(n.li,{children:"Project Editor (aka Basic > Editor)"}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"environment-variables",children:"Environment variables"}),"\n",(0,l.jsx)(n.p,{children:"Environment variables are provided by a CircleCI Context (feedzback-dev for dev, feedzback-staging for staging, feedzback-production for production)."}),"\n",(0,l.jsx)(n.h3,{id:"google-cloud-platform",children:"Google Cloud Platform"}),"\n",(0,l.jsx)(n.p,{children:"These settings are used to build and deploy the server on the GCP Project as a Google Cloud Run managed service."}),"\n",(0,l.jsx)(n.h4,{id:"gcloud_service_key",children:(0,l.jsx)(n.code,{children:"GCLOUD_SERVICE_KEY"})}),"\n",(0,l.jsxs)(n.p,{children:["Full JSON service key linked to the Service Account allowed to build and run the server on the GCP Project.\nIt is also used as the main authentication method for the Firebase CLI during client deployment as ",(0,l.jsx)(n.a,{href:"#firebase_token",children:"FIREBASE_TOKEN"})," usage will be decomissioned in the next major version."]}),"\n",(0,l.jsx)(n.h4,{id:"google_compute_zone",children:(0,l.jsx)(n.code,{children:"GOOGLE_COMPUTE_ZONE"})}),"\n",(0,l.jsx)(n.p,{children:"Default compute zone to use (europe-west1 usually)."}),"\n",(0,l.jsx)(n.h4,{id:"google_project_id",children:(0,l.jsx)(n.code,{children:"GOOGLE_PROJECT_ID"})}),"\n",(0,l.jsx)(n.p,{children:"Self-reference to the Project (used by the CircleCI orb to properly handle resources)."}),"\n",(0,l.jsx)(n.h3,{id:"firebase",children:"Firebase"}),"\n",(0,l.jsx)(n.h4,{id:"firebase_token",children:(0,l.jsx)(n.code,{children:"FIREBASE_TOKEN"})}),"\n",(0,l.jsxs)(n.p,{children:["Token used only by CI to connect to Firebase and deploy the client. Was generated following this ",(0,l.jsx)(n.a,{href:"https://firebase.google.com/docs/cli?authuser=0#cli-ci-systems",children:"documentation"})]}),"\n",(0,l.jsx)(n.h4,{id:"firebase_project_id",children:(0,l.jsx)(n.code,{children:"FIREBASE_PROJECT_ID"})}),"\n",(0,l.jsx)(n.p,{children:"Identifier of the Firebase project."}),"\n",(0,l.jsx)(n.h4,{id:"firebase_client_email",children:(0,l.jsx)(n.code,{children:"FIREBASE_CLIENT_EMAIL"})}),"\n",(0,l.jsx)(n.p,{children:"Identifier used to authenticate against the Firebase stack. Found in the Firebase console."}),"\n",(0,l.jsx)(n.h4,{id:"firebase_private_key",children:(0,l.jsx)(n.code,{children:"FIREBASE_PRIVATE_KEY"})}),"\n",(0,l.jsx)(n.p,{children:"A Service Account must be defined with the proper key. The private key used in the FIREBASE_PRIVATE_KEY environment variable needs to be base64 encoded."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Using bash:"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-bash",children:'echo "content_of_private_key_field_in_json_key" | base64\n'})}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:"Using Node.js:"}),"\n"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-js",children:"Buffer.from('content_of_private_key_field_in_json_key').toString('base64');\n"})}),"\n",(0,l.jsx)(n.h3,{id:"mailgun",children:"Mailgun"}),"\n",(0,l.jsxs)(n.p,{children:["These are injected in the Cloud Run container in order to properly use Mailgun to send emails and notifications.\nOn dev and staging, a sandbox account is used that redirects any sent email to ",(0,l.jsx)(n.a,{href:"mailto:feedzback@zenika.com",children:"feedzback@zenika.com"}),"."]}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_url",children:(0,l.jsx)(n.code,{children:"MAILGUN_URL"})}),"\n",(0,l.jsx)(n.p,{children:"The mailgun endpoint to use to connect to mailgun sending server."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:["for sandbox mailgun account: ",(0,l.jsx)(n.code,{children:"https://api.mailgun.net"})]}),"\n",(0,l.jsxs)(n.li,{children:["for production account (which is in EU): ",(0,l.jsx)(n.code,{children:"https://api.eu.mailgun.net"})]}),"\n"]}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_username",children:(0,l.jsx)(n.code,{children:"MAILGUN_USERNAME"})}),"\n",(0,l.jsx)(n.p,{children:"The Mailgun API username (needs to match the domain of the key)."}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_key",children:(0,l.jsx)(n.code,{children:"MAILGUN_KEY"})}),"\n",(0,l.jsx)(n.p,{children:"An API secret defined on the mailgun platform that allows to send email."}),"\n",(0,l.jsx)(n.h4,{id:"mailgun_domain",children:(0,l.jsx)(n.code,{children:"MAILGUN_DOMAIN"})}),"\n",(0,l.jsxs)(n.p,{children:["The domain associated with the account.\nUse the sandbox username as the domain (",(0,l.jsx)(n.code,{children:"sandbox8d21179029774bb29c92557ea6ab0d88.mailgun.org"}),").\nIn production should be ",(0,l.jsx)(n.code,{children:"feedzback.znk.io"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"crypto",children:"Crypto"}),"\n",(0,l.jsxs)(n.h4,{id:"crypto_secret_key--crypto_secret_iv",children:[(0,l.jsx)(n.code,{children:"CRYPTO_SECRET_KEY"})," & ",(0,l.jsx)(n.code,{children:"CRYPTO_SECRET_IV"})]}),"\n",(0,l.jsx)(n.p,{children:"Used to encrypt/decrypt sensitives data in the Firestore database."}),"\n",(0,l.jsxs)(n.p,{children:["In dev and staging set their values to: ",(0,l.jsx)(n.code,{children:"feedzback"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"node",children:"Node"}),"\n",(0,l.jsx)(n.h4,{id:"node_env",children:(0,l.jsx)(n.code,{children:"NODE_ENV"})}),"\n",(0,l.jsxs)(n.p,{children:["Should be ",(0,l.jsx)(n.code,{children:"production"})," for production environment, otherwise all mails will be sent to ",(0,l.jsx)(n.code,{children:"feedzback@zenika.com"}),"."]}),"\n",(0,l.jsx)(n.h3,{id:"app",children:"App"}),"\n",(0,l.jsx)(n.h4,{id:"server_port",children:(0,l.jsx)(n.code,{children:"SERVER_PORT"})}),"\n",(0,l.jsx)(n.p,{children:"The port on which the server is listening."}),"\n",(0,l.jsx)(n.h4,{id:"client_url",children:(0,l.jsx)(n.code,{children:"CLIENT_URL"})}),"\n",(0,l.jsx)(n.p,{children:"This helps the server compose URLs to include in emails."}),"\n",(0,l.jsx)(n.h2,{id:"usage-analytics",children:"Usage analytics"}),"\n",(0,l.jsxs)(n.p,{children:["Usage analytics can be set up using ",(0,l.jsx)(n.a,{href:"/docs/usage-analytics",children:"these instructions"})]}),"\n",(0,l.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,l.jsx)(n.h3,{id:"development-feedzback-v2-dev-",children:"Development (feedzback-v2-dev) \ud83d\udea7"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-dev",children:"Firebase console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/home/dashboard?hl=en&project=feedzback-v2-dev",children:"GCP console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://app.circleci.com/settings/organization/github/Zenika/contexts/686ad410-3bba-4c59-a904-da3fe737eaa3?return-to=%2F",children:"CircleCI context"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"staging-feedzback-v2-staging-",children:"Staging (feedzback-v2-staging) \ud83d\ude80"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2-staging",children:"Firebase console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/home/dashboard?hl=en&project=feedzback-v2-staging",children:"GCP console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://app.circleci.com/settings/organization/github/Zenika/contexts/489bddb3-fe2e-465e-91f9-b9ba7a155e0d?return-to=%2F",children:"CircleCI context"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"production-feedzback-v2-",children:"Production (feedzback-v2) \ud83c\udfac"}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.firebase.google.com/project/feedzback-v2",children:"Firebase console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://console.cloud.google.com/home/dashboard?hl=en&project=feedzback-v2",children:"GCP console"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.a,{href:"https://app.circleci.com/settings/organization/github/Zenika/contexts/3b5ca05f-7180-479e-9225-9902e29cde9b?return-to=%2F",children:"CircleCI context"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>s});var c=i(6540);const l={},o=c.createContext(l);function d(e){const n=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:d(e.components),c.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/4f3f1eb6.2cebb06f.js b/docs/assets/js/4f3f1eb6.2cebb06f.js new file mode 100644 index 00000000..8931d928 --- /dev/null +++ b/docs/assets/js/4f3f1eb6.2cebb06f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[3136],{2305:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>u});var o=n(8826),a=n(4848),s=n(8453);const r={slug:"starting-documentation",title:"Starting documentation",authors:"stephane.francel",tags:[]},c=void 0,i={authorsImageUrls:[void 0]},u=[];function d(t){const e={code:"code",p:"p",...(0,s.R)(),...t.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.p,{children:"This is the summary of a very long blog post,"}),"\n",(0,a.jsxs)(e.p,{children:["Use a ",(0,a.jsx)(e.code,{children:"\x3c!--"})," ",(0,a.jsx)(e.code,{children:"truncate"})," ",(0,a.jsx)(e.code,{children:"--\x3e"})," comment to limit blog post size in the list view."]})]})}function l(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,a.jsx)(e,{...t,children:(0,a.jsx)(d,{...t})}):d(t)}},8453:(t,e,n)=>{n.d(e,{R:()=>r,x:()=>c});var o=n(6540);const a={},s=o.createContext(a);function r(t){const e=o.useContext(s);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(a):t.components||a:r(t.components),o.createElement(s.Provider,{value:e},t.children)}},8826:t=>{t.exports=JSON.parse('{"permalink":"/feedzback/blog/starting-documentation","editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/blog/2024-03-11-starting-documentation.md","source":"@site/blog/2024-03-11-starting-documentation.md","title":"Starting documentation","description":"This is the summary of a very long blog post,","date":"2024-03-11T00:00:00.000Z","tags":[],"readingTime":2.05,"hasTruncateMarker":true,"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null}],"frontMatter":{"slug":"starting-documentation","title":"Starting documentation","authors":"stephane.francel","tags":[]},"unlisted":false}')}}]); \ No newline at end of file diff --git a/docs/assets/js/4f3f1eb6.5dbf4b6c.js b/docs/assets/js/4f3f1eb6.5dbf4b6c.js deleted file mode 100644 index 509d01c0..00000000 --- a/docs/assets/js/4f3f1eb6.5dbf4b6c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[136],{2305:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>i,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>u});var o=n(8826),a=n(4848),s=n(8453);const r={slug:"starting-documentation",title:"Starting documentation",authors:"stephane.francel",tags:[]},c=void 0,i={authorsImageUrls:[void 0]},u=[];function d(t){const e={code:"code",p:"p",...(0,s.R)(),...t.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.p,{children:"This is the summary of a very long blog post,"}),"\n",(0,a.jsxs)(e.p,{children:["Use a ",(0,a.jsx)(e.code,{children:"\x3c!--"})," ",(0,a.jsx)(e.code,{children:"truncate"})," ",(0,a.jsx)(e.code,{children:"--\x3e"})," comment to limit blog post size in the list view."]})]})}function l(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,a.jsx)(e,{...t,children:(0,a.jsx)(d,{...t})}):d(t)}},8453:(t,e,n)=>{n.d(e,{R:()=>r,x:()=>c});var o=n(6540);const a={},s=o.createContext(a);function r(t){const e=o.useContext(s);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(a):t.components||a:r(t.components),o.createElement(s.Provider,{value:e},t.children)}},8826:t=>{t.exports=JSON.parse('{"permalink":"/feedzback/blog/starting-documentation","editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/blog/2024-03-11-starting-documentation.md","source":"@site/blog/2024-03-11-starting-documentation.md","title":"Starting documentation","description":"This is the summary of a very long blog post,","date":"2024-03-11T00:00:00.000Z","tags":[],"readingTime":2.05,"hasTruncateMarker":true,"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null}],"frontMatter":{"slug":"starting-documentation","title":"Starting documentation","authors":"stephane.francel","tags":[]},"unlisted":false}')}}]); \ No newline at end of file diff --git a/docs/assets/js/531.701e67cb.js b/docs/assets/js/531.701e67cb.js deleted file mode 100644 index 1f341ce5..00000000 --- a/docs/assets/js/531.701e67cb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[531],{4096:(e,t,a)=>{a.d(t,{in:()=>c,OU:()=>C,Ki:()=>A,kJ:()=>x,x:()=>l,e7:()=>m,J_:()=>f,Gx:()=>_});var s=a(6540),n=a(9532),i=a(6803),r=a(4848);function l(){const e=(0,i.A)(),t=e?.data?.blogMetadata;if(!t)throw new Error("useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context");return t}const o=s.createContext(null);function c(e){let{children:t,content:a,isBlogPostPage:n=!1}=e;const i=function(e){let{content:t,isBlogPostPage:a}=e;return(0,s.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:n});return(0,r.jsx)(o.Provider,{value:i,children:t})}function m(){const e=(0,s.useContext)(o);if(null===e)throw new n.dV("BlogPostProvider");return e}var u=a(6025),h=a(4586);const d=e=>new Date(e).toISOString();function g(e){const t=e.map(v);return{author:1===t.length?t[0]:t}}function p(e,t,a){return e?{image:j({imageUrl:t(e,{absolute:!0}),caption:`title image for the blog post: ${a}`})}:{}}function x(e){const{siteConfig:t}=(0,h.A)(),{withBaseUrl:a}=(0,u.hH)(),{metadata:{blogDescription:s,blogTitle:n,permalink:i}}=e,r=`${t.url}${i}`;return{"@context":"https://schema.org","@type":"Blog","@id":r,mainEntityOfPage:r,headline:n,description:s,blogPost:e.items.map((e=>function(e,t,a){const{assets:s,frontMatter:n,metadata:i}=e,{date:r,title:l,description:o,lastUpdatedAt:c}=i,m=s.image??n.image,u=n.keywords??[],h=`${t.url}${i.permalink}`,x=c?d(c):void 0;return{"@type":"BlogPosting","@id":h,mainEntityOfPage:h,url:h,headline:l,name:l,description:o,datePublished:r,...x?{dateModified:x}:{},...g(i.authors),...p(m,a,l),...u?{keywords:u}:{}}}(e.content,t,a)))}}function f(){const e=l(),{assets:t,metadata:a}=m(),{siteConfig:s}=(0,h.A)(),{withBaseUrl:n}=(0,u.hH)(),{date:i,title:r,description:o,frontMatter:c,lastUpdatedAt:x}=a,f=t.image??c.image,v=c.keywords??[],j=x?d(x):void 0,b=`${s.url}${a.permalink}`;return{"@context":"https://schema.org","@type":"BlogPosting","@id":b,mainEntityOfPage:b,url:b,headline:r,name:r,description:o,datePublished:i,...j?{dateModified:j}:{},...g(a.authors),...p(f,n,r),...v?{keywords:v}:{},isPartOf:{"@type":"Blog","@id":`${s.url}${e.blogBasePath}`,name:e.blogTitle}}}function v(e){return{"@type":"Person",...e.name?{name:e.name}:{},...e.title?{description:e.title}:{},...e.url?{url:e.url}:{},...e.email?{email:e.email}:{},...e.imageURL?{image:e.imageURL}:{}}}function j(e){let{imageUrl:t,caption:a}=e;return{"@type":"ImageObject","@id":t,url:t,contentUrl:t,caption:a}}var b=a(6347),w=a(8774),N=a(1682),k=a(9169);function _(e){const{pathname:t}=(0,b.zy)();return(0,s.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,k.ys)(e.permalink,t))}(e,t)))),[e,t])}function A(e){const t=(0,N.$z)(e,(e=>`${new Date(e.date).getFullYear()}`)),a=Object.entries(t);return a.reverse(),a}function C(e){let{items:t,ulClassName:a,liClassName:s,linkClassName:n,linkActiveClassName:i}=e;return(0,r.jsx)("ul",{className:a,children:t.map((e=>(0,r.jsx)("li",{className:s,children:(0,r.jsx)(w.A,{isNavLink:!0,to:e.permalink,className:n,activeClassName:i,children:e.title})},e.permalink)))})}},6913:(e,t,a)=>{a.d(t,{A:()=>j});a(6540);var s=a(4164),n=a(8774),i=a(4848);const r="githubSvg_Uu4N";const l="xSvg_y3PF";const o=function(e){return(0,i.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",...e,children:[(0,i.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,i.jsx)("path",{d:"M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"}),(0,i.jsx)("path",{d:"M3.6 9h16.8"}),(0,i.jsx)("path",{d:"M3.6 15h16.8"}),(0,i.jsx)("path",{d:"M11.5 3a17 17 0 0 0 0 18"}),(0,i.jsx)("path",{d:"M12.5 3a17 17 0 0 1 0 18"})]})},c={authorSocials:"authorSocials_rSDt",authorSocialLink:"authorSocialLink_owbf",authorSocialIcon:"authorSocialIcon_XYv3"},m={twitter:{Icon:function(e){return(0,i.jsx)("svg",{viewBox:"0 0 256 209",width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",...e,children:(0,i.jsx)("path",{d:"M256 25.45c-9.42 4.177-19.542 7-30.166 8.27 10.845-6.5 19.172-16.793 23.093-29.057a105.183 105.183 0 0 1-33.351 12.745C205.995 7.201 192.346.822 177.239.822c-29.006 0-52.523 23.516-52.523 52.52 0 4.117.465 8.125 1.36 11.97-43.65-2.191-82.35-23.1-108.255-54.876-4.52 7.757-7.11 16.78-7.11 26.404 0 18.222 9.273 34.297 23.365 43.716a52.312 52.312 0 0 1-23.79-6.57c-.003.22-.003.44-.003.661 0 25.447 18.104 46.675 42.13 51.5a52.592 52.592 0 0 1-23.718.9c6.683 20.866 26.08 36.05 49.062 36.475-17.975 14.086-40.622 22.483-65.228 22.483-4.24 0-8.42-.249-12.529-.734 23.243 14.902 50.85 23.597 80.51 23.597 96.607 0 149.434-80.031 149.434-149.435 0-2.278-.05-4.543-.152-6.795A106.748 106.748 0 0 0 256 25.45",fill:"#55acee"})})},label:"Twitter"},github:{Icon:function(e){return(0,i.jsx)("svg",{viewBox:"0 0 256 250",width:"1em",height:"1em",...e,className:(0,s.A)(e.className,r),xmlns:"http://www.w3.org/2000/svg",style:{"--dark":"#000","--light":"#fff"},preserveAspectRatio:"xMidYMid",children:(0,i.jsx)("path",{d:"M128.001 0C57.317 0 0 57.307 0 128.001c0 56.554 36.676 104.535 87.535 121.46 6.397 1.185 8.746-2.777 8.746-6.158 0-3.052-.12-13.135-.174-23.83-35.61 7.742-43.124-15.103-43.124-15.103-5.823-14.795-14.213-18.73-14.213-18.73-11.613-7.944.876-7.78.876-7.78 12.853.902 19.621 13.19 19.621 13.19 11.417 19.568 29.945 13.911 37.249 10.64 1.149-8.272 4.466-13.92 8.127-17.116-28.431-3.236-58.318-14.212-58.318-63.258 0-13.975 5-25.394 13.188-34.358-1.329-3.224-5.71-16.242 1.24-33.874 0 0 10.749-3.44 35.21 13.121 10.21-2.836 21.16-4.258 32.038-4.307 10.878.049 21.837 1.47 32.066 4.307 24.431-16.56 35.165-13.12 35.165-13.12 6.967 17.63 2.584 30.65 1.255 33.873 8.207 8.964 13.173 20.383 13.173 34.358 0 49.163-29.944 59.988-58.447 63.157 4.591 3.972 8.682 11.762 8.682 23.704 0 17.126-.148 30.91-.148 35.126 0 3.407 2.304 7.398 8.792 6.14C219.37 232.5 256 184.537 256 128.002 256 57.307 198.691 0 128.001 0Zm-80.06 182.34c-.282.636-1.283.827-2.194.39-.929-.417-1.45-1.284-1.15-1.922.276-.655 1.279-.838 2.205-.399.93.418 1.46 1.293 1.139 1.931Zm6.296 5.618c-.61.566-1.804.303-2.614-.591-.837-.892-.994-2.086-.375-2.66.63-.566 1.787-.301 2.626.591.838.903 1 2.088.363 2.66Zm4.32 7.188c-.785.545-2.067.034-2.86-1.104-.784-1.138-.784-2.503.017-3.05.795-.547 2.058-.055 2.861 1.075.782 1.157.782 2.522-.019 3.08Zm7.304 8.325c-.701.774-2.196.566-3.29-.49-1.119-1.032-1.43-2.496-.726-3.27.71-.776 2.213-.558 3.315.49 1.11 1.03 1.45 2.505.701 3.27Zm9.442 2.81c-.31 1.003-1.75 1.459-3.199 1.033-1.448-.439-2.395-1.613-2.103-2.626.301-1.01 1.747-1.484 3.207-1.028 1.446.436 2.396 1.602 2.095 2.622Zm10.744 1.193c.036 1.055-1.193 1.93-2.715 1.95-1.53.034-2.769-.82-2.786-1.86 0-1.065 1.202-1.932 2.733-1.958 1.522-.03 2.768.818 2.768 1.868Zm10.555-.405c.182 1.03-.875 2.088-2.387 2.37-1.485.271-2.861-.365-3.05-1.386-.184-1.056.893-2.114 2.376-2.387 1.514-.263 2.868.356 3.061 1.403Z"})})},label:"GitHub"},stackoverflow:{Icon:function(e){return(0,i.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 169.61 200",width:"1em",height:"1em",...e,children:[(0,i.jsx)("path",{d:"M140.44 178.38v-48.65h21.61V200H0v-70.27h21.61v48.65z",fill:"#bcbbbb"}),(0,i.jsx)("path",{d:"M124.24 140.54l4.32-16.22-86.97-17.83-3.78 17.83zM49.7 82.16L130.72 120l7.56-16.22-81.02-37.83zm22.68-40l68.06 57.3 11.35-13.51-68.6-57.3-11.35 13.51zM116.14 0l-14.59 10.81 53.48 71.89 14.58-10.81zM37.81 162.16h86.43v-16.21H37.81z",fill:"#f48024"})]})},label:"Stack Overflow"},linkedin:{Icon:function(e){return(0,i.jsx)("svg",{width:"1em",height:"1em",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid",viewBox:"0 0 256 256",...e,children:(0,i.jsx)("path",{d:"M218.123 218.127h-37.931v-59.403c0-14.165-.253-32.4-19.728-32.4-19.756 0-22.779 15.434-22.779 31.369v60.43h-37.93V95.967h36.413v16.694h.51a39.907 39.907 0 0 1 35.928-19.733c38.445 0 45.533 25.288 45.533 58.186l-.016 67.013ZM56.955 79.27c-12.157.002-22.014-9.852-22.016-22.009-.002-12.157 9.851-22.014 22.008-22.016 12.157-.003 22.014 9.851 22.016 22.008A22.013 22.013 0 0 1 56.955 79.27m18.966 138.858H37.95V95.967h37.97v122.16ZM237.033.018H18.89C8.58-.098.125 8.161-.001 18.471v219.053c.122 10.315 8.576 18.582 18.89 18.474h218.144c10.336.128 18.823-8.139 18.966-18.474V18.454c-.147-10.33-8.635-18.588-18.966-18.453",fill:"#0A66C2"})})},label:"LinkedIn"},x:{Icon:function(e){return(0,i.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",fill:"none",viewBox:"0 0 1200 1227",...e,className:(0,s.A)(e.className,l),style:{"--dark":"#000","--light":"#fff"},children:(0,i.jsx)("path",{d:"M714.163 519.284 1160.89 0h-105.86L667.137 450.887 357.328 0H0l468.492 681.821L0 1226.37h105.866l409.625-476.152 327.181 476.152H1200L714.137 519.284h.026ZM569.165 687.828l-47.468-67.894-377.686-540.24h162.604l304.797 435.991 47.468 67.894 396.2 566.721H892.476L569.165 687.854v-.026Z"})})},label:"X"}};function u(e){let{platform:t,link:a}=e;const{Icon:r,label:l}=m[u=t]??{Icon:o,label:u};var u;return(0,i.jsx)(n.A,{className:c.authorSocialLink,href:a,title:l,children:(0,i.jsx)(r,{className:(0,s.A)(c.authorSocialLink)})})}function h(e){let{author:t}=e;const a=Object.entries(t.socials??{});return(0,i.jsx)("div",{className:c.authorSocials,children:a.map((e=>{let[t,a]=e;return(0,i.jsx)(u,{platform:t,link:a},t)}))})}var d=a(1107);const g={authorImage:"authorImage_XqGP","author-as-h1":"author-as-h1_n9oJ","author-as-h2":"author-as-h2_gXvM",authorDetails:"authorDetails_lV9A",authorName:"authorName_yefp",authorTitle:"authorTitle_nd0D",authorBlogPostCount:"authorBlogPostCount_iiJ5"};function p(e){return e.href?(0,i.jsx)(n.A,{...e}):(0,i.jsx)(i.Fragment,{children:e.children})}function x(e){let{title:t}=e;return(0,i.jsx)("small",{className:g.authorTitle,title:t,children:t})}function f(e){let{name:t,as:a}=e;return a?(0,i.jsx)(d.A,{as:a,className:g.authorName,children:t}):(0,i.jsx)("span",{className:g.authorName,children:t})}function v(e){let{count:t}=e;return(0,i.jsx)("span",{className:(0,s.A)(g.authorBlogPostCount),children:t})}function j(e){let{as:t,author:a,className:n,count:r}=e;const{name:l,title:o,url:c,imageURL:m,email:u,page:d}=a,j=d?.permalink||c||u&&`mailto:${u}`||void 0;return(0,i.jsxs)("div",{className:(0,s.A)("avatar margin-bottom--sm",n,g[`author-as-${t}`]),children:[m&&(0,i.jsx)(p,{href:j,className:"avatar__photo-link",children:(0,i.jsx)("img",{className:(0,s.A)("avatar__photo",g.authorImage),src:m,alt:l})}),(l||o)&&(0,i.jsxs)("div",{className:(0,s.A)("avatar__intro",g.authorDetails),children:[(0,i.jsxs)("div",{className:"avatar__name",children:[l&&(0,i.jsx)(p,{href:j,children:(0,i.jsx)(f,{name:l,as:t})}),void 0!==r&&(0,i.jsx)(v,{count:r})]}),!!o&&(0,i.jsx)(x,{title:o}),(0,i.jsx)(h,{author:a})]})]})}},8027:(e,t,a)=>{a.d(t,{A:()=>I});var s=a(6540),n=a(4164),i=a(781),r=a(4581),l=a(1312),o=a(4096),c=a(6342),m=a(1107),u=a(4848);function h(e){let{year:t,yearGroupHeadingClassName:a,children:s}=e;return(0,u.jsxs)("div",{role:"group",children:[(0,u.jsx)(m.A,{as:"h3",className:a,children:t}),s]})}function d(e){let{items:t,yearGroupHeadingClassName:a,ListComponent:s}=e;if((0,c.p)().blog.sidebar.groupByYear){const e=(0,o.Ki)(t);return(0,u.jsx)(u.Fragment,{children:e.map((e=>{let[t,n]=e;return(0,u.jsx)(h,{year:t,yearGroupHeadingClassName:a,children:(0,u.jsx)(s,{items:n})},t)}))})}return(0,u.jsx)(s,{items:t})}const g=(0,s.memo)(d),p="sidebar_re4s",x="sidebarItemTitle_pO2u",f="sidebarItemList_Yudw",v="sidebarItem__DBe",j="sidebarItemLink_mo7H",b="sidebarItemLinkActive_I1ZP",w="yearGroupHeading_rMGB",N=e=>{let{items:t}=e;return(0,u.jsx)(o.OU,{items:t,ulClassName:(0,n.A)(f,"clean-list"),liClassName:v,linkClassName:j,linkActiveClassName:b})};function k(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,u.jsx)("aside",{className:"col col--3",children:(0,u.jsxs)("nav",{className:(0,n.A)(p,"thin-scrollbar"),"aria-label":(0,l.T)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,u.jsx)("div",{className:(0,n.A)(x,"margin-bottom--md"),children:t.title}),(0,u.jsx)(g,{items:a,ListComponent:N,yearGroupHeadingClassName:w})]})})}const _=(0,s.memo)(k);var A=a(5600);const C={yearGroupHeading:"yearGroupHeading_QT03"},M=e=>{let{items:t}=e;return(0,u.jsx)(o.OU,{items:t,ulClassName:"menu__list",liClassName:"menu__list-item",linkClassName:"menu__link",linkActiveClassName:"menu__link--active"})};function y(e){let{sidebar:t}=e;const a=(0,o.Gx)(t.items);return(0,u.jsx)(g,{items:a,ListComponent:M,yearGroupHeadingClassName:C.yearGroupHeading})}function P(e){return(0,u.jsx)(A.GX,{component:y,props:e})}const B=(0,s.memo)(P);function L(e){let{sidebar:t}=e;const a=(0,r.l)();return t?.items.length?"mobile"===a?(0,u.jsx)(B,{sidebar:t}):(0,u.jsx)(_,{sidebar:t}):null}function I(e){const{sidebar:t,toc:a,children:s,...r}=e,l=t&&t.items.length>0;return(0,u.jsx)(i.A,{...r,children:(0,u.jsx)("div",{className:"container margin-vert--lg",children:(0,u.jsxs)("div",{className:"row",children:[(0,u.jsx)(L,{sidebar:t}),(0,u.jsx)("main",{className:(0,n.A)("col",{"col--7":l,"col--9 col--offset-1":!l}),children:s}),a&&(0,u.jsx)("div",{className:"col col--2",children:a})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/554.795ccddc.js b/docs/assets/js/554.795ccddc.js deleted file mode 100644 index 3a17eb2f..00000000 --- a/docs/assets/js/554.795ccddc.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[554],{7293:(e,t,n)=>{"use strict";n.d(t,{A:()=>L});var s=n(6540),a=n(4848);function o(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=t.filter((e=>e!==n)),c=n?.props.children;return{mdxAdmonitionTitle:c,rest:o.length>0?(0,a.jsx)(a.Fragment,{children:o}):null}}(e.children),o=e.title??t;return{...e,...o&&{title:o},children:n}}var c=n(4164),i=n(1312),r=n(7559);const l={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:t,className:n,children:s}=e;return(0,a.jsx)("div",{className:(0,c.A)(r.G.common.admonition,r.G.common.admonitionType(t),l.admonition,n),children:s})}function u(e){let{icon:t,title:n}=e;return(0,a.jsxs)("div",{className:l.admonitionHeading,children:[(0,a.jsx)("span",{className:l.admonitionIcon,children:t}),n]})}function m(e){let{children:t}=e;return t?(0,a.jsx)("div",{className:l.admonitionContent,children:t}):null}function h(e){const{type:t,icon:n,title:s,children:o,className:c}=e;return(0,a.jsxs)(d,{type:t,className:c,children:[s||n?(0,a.jsx)(u,{title:s,icon:n}):null,(0,a.jsx)(m,{children:o})]})}function p(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const f={icon:(0,a.jsx)(p,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function g(e){return(0,a.jsx)(h,{...f,...e,className:(0,c.A)("alert alert--secondary",e.className),children:e.children})}function x(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const j={icon:(0,a.jsx)(x,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function b(e){return(0,a.jsx)(h,{...j,...e,className:(0,c.A)("alert alert--success",e.className),children:e.children})}function v(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const N={icon:(0,a.jsx)(v,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function y(e){return(0,a.jsx)(h,{...N,...e,className:(0,c.A)("alert alert--info",e.className),children:e.children})}function A(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const k={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function B(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const C={icon:(0,a.jsx)(B,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const w={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const _={...{note:g,tip:b,info:y,warning:function(e){return(0,a.jsx)(h,{...k,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(h,{...C,...e,className:(0,c.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(g,{title:"secondary",...e}),important:e=>(0,a.jsx)(y,{title:"important",...e}),success:e=>(0,a.jsx)(b,{title:"success",...e}),caution:function(e){return(0,a.jsx)(h,{...w,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})}}};function L(e){const t=o(e),n=(s=t.type,_[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),_.info));var s;return(0,a.jsx)(n,{...t})}},4336:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});n(6540);var s=n(4164),a=n(1312),o=n(7559),c=n(8774);const i={iconEdit:"iconEdit_Z9Sw"};var r=n(4848);function l(e){let{className:t,...n}=e;return(0,r.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,s.A)(i.iconEdit,t),"aria-hidden":"true",...n,children:(0,r.jsx)("g",{children:(0,r.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function d(e){let{editUrl:t}=e;return(0,r.jsxs)(c.A,{to:t,className:o.G.common.editThisPage,children:[(0,r.jsx)(l,{}),(0,r.jsx)(a.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=n(6266);function m(e){let{lastUpdatedAt:t}=e;const n=new Date(t),s=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(n);return(0,r.jsx)(a.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,r.jsx)("b",{children:(0,r.jsx)("time",{dateTime:n.toISOString(),itemProp:"dateModified",children:s})})},children:" on {date}"})}function h(e){let{lastUpdatedBy:t}=e;return(0,r.jsx)(a.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,r.jsx)("b",{children:t})},children:" by {user}"})}function p(e){let{lastUpdatedAt:t,lastUpdatedBy:n}=e;return(0,r.jsxs)("span",{className:o.G.common.lastUpdated,children:[(0,r.jsx)(a.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t?(0,r.jsx)(m,{lastUpdatedAt:t}):"",byUser:n?(0,r.jsx)(h,{lastUpdatedBy:n}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const f={lastUpdated:"lastUpdated_JAkA"};function g(e){let{className:t,editUrl:n,lastUpdatedAt:a,lastUpdatedBy:o}=e;return(0,r.jsxs)("div",{className:(0,s.A)("row",t),children:[(0,r.jsx)("div",{className:"col",children:n&&(0,r.jsx)(d,{editUrl:n})}),(0,r.jsx)("div",{className:(0,s.A)("col",f.lastUpdated),children:(a||o)&&(0,r.jsx)(p,{lastUpdatedAt:a,lastUpdatedBy:o})})]})}},5533:(e,t,n)=>{"use strict";n.d(t,{A:()=>re});var s=n(6540),a=n(8453),o=n(5260),c=n(2303),i=n(4164),r=n(5293),l=n(6342);function d(){const{prism:e}=(0,l.p)(),{colorMode:t}=(0,r.G)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var u=n(7559),m=n(8426),h=n.n(m);const p=/title=(?["'])(?.*?)\1/,f=/\{(?<range>[\d,-]+)\}/,g={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},x={...g,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},j=Object.keys(g);function b(e,t){const n=e.map((e=>{const{start:n,end:s}=x[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:s,magicComments:a,metastring:o}=t;if(o&&f.test(o)){const e=o.match(f).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,s=h()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(s),code:n}}if(void 0===s)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return b(["tex"],t);case"lua":case"haskell":case"sql":return b(["lua"],t);case"wasm":return b(["wasm"],t);case"vb":case"vba":case"visual-basic":return b(["vb","rem"],t);case"vbnet":return b(["vbnet","rem"],t);case"batch":return b(["rem"],t);case"basic":return b(["rem","f90"],t);case"fsharp":return b(["js","ml"],t);case"ocaml":case"sml":return b(["ml"],t);case"fortran":return b(["f90"],t);case"cobol":return b(["cobol"],t);default:return b(j,t)}}(s,a),i=n.split("\n"),r=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),l=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),d=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let h=0;h<i.length;){const e=i[h].match(c);if(!e){h+=1;continue}const t=e.slice(1).find((e=>void 0!==e));l[t]?r[l[t]].range+=`${h},`:d[t]?r[d[t]].start=h:u[t]&&(r[u[t]].range+=`${r[u[t]].start}-${h-1},`),i.splice(h,1)}n=i.join("\n");const m={};return Object.entries(r).forEach((e=>{let[t,{range:n}]=e;h()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const N={codeBlockContainer:"codeBlockContainer_Ckt0"};var y=n(4848);function A(e){let{as:t,...n}=e;const s=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[s,a]=e;const o=t[s];o&&"string"==typeof a&&(n[o]=a)})),n}(d());return(0,y.jsx)(t,{...n,style:s,className:(0,i.A)(n.className,N.codeBlockContainer,u.G.common.codeBlock)})}const k={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function B(e){let{children:t,className:n}=e;return(0,y.jsx)(A,{as:"pre",tabIndex:0,className:(0,i.A)(k.codeBlockStandalone,"thin-scrollbar",n),children:(0,y.jsx)("code",{className:k.codeBlockLines,children:t})})}var C=n(9532);const w={attributes:!0,characterData:!0,childList:!0,subtree:!0};function _(e,t){const[n,a]=(0,s.useState)(),o=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=w);const a=(0,C._q)(t),o=(0,C.Be)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,o),()=>t.disconnect()}),[e,a,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var L=n(1765);const E={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function T(e){let{line:t,classNames:n,showLineNumbers:s,getLineProps:a,getTokenProps:o}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const c=a({line:t,className:(0,i.A)(n,s&&E.codeLine)}),r=t.map(((e,t)=>(0,y.jsx)("span",{...o({token:e})},t)));return(0,y.jsxs)("span",{...c,children:[s?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)("span",{className:E.codeLineNumber}),(0,y.jsx)("span",{className:E.codeLineContent,children:r})]}):r,(0,y.jsx)("br",{})]})}var S=n(1312);function z(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function U(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const M={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(e){let{code:t,className:n}=e;const[a,o]=(0,s.useState)(!1),c=(0,s.useRef)(void 0),r=(0,s.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const s=document.createElement("textarea"),a=document.activeElement;s.value=e,s.setAttribute("readonly",""),s.style.contain="strict",s.style.position="absolute",s.style.left="-9999px",s.style.fontSize="12pt";const o=document.getSelection(),c=o.rangeCount>0&&o.getRangeAt(0);n.append(s),s.select(),s.selectionStart=0,s.selectionEnd=e.length;let i=!1;try{i=document.execCommand("copy")}catch{}s.remove(),c&&(o.removeAllRanges(),o.addRange(c)),a&&a.focus()}(t),o(!0),c.current=window.setTimeout((()=>{o(!1)}),1e3)}),[t]);return(0,s.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),(0,y.jsx)("button",{type:"button","aria-label":a?(0,S.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,S.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,S.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.A)("clean-btn",n,M.copyButton,a&&M.copyButtonCopied),onClick:r,children:(0,y.jsxs)("span",{className:M.copyButtonIcons,"aria-hidden":"true",children:[(0,y.jsx)(z,{className:M.copyButtonIcon}),(0,y.jsx)(U,{className:M.copyButtonSuccessIcon})]})})}function H(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const R={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function V(e){let{className:t,onClick:n,isEnabled:s}=e;const a=(0,S.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,y.jsx)("button",{type:"button",onClick:n,className:(0,i.A)("clean-btn",t,s&&R.wordWrapButtonEnabled),"aria-label":a,title:a,children:(0,y.jsx)(H,{className:R.wordWrapButtonIcon,"aria-hidden":"true"})})}function W(e){let{children:t,className:n="",metastring:a,title:o,showLineNumbers:c,language:r}=e;const{prism:{defaultLanguage:u,magicComments:m}}=(0,l.p)(),h=function(e){return e?.toLowerCase()}(r??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??u),f=d(),g=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),o=(0,s.useRef)(null),c=(0,s.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),i=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");a(n)}),[o]);return _(o,i),(0,s.useEffect)((()=>{i()}),[e,i]),(0,s.useEffect)((()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)})),[i]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:c}}(),x=function(e){return e?.match(p)?.groups.title??""}(a)||o,{lineClassNames:j,code:b}=v(t,{metastring:a,language:h,magicComments:m}),N=c??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return(0,y.jsxs)(A,{as:"div",className:(0,i.A)(n,h&&!n.includes(`language-${h}`)&&`language-${h}`),children:[x&&(0,y.jsx)("div",{className:k.codeBlockTitle,children:x}),(0,y.jsxs)("div",{className:k.codeBlockContent,children:[(0,y.jsx)(L.f4,{theme:f,code:b,language:h??"text",children:e=>{let{className:t,style:n,tokens:s,getLineProps:a,getTokenProps:o}=e;return(0,y.jsx)("pre",{tabIndex:0,ref:g.codeBlockRef,className:(0,i.A)(t,k.codeBlock,"thin-scrollbar"),style:n,children:(0,y.jsx)("code",{className:(0,i.A)(k.codeBlockLines,N&&k.codeBlockLinesWithNumbering),children:s.map(((e,t)=>(0,y.jsx)(T,{line:e,getLineProps:a,getTokenProps:o,classNames:j[t],showLineNumbers:N},t)))})})}}),(0,y.jsxs)("div",{className:k.buttonGroup,children:[(g.isEnabled||g.isCodeScrollable)&&(0,y.jsx)(V,{className:k.codeButton,onClick:()=>g.toggle(),isEnabled:g.isEnabled}),(0,y.jsx)(I,{className:k.codeButton,code:b})]})]})]})}function $(e){let{children:t,...n}=e;const a=(0,c.A)(),o=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof o?W:B;return(0,y.jsx)(i,{...n,children:o},String(a))}function D(e){return(0,y.jsx)("code",{...e})}var P=n(8774);var G=n(3427),q=n(1422);const O={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function F(e){return!!e&&("SUMMARY"===e.tagName||F(e.parentElement))}function Z(e,t){return!!e&&(e===t||Z(e.parentElement,t))}function J(e){let{summary:t,children:n,...a}=e;(0,G.A)().collectAnchor(a.id);const o=(0,c.A)(),r=(0,s.useRef)(null),{collapsed:l,setCollapsed:d}=(0,q.u)({initialState:!a.open}),[u,m]=(0,s.useState)(a.open),h=s.isValidElement(t)?t:(0,y.jsx)("summary",{children:t??"Details"});return(0,y.jsxs)("details",{...a,ref:r,open:u,"data-collapsed":l,className:(0,i.A)(O.details,o&&O.isBrowser,a.className),onMouseDown:e=>{F(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;F(t)&&Z(t,r.current)&&(e.preventDefault(),l?(d(!1),m(!0)):d(!0))},children:[h,(0,y.jsx)(q.N,{lazy:!1,collapsed:l,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{d(e),m(!e)},children:(0,y.jsx)("div",{className:O.collapsibleContent,children:n})})]})}const Y={details:"details_b_Ee"},K="alert alert--info";function Q(e){let{...t}=e;return(0,y.jsx)(J,{...t,className:(0,i.A)(K,Y.details,t.className)})}function X(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,y.jsx)(y.Fragment,{children:t.filter((e=>e!==n))});return(0,y.jsx)(Q,{...e,summary:n,children:a})}var ee=n(1107);function te(e){return(0,y.jsx)(ee.A,{...e})}const ne={containsTaskList:"containsTaskList_mC6p"};function se(e){if(void 0!==e)return(0,i.A)(e,e?.includes("contains-task-list")&&ne.containsTaskList)}const ae={img:"img_ev3q"};var oe=n(7293),ce=n(418);const ie={Head:o.A,details:X,Details:X,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,y.jsx)(D,{...e}):(0,y.jsx)($,{...e})},a:function(e){return(0,y.jsx)(P.A,{...e})},pre:function(e){return(0,y.jsx)(y.Fragment,{children:e.children})},ul:function(e){return(0,y.jsx)("ul",{...e,className:se(e.className)})},li:function(e){return(0,G.A)().collectAnchor(e.id),(0,y.jsx)("li",{...e})},img:function(e){return(0,y.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,i.A)(t,ae.img))});var t},h1:e=>(0,y.jsx)(te,{as:"h1",...e}),h2:e=>(0,y.jsx)(te,{as:"h2",...e}),h3:e=>(0,y.jsx)(te,{as:"h3",...e}),h4:e=>(0,y.jsx)(te,{as:"h4",...e}),h5:e=>(0,y.jsx)(te,{as:"h5",...e}),h6:e=>(0,y.jsx)(te,{as:"h6",...e}),admonition:oe.A,mermaid:ce.A};function re(e){let{children:t}=e;return(0,y.jsx)(a.x,{components:ie,children:t})}},9022:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var s=n(4164),a=n(8774),o=n(4848);function c(e){const{permalink:t,title:n,subLabel:c,isNext:i}=e;return(0,o.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",i?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[c&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:c}),(0,o.jsx)("div",{className:"pagination-nav__label",children:n})]})}},8046:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(6540);var s=n(4164),a=n(1312),o=n(8774);const c={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var i=n(4848);function r(e){let{permalink:t,label:n,count:a,description:r}=e;return(0,i.jsxs)(o.A,{href:t,title:r,className:(0,s.A)(c.tag,a?c.tagWithCount:c.tagRegular),children:[n,a&&(0,i.jsx)("span",{children:a})]})}const l={tags:"tags_jXut",tag:"tag_QGVx"};function d(e){let{tags:t}=e;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("b",{children:(0,i.jsx)(a.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,i.jsx)("ul",{className:(0,s.A)(l.tags,"padding--none","margin-left--sm"),children:t.map((e=>(0,i.jsx)("li",{className:l.tag,children:(0,i.jsx)(r,{...e})},e.permalink)))})]})}},6266:(e,t,n)=>{"use strict";n.d(t,{i:()=>a});var s=n(4586);function a(e){void 0===e&&(e={});const{i18n:{currentLocale:t}}=(0,s.A)(),n=function(){const{i18n:{currentLocale:e,localeConfigs:t}}=(0,s.A)();return t[e].calendar}();return new Intl.DateTimeFormat(t,{calendar:n,...e})}},8426:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,o]=t;if(s&&o){s=parseInt(s),o=parseInt(o);const e=s<o?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(o+=e);for(let t=s;t!==o;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},8453:(e,t,n)=>{"use strict";n.d(t,{R:()=>c,x:()=>i});var s=n(6540);const a={},o=s.createContext(a);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/5656e821.47aa1c90.js b/docs/assets/js/5656e821.47aa1c90.js new file mode 100644 index 00000000..f473a3f3 --- /dev/null +++ b/docs/assets/js/5656e821.47aa1c90.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[4939],{446:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"technical-guides/client/i18n","title":"i18n","description":"The localization uses the native Angular i18n feature.","source":"@site/docs/technical-guides/client/i18n.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/i18n","permalink":"/feedzback/docs/technical-guides/client/i18n","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/i18n.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Cookies","permalink":"/feedzback/docs/technical-guides/client/cookies"},"next":{"title":"Swagger","permalink":"/feedzback/docs/technical-guides/server/swagger"}}');var i=t(4848),r=t(8453);const c={},a="i18n",o={},l=[{value:"Be consistent with spaces",id:"be-consistent-with-spaces",level:2},{value:"Running the development server for the <code>en</code> locale",id:"running-the-development-server-for-the-en-locale",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"i18n",children:"i18n"})}),"\n",(0,i.jsx)(n.p,{children:"The localization uses the native Angular i18n feature."}),"\n",(0,i.jsxs)(n.p,{children:["The app is written in ",(0,i.jsx)(n.strong,{children:"French"})," and translated into ",(0,i.jsx)(n.strong,{children:"English"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["To generate the source file ",(0,i.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.fr.json",children:"src/locales/messages.fr.json"}),", run the following NPM script ",(0,i.jsx)(n.code,{children:"npm run extract-i18n"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Note the post-processing script ",(0,i.jsx)(n.code,{children:"postextract-i18n"}),", which sorts the translations alphabetically."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "extract-i18n": "ng extract-i18n --format json --output-path src/locales/ --out-file messages.fr.json",\n "postextract-i18n": "node src/locales/sort-messages-fr-translations.js"\n }\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The target file ",(0,i.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.en.json",children:"src/locales/messages.en.json"})," was created and translated manually."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"Don't forget to regenerate the source file every time you add or modify text in the source code.\nThen update the destination file accordingly."})}),"\n",(0,i.jsx)(n.h2,{id:"be-consistent-with-spaces",children:"Be consistent with spaces"}),"\n",(0,i.jsx)(n.p,{children:"When Angular generates the source file, some translations are surrounded by a space."}),"\n",(0,i.jsxs)(n.p,{children:["For example, in the file ",(0,i.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/feature/angular-18/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.component.html",children:(0,i.jsx)(n.code,{children:"give-requested-feedback.component.html"})}),", the text ",(0,i.jsx)(n.em,{children:'"Sauvegarder"'})," appears like this..."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-html",children:'<button\n type="button"\n [disabled]="submitInProgress"\n mat-stroked-button\n matTooltip="Enregistrer en tant que brouillon"\n i18n-matTooltip="@@Action.SaveAsDraft"\n i18n="@@Action.Save"\n (click)="onDraft()"\n>\n Sauvegarder\n</button>\n'})}),"\n",(0,i.jsxs)(n.p,{children:["...and in the file ",(0,i.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.fr.json",children:"src/locales/messages.fr.json"}),", the translation appears like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "locale": "fr",\n "translations": {\n "Action.Save": " Sauvegarder "\n }\n}\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"warning",children:(0,i.jsxs)(n.p,{children:["You must be consistent when the same text is used several times in the source code and preserve these spaces, otherwise the script ",(0,i.jsx)(n.code,{children:"npm run extract-i18n"})," will raise warnings."]})}),"\n",(0,i.jsxs)(n.h2,{id:"running-the-development-server-for-the-en-locale",children:["Running the development server for the ",(0,i.jsx)(n.code,{children:"en"})," locale"]}),"\n",(0,i.jsx)(n.p,{children:"As you probably know, the Angular development server does not support multiple locales\n(and the language switch button will not work in this environment)."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["To run the development server for the ",(0,i.jsx)(n.code,{children:"fr"})," locale, use the command: ",(0,i.jsx)(n.code,{children:"npm run start"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["To run the development server for the ",(0,i.jsx)(n.code,{children:"en"})," locale, use the command: ",(0,i.jsx)(n.code,{children:"npm run start:en"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var s=t(6540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/5656e821.8e255ae5.js b/docs/assets/js/5656e821.8e255ae5.js deleted file mode 100644 index 88e3fba7..00000000 --- a/docs/assets/js/5656e821.8e255ae5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[939],{446:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"technical-guides/client/i18n","title":"i18n","description":"The localization uses the native Angular i18n feature.","source":"@site/docs/technical-guides/client/i18n.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/i18n","permalink":"/feedzback/docs/technical-guides/client/i18n","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/i18n.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Cookies","permalink":"/feedzback/docs/technical-guides/client/cookies"},"next":{"title":"Swagger","permalink":"/feedzback/docs/technical-guides/server/swagger"}}');var r=t(4848),i=t(8453);const c={},o="i18n",a={},l=[{value:"Be consistent with spaces",id:"be-consistent-with-spaces",level:2},{value:"Running the development server for the <code>en</code> locale",id:"running-the-development-server-for-the-en-locale",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"i18n",children:"i18n"})}),"\n",(0,r.jsx)(n.p,{children:"The localization uses the native Angular i18n feature."}),"\n",(0,r.jsxs)(n.p,{children:["The app is written in ",(0,r.jsx)(n.strong,{children:"French"})," and translated into ",(0,r.jsx)(n.strong,{children:"English"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["To generate the source file ",(0,r.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.fr.json",children:"src/locales/messages.fr.json"}),", run the following NPM script ",(0,r.jsx)(n.code,{children:"npm run extract-i18n"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Note the post-processing script ",(0,r.jsx)(n.code,{children:"postextract-i18n"}),", which sorts the translations alphabetically."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "extract-i18n": "ng extract-i18n --format json --output-path src/locales/ --out-file messages.fr.json",\n "postextract-i18n": "node src/locales/sort-messages-fr-translations.js"\n }\n}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The target file ",(0,r.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.en.json",children:"src/locales/messages.en.json"})," was created and translated manually."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"Don't forget to regenerate the source file every time you add or modify text in the source code.\nThen update the destination file accordingly."})}),"\n",(0,r.jsx)(n.h2,{id:"be-consistent-with-spaces",children:"Be consistent with spaces"}),"\n",(0,r.jsx)(n.p,{children:"When Angular generates the source file, some translations are surrounded by a space."}),"\n",(0,r.jsxs)(n.p,{children:["For example, in the file ",(0,r.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/feature/angular-18/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.component.html",children:(0,r.jsx)(n.code,{children:"give-requested-feedback.component.html"})}),", the text ",(0,r.jsx)(n.em,{children:'"Sauvegarder"'})," appears like this..."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-html",children:'<button\n type="button"\n [disabled]="submitInProgress"\n mat-stroked-button\n matTooltip="Enregistrer en tant que brouillon"\n i18n-matTooltip="@@Action.SaveAsDraft"\n i18n="@@Action.Save"\n (click)="onDraft()"\n>\n Sauvegarder\n</button>\n'})}),"\n",(0,r.jsxs)(n.p,{children:["...and in the file ",(0,r.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/locales/messages.fr.json",children:"src/locales/messages.fr.json"}),", the translation appears like this:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'{\n "locale": "fr",\n "translations": {\n "Action.Save": " Sauvegarder "\n }\n}\n'})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["You must be consistent when the same text is used several times in the source code and preserve these spaces, otherwise the script ",(0,r.jsx)(n.code,{children:"npm run extract-i18n"})," will raise warnings."]})}),"\n",(0,r.jsxs)(n.h2,{id:"running-the-development-server-for-the-en-locale",children:["Running the development server for the ",(0,r.jsx)(n.code,{children:"en"})," locale"]}),"\n",(0,r.jsx)(n.p,{children:"As you probably know, the Angular development server does not support multiple locales\n(and the language switch button will not work in this environment)."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["To run the development server for the ",(0,r.jsx)(n.code,{children:"fr"})," locale, use the command: ",(0,r.jsx)(n.code,{children:"npm run start"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:["To run the development server for the ",(0,r.jsx)(n.code,{children:"en"})," locale, use the command: ",(0,r.jsx)(n.code,{children:"npm run start:en"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(6540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/5e95c892.2de06b2e.js b/docs/assets/js/5e95c892.2de06b2e.js deleted file mode 100644 index 56cbe723..00000000 --- a/docs/assets/js/5e95c892.2de06b2e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[647],{7121:(e,s,c)=>{c.r(s),c.d(s,{default:()=>f});c(6540);var r=c(4164),a=c(1213),d=c(7559),u=c(2831),n=c(781),t=c(4848);function f(e){return(0,t.jsx)(a.e3,{className:(0,r.A)(d.G.wrapper.docsPages),children:(0,t.jsx)(n.A,{children:(0,u.v)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/5e95c892.5cc96f6c.js b/docs/assets/js/5e95c892.5cc96f6c.js new file mode 100644 index 00000000..da1edd89 --- /dev/null +++ b/docs/assets/js/5e95c892.5cc96f6c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[9647],{7121:(e,s,c)=>{c.r(s),c.d(s,{default:()=>f});c(6540);var r=c(4164),a=c(1213),d=c(7559),u=c(2831),n=c(781),t=c(4848);function f(e){return(0,t.jsx)(a.e3,{className:(0,r.A)(d.G.wrapper.docsPages),children:(0,t.jsx)(n.A,{children:(0,u.v)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/621db11d.4780e475.js b/docs/assets/js/621db11d.4780e475.js new file mode 100644 index 00000000..d937f168 --- /dev/null +++ b/docs/assets/js/621db11d.4780e475.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[4212],{8790:(s,t,e)=>{e.r(t),e.d(t,{default:()=>x});e(6540);var a=e(4164),r=e(1213),o=e(7559),h=e(1312),i=e(4848);const u=()=>(0,h.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});var c=e(8027),n=e(1463),l=e(1107),d=e(6913);const g={authorListItem:"authorListItem_n3yI"};function b(s){let{author:t}=s;return(0,i.jsx)("li",{className:g.authorListItem,children:(0,i.jsx)(d.A,{as:"h2",author:t,count:t.count})})}function j(s){let{authors:t}=s;return(0,i.jsx)("section",{className:(0,a.A)("margin-vert--lg",g.authorsListSection),children:(0,i.jsx)("ul",{children:t.map((s=>(0,i.jsx)(b,{author:s},s.key)))})})}function x(s){let{authors:t,sidebar:e}=s;const h=u();return(0,i.jsxs)(r.e3,{className:(0,a.A)(o.G.wrapper.blogPages,o.G.page.blogAuthorsListPage),children:[(0,i.jsx)(r.be,{title:h}),(0,i.jsx)(n.A,{tag:"blog_authors_list"}),(0,i.jsxs)(c.A,{sidebar:e,children:[(0,i.jsx)(l.A,{as:"h1",children:h}),(0,i.jsx)(j,{authors:t})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/621db11d.ef111f0f.js b/docs/assets/js/621db11d.ef111f0f.js deleted file mode 100644 index 85a897a1..00000000 --- a/docs/assets/js/621db11d.ef111f0f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[212],{8790:(s,t,e)=>{e.r(t),e.d(t,{default:()=>x});e(6540);var a=e(4164),r=e(1213),o=e(7559),h=e(1312),i=e(4848);const u=()=>(0,h.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});var c=e(8027),n=e(1463),l=e(1107),d=e(6913);const g={authorListItem:"authorListItem_n3yI"};function b(s){let{author:t}=s;return(0,i.jsx)("li",{className:g.authorListItem,children:(0,i.jsx)(d.A,{as:"h2",author:t,count:t.count})})}function j(s){let{authors:t}=s;return(0,i.jsx)("section",{className:(0,a.A)("margin-vert--lg",g.authorsListSection),children:(0,i.jsx)("ul",{children:t.map((s=>(0,i.jsx)(b,{author:s},s.key)))})})}function x(s){let{authors:t,sidebar:e}=s;const h=u();return(0,i.jsxs)(r.e3,{className:(0,a.A)(o.G.wrapper.blogPages,o.G.page.blogAuthorsListPage),children:[(0,i.jsx)(r.be,{title:h}),(0,i.jsx)(n.A,{tag:"blog_authors_list"}),(0,i.jsxs)(c.A,{sidebar:e,children:[(0,i.jsx)(l.A,{as:"h1",children:h}),(0,i.jsx)(j,{authors:t})]})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/634558fb.6d867026.js b/docs/assets/js/634558fb.6d867026.js new file mode 100644 index 00000000..3a2eb72e --- /dev/null +++ b/docs/assets/js/634558fb.6d867026.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2172],{2252:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"business-cases/reply-to-feedback-request","title":"Reply to feedback request","description":"User story","source":"@site/docs/business-cases/reply-to-feedback-request.md","sourceDirName":"business-cases","slug":"/business-cases/reply-to-feedback-request","permalink":"/feedzback/docs/business-cases/reply-to-feedback-request","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/reply-to-feedback-request.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Request feedback","permalink":"/feedzback/docs/business-cases/request-feedback"},"next":{"title":"Give spontaneous feedback","permalink":"/feedzback/docs/business-cases/give-spontaneous-feedback"}}');var i=n(4848),c=n(8453);const d={},r="Reply to feedback request",a={},l=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,c.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"reply-to-feedback-request",children:"Reply to feedback request"})}),"\n",(0,i.jsx)(s.h2,{id:"user-story",children:"User story"}),"\n",(0,i.jsx)(s.p,{children:"As I have received a feedback request, I would like to be able to reply to this request.\nIf I can't complete my feedback in one go, I'd like to be able to save it as a draft and continue later."}),"\n",(0,i.jsx)(s.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,i.jsxs)(s.p,{children:["Be sure to read ",(0,i.jsx)(s.a,{href:"./request-feedback",children:"Request feedback"})," first.\nTo learn more about draft, read the ",(0,i.jsx)(s.a,{href:"./feedback-draft",children:"Feedback draft"})," documentation."]}),"\n",(0,i.jsxs)(s.p,{children:["To reply to a feedback request, the ",(0,i.jsx)(s.code,{children:"giverEmail"})," must visit the following page, based on its secret ",(0,i.jsx)(s.code,{children:"tokenId"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-txt",children:"/give-requested/token/<tokenId>\n"})}),"\n",(0,i.jsxs)(s.p,{children:["As the ",(0,i.jsx)(s.code,{children:"giverEmail"})," may be external to the Zenika organisation, access to this page does not require user authentification.\nInstead, the ",(0,i.jsx)(s.code,{children:"tokenId"})," acts as an access token."]}),"\n",(0,i.jsxs)(s.p,{children:["On client side, the ",(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.guard.ts",children:(0,i.jsx)(s.code,{children:"giveRequestedFeedbackGuard"})})," guard ensures that the ",(0,i.jsx)(s.code,{children:"tokenId"})," is valid.\nIf the ",(0,i.jsx)(s.code,{children:"giverEmail"})," is already authenticated, it remains authenticated.\nOtherwise, he is silently authenticated as an anonymous user (in other words, a session is created for him)."]}),"\n",(0,i.jsxs)(s.p,{children:["On server side, the ",(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,i.jsx)(s.code,{children:"FeedbackController.checkRequest"})})," method returns the feedback request details and possibly a previously saved draft."]}),"\n",(0,i.jsx)(s.p,{children:"Once the feedback is complete, 2 or 3 Firestore documents are affected:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["In the ",(0,i.jsx)(s.code,{children:"feedback"})," collection, the document with ID ",(0,i.jsx)(s.code,{children:"feedbackId"})," is updated:"]}),"\n"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-ts",children:"const feedback: Feedback = {\n giverEmail: 'gimini@zenika.com',\n receiverEmail: 'pinocchio@zenika.com',\n\n // -----------------------------------------------------\n // Added fields (in reality, the contents are encrypted)\n positive: 'You did great...', // required\n negative: 'Youd should improve...', // required\n comment: '', // optional\n // -----------------------------------------------------\n\n message: 'Hi Gimini, give me some feedback please.',\n shared: true,\n requested: true,\n status: 'done', // Updated field\n createdAt: 1711403799463,\n updatedAt: 1711712182618, // Updated field\n archived: 0,\n};\n"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In the ",(0,i.jsx)(s.code,{children:"feedbackRequestToken"})," collection, the document with ID ",(0,i.jsx)(s.code,{children:"tokenId"})," is deleted."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In the ",(0,i.jsx)(s.code,{children:"feedbackDraft"})," collection, the draft, if it exists, is deleted."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.p,{children:["Finally, an email is sent to the ",(0,i.jsx)(s.code,{children:"receiverEmail"})," inviting them to consult the feedback they have just received."]}),"\n",(0,i.jsx)(s.h2,{id:"links",children:"Links"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Client"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.guard.ts",children:(0,i.jsx)(s.code,{children:"giveRequestedFeedbackGuard"})})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.component.ts",children:(0,i.jsx)(s.code,{children:"GiveRequestedFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Server"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,i.jsx)(s.code,{children:"FeedbackController"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"checkRequest"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"giveRequested"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>d,x:()=>r});var t=n(6540);const i={},c=t.createContext(i);function d(e){const s=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/634558fb.6e63cc59.js b/docs/assets/js/634558fb.6e63cc59.js deleted file mode 100644 index 568a6411..00000000 --- a/docs/assets/js/634558fb.6e63cc59.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[172],{2252:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"business-cases/reply-to-feedback-request","title":"Reply to feedback request","description":"User story","source":"@site/docs/business-cases/reply-to-feedback-request.md","sourceDirName":"business-cases","slug":"/business-cases/reply-to-feedback-request","permalink":"/feedzback/docs/business-cases/reply-to-feedback-request","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/reply-to-feedback-request.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Request feedback","permalink":"/feedzback/docs/business-cases/request-feedback"},"next":{"title":"Give spontaneous feedback","permalink":"/feedzback/docs/business-cases/give-spontaneous-feedback"}}');var i=n(4848),c=n(8453);const d={},r="Reply to feedback request",a={},l=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,c.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"reply-to-feedback-request",children:"Reply to feedback request"})}),"\n",(0,i.jsx)(s.h2,{id:"user-story",children:"User story"}),"\n",(0,i.jsx)(s.p,{children:"As I have received a feedback request, I would like to be able to reply to this request.\nIf I can't complete my feedback in one go, I'd like to be able to save it as a draft and continue later."}),"\n",(0,i.jsx)(s.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,i.jsxs)(s.p,{children:["Be sure to read ",(0,i.jsx)(s.a,{href:"./request-feedback",children:"Request feedback"})," first.\nTo learn more about draft, read the ",(0,i.jsx)(s.a,{href:"./feedback-draft",children:"Feedback draft"})," documentation."]}),"\n",(0,i.jsxs)(s.p,{children:["To reply to a feedback request, the ",(0,i.jsx)(s.code,{children:"giverEmail"})," must visit the following page, based on its secret ",(0,i.jsx)(s.code,{children:"tokenId"}),":"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-txt",children:"/give-requested/token/<tokenId>\n"})}),"\n",(0,i.jsxs)(s.p,{children:["As the ",(0,i.jsx)(s.code,{children:"giverEmail"})," may be external to the Zenika organisation, access to this page does not require user authentification.\nInstead, the ",(0,i.jsx)(s.code,{children:"tokenId"})," acts as an access token."]}),"\n",(0,i.jsxs)(s.p,{children:["On client side, the ",(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.guard.ts",children:(0,i.jsx)(s.code,{children:"giveRequestedFeedbackGuard"})})," guard ensures that the ",(0,i.jsx)(s.code,{children:"tokenId"})," is valid.\nIf the ",(0,i.jsx)(s.code,{children:"giverEmail"})," is already authenticated, it remains authenticated.\nOtherwise, he is silently authenticated as an anonymous user (in other words, a session is created for him)."]}),"\n",(0,i.jsxs)(s.p,{children:["On server side, the ",(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,i.jsx)(s.code,{children:"FeedbackController.checkRequest"})})," method returns the feedback request details and possibly a previously saved draft."]}),"\n",(0,i.jsx)(s.p,{children:"Once the feedback is complete, 2 or 3 Firestore documents are affected:"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["In the ",(0,i.jsx)(s.code,{children:"feedback"})," collection, the document with ID ",(0,i.jsx)(s.code,{children:"feedbackId"})," is updated:"]}),"\n"]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-ts",children:"const feedback: Feedback = {\n giverEmail: 'gimini@zenika.com',\n receiverEmail: 'pinocchio@zenika.com',\n\n // -----------------------------------------------------\n // Added fields (in reality, the contents are encrypted)\n positive: 'You did great...', // required\n negative: 'Youd should improve...', // required\n comment: '', // optional\n // -----------------------------------------------------\n\n message: 'Hi Gimini, give me some feedback please.',\n shared: true,\n requested: true,\n status: 'done', // Updated field\n createdAt: 1711403799463,\n updatedAt: 1711712182618, // Updated field\n archived: 0,\n};\n"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In the ",(0,i.jsx)(s.code,{children:"feedbackRequestToken"})," collection, the document with ID ",(0,i.jsx)(s.code,{children:"tokenId"})," is deleted."]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["\n",(0,i.jsxs)(s.p,{children:["In the ",(0,i.jsx)(s.code,{children:"feedbackDraft"})," collection, the draft, if it exists, is deleted."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.p,{children:["Finally, an email is sent to the ",(0,i.jsx)(s.code,{children:"receiverEmail"})," inviting them to consult the feedback they have just received."]}),"\n",(0,i.jsx)(s.h2,{id:"links",children:"Links"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Client"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.guard.ts",children:(0,i.jsx)(s.code,{children:"giveRequestedFeedbackGuard"})})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.component.ts",children:(0,i.jsx)(s.code,{children:"GiveRequestedFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"Server"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,i.jsx)(s.code,{children:"FeedbackController"})}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"checkRequest"})}),"\n",(0,i.jsx)(s.li,{children:(0,i.jsx)(s.code,{children:"giveRequested"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>d,x:()=>r});var t=n(6540);const i={},c=t.createContext(i);function d(e){const s=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/65a3cb41.38af0435.js b/docs/assets/js/65a3cb41.38af0435.js deleted file mode 100644 index fd02e160..00000000 --- a/docs/assets/js/65a3cb41.38af0435.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[906],{1868:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"technical-guides/environments/local","title":"Local","description":"As explained in the installation guide, you can run the client and server apps locally, for development purposes.","source":"@site/docs/technical-guides/environments/local.md","sourceDirName":"technical-guides/environments","slug":"/technical-guides/environments/local","permalink":"/feedzback/docs/technical-guides/environments/local","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/environments/local.md","tags":[],"version":"current","frontMatter":{"title":"Local"},"sidebar":"default","previous":{"title":"Overview","permalink":"/feedzback/docs/technical-guides/environments/overview"},"next":{"title":"Firebase Hosting","permalink":"/feedzback/docs/technical-guides/client/firebase-hosting"}}');var r=t(4848),i=t(8453);const o={title:"Local"},a="Local dev environment",c={},l=[{value:"<code>*:emulators</code> scripts",id:"emulators-scripts",level:2},{value:"<code>*:e2e</code> scripts",id:"e2e-scripts",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"local-dev-environment",children:"Local dev environment"})}),"\n",(0,r.jsxs)(n.p,{children:["As explained in the ",(0,r.jsx)(n.a,{href:"/docs/installation",children:"installation guide"}),", you can run the ",(0,r.jsx)(n.em,{children:"client"})," and ",(0,r.jsx)(n.em,{children:"server"})," apps locally, for development purposes.\nBut you are still connecting to the remote ",(0,r.jsx)(n.code,{children:"feedzback-v2-dev"})," Firebase project for Authentication and Firestore services."]}),"\n",(0,r.jsxs)(n.p,{children:["The good news is that you can run the entire stack locally, using the ",(0,r.jsx)(n.a,{href:"https://firebase.google.com/docs/emulator-suite",children:"Firebase emulator suite"}),"!"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsx)(n.p,{children:"When using the Firebase emulator, the Google Auth provider is no longer available.\nOnly the Email/Password provider is enabled."})}),"\n",(0,r.jsxs)(n.h2,{id:"emulators-scripts",children:[(0,r.jsx)(n.code,{children:"*:emulators"})," scripts"]}),"\n",(0,r.jsxs)(n.p,{children:["In this execution context, the ",(0,r.jsx)(n.em,{children:"client"})," and ",(0,r.jsx)(n.em,{children:"server"}),' apps are running in "dev" mode (with hot-reloading).']}),"\n",(0,r.jsxs)(n.p,{children:["Only the Firebase ",(0,r.jsx)(n.em,{children:"Auth"})," and ",(0,r.jsx)(n.em,{children:"Firestore"})," emulators are started. The ",(0,r.jsx)(n.em,{children:"Hosting"})," emulator is not used in this context."]}),"\n",(0,r.jsx)(n.p,{children:"Here are the NPM scripts for this execution context:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",metastring:'title="/client/package.json"',children:'{\n "scripts": {\n "start:emulators": "ng serve -c development-emulators",\n "firebase:emulators": "firebase emulators:start --only auth:dev,firestore:dev --import ./firebase-emulators-data",\n "server:emulators": "npm --prefix ../server run start:emulators",\n\n // To launch the stack with a single command:\n "stack:emulators": "concurrently \\"npm run firebase:emulators\\" \\"npm run server:emulators\\" \\"npm run start:emulators\\""\n }\n}\n'})}),"\n",(0,r.jsxs)(n.h2,{id:"e2e-scripts",children:[(0,r.jsx)(n.code,{children:"*:e2e"})," scripts"]}),"\n",(0,r.jsxs)(n.p,{children:["In this execution context, the ",(0,r.jsx)(n.em,{children:"client"})," and ",(0,r.jsx)(n.em,{children:"server"}),' apps are running in "build" mode (no hot-reloading).']}),"\n",(0,r.jsxs)(n.p,{children:["This time, not only are the Firebase ",(0,r.jsx)(n.em,{children:"Auth"})," and ",(0,r.jsx)(n.em,{children:"Firestore"})," emulators started, but so is the ",(0,r.jsx)(n.em,{children:"Hosting"})," emulator that serves the client application."]}),"\n",(0,r.jsx)(n.p,{children:"This environment is the closest to the production environment (with the exception of the authentication method) and is therefore ideal for e2e testing."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",metastring:'title="/client/package.json"',children:'{\n "scripts": {\n "firebase:e2e": "firebase emulators:start --only auth:dev,firestore:dev,hosting:dev --import ./firebase-emulators-data",\n "server:e2e": "npm --prefix ../server run start:e2e",\n\n // To launch the stack with a single command:\n "prestack:e2e": "npm run build:e2e",\n "stack:e2e": "concurrently \\"npm run firebase:e2e\\" \\"npm run server:e2e\\""\n }\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(6540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/6c28a435.12d52798.js b/docs/assets/js/6c28a435.12d52798.js new file mode 100644 index 00000000..52f32531 --- /dev/null +++ b/docs/assets/js/6c28a435.12d52798.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[4347],{4248:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"default":[{"type":"link","label":"Audience","href":"/feedzback/docs/audience","docId":"audience","unlisted":false},{"type":"link","label":"Technical stack","href":"/feedzback/docs/technical-stack","docId":"technical-stack","unlisted":false},{"type":"link","label":"Installation","href":"/feedzback/docs/installation","docId":"installation","unlisted":false},{"type":"category","label":"Business cases","items":[{"type":"link","label":"Request feedback","href":"/feedzback/docs/business-cases/request-feedback","docId":"business-cases/request-feedback","unlisted":false},{"type":"link","label":"Reply to feedback request","href":"/feedzback/docs/business-cases/reply-to-feedback-request","docId":"business-cases/reply-to-feedback-request","unlisted":false},{"type":"link","label":"Give spontaneous feedback","href":"/feedzback/docs/business-cases/give-spontaneous-feedback","docId":"business-cases/give-spontaneous-feedback","unlisted":false},{"type":"link","label":"Feedback draft","href":"/feedzback/docs/business-cases/feedback-draft","docId":"business-cases/feedback-draft","unlisted":false},{"type":"link","label":"Shared feedback","href":"/feedzback/docs/business-cases/shared-feedback","docId":"business-cases/shared-feedback","unlisted":false},{"type":"link","label":"Archiving","href":"/feedzback/docs/business-cases/archiving","docId":"business-cases/archiving","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Ubiquitous language","href":"/feedzback/docs/ubiquitous-language","docId":"ubiquitous-language","unlisted":false},{"type":"category","label":"Technical guides","items":[{"type":"category","label":"Environments","items":[{"type":"link","label":"Overview","href":"/feedzback/docs/technical-guides/environments/overview","docId":"technical-guides/environments/overview","unlisted":false},{"type":"link","label":"Local dev","href":"/feedzback/docs/technical-guides/environments/local-dev","docId":"technical-guides/environments/local-dev","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Client","items":[{"type":"link","label":"Firebase Hosting","href":"/feedzback/docs/technical-guides/client/firebase-hosting","docId":"technical-guides/client/firebase-hosting","unlisted":false},{"type":"link","label":"Styles","href":"/feedzback/docs/technical-guides/client/styles","docId":"technical-guides/client/styles","unlisted":false},{"type":"link","label":"Icons","href":"/feedzback/docs/technical-guides/client/icons","docId":"technical-guides/client/icons","unlisted":false},{"type":"link","label":"Demo","href":"/feedzback/docs/technical-guides/client/demo","docId":"technical-guides/client/demo","unlisted":false},{"type":"link","label":"Cookies","href":"/feedzback/docs/technical-guides/client/cookies","docId":"technical-guides/client/cookies","unlisted":false},{"type":"link","label":"i18n","href":"/feedzback/docs/technical-guides/client/i18n","docId":"technical-guides/client/i18n","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Server","items":[{"type":"link","label":"Swagger","href":"/feedzback/docs/technical-guides/server/swagger","docId":"technical-guides/server/swagger","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"E2E testing","href":"/feedzback/docs/technical-guides/e2e-testing","docId":"technical-guides/e2e-testing","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"CI / CD","items":[{"type":"link","label":"Quick start","href":"/feedzback/docs/ci-cd/quick-start","docId":"ci-cd/quick-start","unlisted":false},{"type":"link","label":"CircleCI","href":"/feedzback/docs/ci-cd/circle-ci","docId":"ci-cd/circle-ci","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Usage analytics","href":"/feedzback/docs/usage-analytics","docId":"usage-analytics","unlisted":false},{"type":"category","label":"Update guide","items":[{"type":"link","label":"Client app","href":"/feedzback/docs/update/client","docId":"update/client","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Documentation","href":"/feedzback/docs/documentation","docId":"documentation","unlisted":false}]},"docs":{"audience":{"id":"audience","title":"Audience","description":"This documentation is aimed at developers who need to participate in the project.","sidebar":"default"},"business-cases/archiving":{"id":"business-cases/archiving","title":"Archiving","description":"User story","sidebar":"default"},"business-cases/feedback-draft":{"id":"business-cases/feedback-draft","title":"Feedback draft","description":"User story","sidebar":"default"},"business-cases/give-spontaneous-feedback":{"id":"business-cases/give-spontaneous-feedback","title":"Give spontaneous feedback","description":"User story","sidebar":"default"},"business-cases/reply-to-feedback-request":{"id":"business-cases/reply-to-feedback-request","title":"Reply to feedback request","description":"User story","sidebar":"default"},"business-cases/request-feedback":{"id":"business-cases/request-feedback","title":"Request feedback","description":"User story","sidebar":"default"},"business-cases/shared-feedback":{"id":"business-cases/shared-feedback","title":"Shared feedback","description":"User story","sidebar":"default"},"ci-cd/circle-ci":{"id":"ci-cd/circle-ci","title":"CircleCI","description":"Pre-requisites","sidebar":"default"},"ci-cd/quick-start":{"id":"ci-cd/quick-start","title":"Quick start","description":"This repository includes a fully integrated CI/CD script that works with CircleCI (see .circleci/config.yml).","sidebar":"default"},"documentation":{"id":"documentation","title":"Documentation","description":"This documentation is powered by the Docusaurus framework.","sidebar":"default"},"installation":{"id":"installation","title":"Installation","description":"Permissions","sidebar":"default"},"technical-guides/client/cookies":{"id":"technical-guides/client/cookies","title":"Cookies","description":"The application is available in two languages: English and French. The app-locale-id cookie reflects the language used by the client. This cookie must be provided in certain HTTP requests.","sidebar":"default"},"technical-guides/client/demo":{"id":"technical-guides/client/demo","title":"Demo","description":"Some components of the design system are presented in a demo available here:","sidebar":"default"},"technical-guides/client/firebase-hosting":{"id":"technical-guides/client/firebase-hosting","title":"Firebase Hosting","description":"The client app is deployed on Firebase Hosting which uses 2 configuration files.","sidebar":"default"},"technical-guides/client/i18n":{"id":"technical-guides/client/i18n","title":"i18n","description":"The localization uses the native Angular i18n feature.","sidebar":"default"},"technical-guides/client/icons":{"id":"technical-guides/client/icons","title":"Icons","description":"Material icons","sidebar":"default"},"technical-guides/client/styles":{"id":"technical-guides/client/styles","title":"Styles","description":"Global styles","sidebar":"default"},"technical-guides/e2e-testing":{"id":"technical-guides/e2e-testing","title":"E2E testing","description":"E2E tests are performed using Playwright.","sidebar":"default"},"technical-guides/environments/local-dev":{"id":"technical-guides/environments/local-dev","title":"Local dev","description":"As explained in the installation guide, you can run the client and server apps locally, for development purposes.","sidebar":"default"},"technical-guides/environments/overview":{"id":"technical-guides/environments/overview","title":"Overview","description":"There are 3 remote environments: production, staging and development.","sidebar":"default"},"technical-guides/server/swagger":{"id":"technical-guides/server/swagger","title":"Swagger","description":"Discover the server API via Swagger dev or Swagger staging.","sidebar":"default"},"technical-stack":{"id":"technical-stack","title":"Technical stack","description":"Client app","sidebar":"default"},"ubiquitous-language":{"id":"ubiquitous-language","title":"Ubiquitous language","description":"anonymous user","sidebar":"default"},"update/client":{"id":"update/client","title":"Client app","description":"You can update the Angular framework dependencies by following the instructions provided by Angular.","sidebar":"default"},"usage-analytics":{"id":"usage-analytics","title":"Usage analytics","description":"1. The plugin Stream Firestore to BigQuery streams every change in the firestore DB into a BigQuery table (including the user e-mails which are personal data, but the feedback itself is encrypted)","sidebar":"default"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/6c28a435.b95862a6.js b/docs/assets/js/6c28a435.b95862a6.js deleted file mode 100644 index 9c474692..00000000 --- a/docs/assets/js/6c28a435.b95862a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[347],{4248:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"default":[{"type":"link","label":"Audience","href":"/feedzback/docs/audience","docId":"audience","unlisted":false},{"type":"link","label":"Technical stack","href":"/feedzback/docs/technical-stack","docId":"technical-stack","unlisted":false},{"type":"link","label":"Installation","href":"/feedzback/docs/installation","docId":"installation","unlisted":false},{"type":"category","label":"Business cases","items":[{"type":"link","label":"Request feedback","href":"/feedzback/docs/business-cases/request-feedback","docId":"business-cases/request-feedback","unlisted":false},{"type":"link","label":"Reply to feedback request","href":"/feedzback/docs/business-cases/reply-to-feedback-request","docId":"business-cases/reply-to-feedback-request","unlisted":false},{"type":"link","label":"Give spontaneous feedback","href":"/feedzback/docs/business-cases/give-spontaneous-feedback","docId":"business-cases/give-spontaneous-feedback","unlisted":false},{"type":"link","label":"Feedback draft","href":"/feedzback/docs/business-cases/feedback-draft","docId":"business-cases/feedback-draft","unlisted":false},{"type":"link","label":"Shared feedback","href":"/feedzback/docs/business-cases/shared-feedback","docId":"business-cases/shared-feedback","unlisted":false},{"type":"link","label":"Archiving","href":"/feedzback/docs/business-cases/archiving","docId":"business-cases/archiving","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Ubiquitous language","href":"/feedzback/docs/ubiquitous-language","docId":"ubiquitous-language","unlisted":false},{"type":"category","label":"Technical guides","items":[{"type":"category","label":"Environments","items":[{"type":"link","label":"Overview","href":"/feedzback/docs/technical-guides/environments/overview","docId":"technical-guides/environments/overview","unlisted":false},{"type":"link","label":"Local","href":"/feedzback/docs/technical-guides/environments/local","docId":"technical-guides/environments/local","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Client","items":[{"type":"link","label":"Firebase Hosting","href":"/feedzback/docs/technical-guides/client/firebase-hosting","docId":"technical-guides/client/firebase-hosting","unlisted":false},{"type":"link","label":"Styles","href":"/feedzback/docs/technical-guides/client/styles","docId":"technical-guides/client/styles","unlisted":false},{"type":"link","label":"Icons","href":"/feedzback/docs/technical-guides/client/icons","docId":"technical-guides/client/icons","unlisted":false},{"type":"link","label":"Demo","href":"/feedzback/docs/technical-guides/client/demo","docId":"technical-guides/client/demo","unlisted":false},{"type":"link","label":"Cookies","href":"/feedzback/docs/technical-guides/client/cookies","docId":"technical-guides/client/cookies","unlisted":false},{"type":"link","label":"i18n","href":"/feedzback/docs/technical-guides/client/i18n","docId":"technical-guides/client/i18n","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Server","items":[{"type":"link","label":"Swagger","href":"/feedzback/docs/technical-guides/server/swagger","docId":"technical-guides/server/swagger","unlisted":false}],"collapsed":true,"collapsible":true}],"collapsed":true,"collapsible":true},{"type":"category","label":"CI / CD","items":[{"type":"link","label":"Quick start","href":"/feedzback/docs/ci-cd/quick-start","docId":"ci-cd/quick-start","unlisted":false},{"type":"link","label":"CircleCI","href":"/feedzback/docs/ci-cd/circle-ci","docId":"ci-cd/circle-ci","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Usage analytics","href":"/feedzback/docs/usage-analytics","docId":"usage-analytics","unlisted":false},{"type":"category","label":"Update guide","items":[{"type":"link","label":"Client app","href":"/feedzback/docs/update/client","docId":"update/client","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Documentation","href":"/feedzback/docs/documentation","docId":"documentation","unlisted":false}]},"docs":{"audience":{"id":"audience","title":"Audience","description":"This documentation is aimed at developers who need to participate in the project.","sidebar":"default"},"business-cases/archiving":{"id":"business-cases/archiving","title":"Archiving","description":"User story","sidebar":"default"},"business-cases/feedback-draft":{"id":"business-cases/feedback-draft","title":"Feedback draft","description":"User story","sidebar":"default"},"business-cases/give-spontaneous-feedback":{"id":"business-cases/give-spontaneous-feedback","title":"Give spontaneous feedback","description":"User story","sidebar":"default"},"business-cases/reply-to-feedback-request":{"id":"business-cases/reply-to-feedback-request","title":"Reply to feedback request","description":"User story","sidebar":"default"},"business-cases/request-feedback":{"id":"business-cases/request-feedback","title":"Request feedback","description":"User story","sidebar":"default"},"business-cases/shared-feedback":{"id":"business-cases/shared-feedback","title":"Shared feedback","description":"User story","sidebar":"default"},"ci-cd/circle-ci":{"id":"ci-cd/circle-ci","title":"CircleCI","description":"Pre-requisites","sidebar":"default"},"ci-cd/quick-start":{"id":"ci-cd/quick-start","title":"Quick start","description":"This repository includes a fully integrated CI/CD script that works with CircleCI (see .circleci/config.yml).","sidebar":"default"},"documentation":{"id":"documentation","title":"Documentation","description":"This documentation is powered by the Docusaurus framework.","sidebar":"default"},"installation":{"id":"installation","title":"Installation","description":"Permissions","sidebar":"default"},"technical-guides/client/cookies":{"id":"technical-guides/client/cookies","title":"Cookies","description":"The application is available in two languages: English and French. The app-locale-id cookie reflects the language used by the client. This cookie must be provided in certain HTTP requests.","sidebar":"default"},"technical-guides/client/demo":{"id":"technical-guides/client/demo","title":"Demo","description":"Some components of the design system are presented in a demo available here:","sidebar":"default"},"technical-guides/client/firebase-hosting":{"id":"technical-guides/client/firebase-hosting","title":"Firebase Hosting","description":"The client app is deployed on Firebase Hosting which uses 2 configuration files.","sidebar":"default"},"technical-guides/client/i18n":{"id":"technical-guides/client/i18n","title":"i18n","description":"The localization uses the native Angular i18n feature.","sidebar":"default"},"technical-guides/client/icons":{"id":"technical-guides/client/icons","title":"Icons","description":"Material icons","sidebar":"default"},"technical-guides/client/styles":{"id":"technical-guides/client/styles","title":"Styles","description":"Global styles","sidebar":"default"},"technical-guides/environments/local":{"id":"technical-guides/environments/local","title":"Local","description":"As explained in the installation guide, you can run the client and server apps locally, for development purposes.","sidebar":"default"},"technical-guides/environments/overview":{"id":"technical-guides/environments/overview","title":"Overview","description":"There are 3 remote environments: production, staging and development.","sidebar":"default"},"technical-guides/server/swagger":{"id":"technical-guides/server/swagger","title":"Swagger","description":"Discover the server API via Swagger dev or Swagger staging.","sidebar":"default"},"technical-stack":{"id":"technical-stack","title":"Technical stack","description":"Client app","sidebar":"default"},"ubiquitous-language":{"id":"ubiquitous-language","title":"Ubiquitous language","description":"anonymous user","sidebar":"default"},"update/client":{"id":"update/client","title":"Client app","description":"You can update the Angular framework dependencies by following the instructions provided by Angular.","sidebar":"default"},"usage-analytics":{"id":"usage-analytics","title":"Usage analytics","description":"1. The plugin Stream Firestore to BigQuery streams every change in the firestore DB into a BigQuery table (including the user e-mails which are personal data, but the feedback itself is encrypted)","sidebar":"default"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/6e9c3c91.129da40e.js b/docs/assets/js/6e9c3c91.129da40e.js deleted file mode 100644 index 46d85a8a..00000000 --- a/docs/assets/js/6e9c3c91.129da40e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[368],{8317:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"starting-documentation","metadata":{"permalink":"/feedzback/blog/starting-documentation","editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/blog/2024-03-11-starting-documentation.md","source":"@site/blog/2024-03-11-starting-documentation.md","title":"Starting documentation","description":"This is the summary of a very long blog post,","date":"2024-03-11T00:00:00.000Z","tags":[],"readingTime":2.05,"hasTruncateMarker":true,"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null}],"frontMatter":{"slug":"starting-documentation","title":"Starting documentation","authors":"stephane.francel","tags":[]},"unlisted":false},"content":"This is the summary of a very long blog post,\\n\\nUse a `\x3c!--` `truncate` `--\x3e` comment to limit blog post size in the list view.\\n\\n\x3c!--truncate--\x3e\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}]}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/6e9c3c91.2e372a7e.js b/docs/assets/js/6e9c3c91.2e372a7e.js new file mode 100644 index 00000000..7ae9515a --- /dev/null +++ b/docs/assets/js/6e9c3c91.2e372a7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[7368],{8317:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"starting-documentation","metadata":{"permalink":"/feedzback/blog/starting-documentation","editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/blog/2024-03-11-starting-documentation.md","source":"@site/blog/2024-03-11-starting-documentation.md","title":"Starting documentation","description":"This is the summary of a very long blog post,","date":"2024-03-11T00:00:00.000Z","tags":[],"readingTime":2.05,"hasTruncateMarker":true,"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null}],"frontMatter":{"slug":"starting-documentation","title":"Starting documentation","authors":"stephane.francel","tags":[]},"unlisted":false},"content":"This is the summary of a very long blog post,\\n\\nUse a `\x3c!--` `truncate` `--\x3e` comment to limit blog post size in the list view.\\n\\n\x3c!--truncate--\x3e\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet\\n\\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}]}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/75212946.2bcde41c.js b/docs/assets/js/75212946.2bcde41c.js deleted file mode 100644 index 8e2abda3..00000000 --- a/docs/assets/js/75212946.2bcde41c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[317],{5551:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>u,contentTitle:()=>m,default:()=>a,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var i=t(8826),o=t(4848),n=t(8453);const r={slug:"starting-documentation",title:"Starting documentation",authors:"stephane.francel",tags:[]},m=void 0,u={authorsImageUrls:[void 0]},c=[];function l(e){const s={code:"code",p:"p",...(0,n.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.p,{children:"This is the summary of a very long blog post,"}),"\n",(0,o.jsxs)(s.p,{children:["Use a ",(0,o.jsx)(s.code,{children:"\x3c!--"})," ",(0,o.jsx)(s.code,{children:"truncate"})," ",(0,o.jsx)(s.code,{children:"--\x3e"})," comment to limit blog post size in the list view."]}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"})]})}function a(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>m});var i=t(6540);const o={},n=i.createContext(o);function r(e){const s=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function m(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(n.Provider,{value:s},e.children)}},8826:e=>{e.exports=JSON.parse('{"permalink":"/feedzback/blog/starting-documentation","editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/blog/2024-03-11-starting-documentation.md","source":"@site/blog/2024-03-11-starting-documentation.md","title":"Starting documentation","description":"This is the summary of a very long blog post,","date":"2024-03-11T00:00:00.000Z","tags":[],"readingTime":2.05,"hasTruncateMarker":true,"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null}],"frontMatter":{"slug":"starting-documentation","title":"Starting documentation","authors":"stephane.francel","tags":[]},"unlisted":false}')}}]); \ No newline at end of file diff --git a/docs/assets/js/75212946.c3d2a655.js b/docs/assets/js/75212946.c3d2a655.js new file mode 100644 index 00000000..de253af5 --- /dev/null +++ b/docs/assets/js/75212946.c3d2a655.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[9317],{5551:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>u,contentTitle:()=>m,default:()=>a,frontMatter:()=>r,metadata:()=>i,toc:()=>c});var i=t(8826),o=t(4848),n=t(8453);const r={slug:"starting-documentation",title:"Starting documentation",authors:"stephane.francel",tags:[]},m=void 0,u={authorsImageUrls:[void 0]},c=[];function l(e){const s={code:"code",p:"p",...(0,n.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.p,{children:"This is the summary of a very long blog post,"}),"\n",(0,o.jsxs)(s.p,{children:["Use a ",(0,o.jsx)(s.code,{children:"\x3c!--"})," ",(0,o.jsx)(s.code,{children:"truncate"})," ",(0,o.jsx)(s.code,{children:"--\x3e"})," comment to limit blog post size in the list view."]}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"}),"\n",(0,o.jsx)(s.p,{children:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet"})]})}function a(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,s,t)=>{t.d(s,{R:()=>r,x:()=>m});var i=t(6540);const o={},n=i.createContext(o);function r(e){const s=i.useContext(n);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function m(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(n.Provider,{value:s},e.children)}},8826:e=>{e.exports=JSON.parse('{"permalink":"/feedzback/blog/starting-documentation","editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/blog/2024-03-11-starting-documentation.md","source":"@site/blog/2024-03-11-starting-documentation.md","title":"Starting documentation","description":"This is the summary of a very long blog post,","date":"2024-03-11T00:00:00.000Z","tags":[],"readingTime":2.05,"hasTruncateMarker":true,"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null}],"frontMatter":{"slug":"starting-documentation","title":"Starting documentation","authors":"stephane.francel","tags":[]},"unlisted":false}')}}]); \ No newline at end of file diff --git a/docs/assets/js/7ab81c4a.37fe5a42.js b/docs/assets/js/7ab81c4a.37fe5a42.js new file mode 100644 index 00000000..5ba379da --- /dev/null +++ b/docs/assets/js/7ab81c4a.37fe5a42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2852],{4718:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>d,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"documentation","title":"Documentation","description":"This documentation is powered by the Docusaurus framework.","source":"@site/docs/documentation.md","sourceDirName":".","slug":"/documentation","permalink":"/feedzback/docs/documentation","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/documentation.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Client app","permalink":"/feedzback/docs/update/client"}}');var t=i(4848),c=i(8453);const d={},o="Documentation",r={},l=[{value:"Installation",id:"installation",level:2},{value:"Contribute",id:"contribute",level:2},{value:"Build & deploy",id:"build--deploy",level:2},{value:"Update",id:"update",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"documentation",children:"Documentation"})}),"\n",(0,t.jsxs)(n.p,{children:["This documentation is powered by the ",(0,t.jsx)(n.a,{href:"https://docusaurus.io/",children:"Docusaurus"})," framework."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Open your IDE in ",(0,t.jsx)(n.code,{children:"./docs-source"})," directory and run the following commands:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install\nnpm start\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then visit the URL ",(0,t.jsx)(n.a,{href:"http://localhost:4100/feedzback/",children:"http://localhost:4100/feedzback/"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"contribute",children:"Contribute"}),"\n",(0,t.jsxs)(n.p,{children:["The documentation is written in markdown files located in the ",(0,t.jsx)(n.code,{children:"docs-source/docs"})," directory."]}),"\n",(0,t.jsxs)(n.p,{children:["New files must be referenced in ",(0,t.jsx)(n.code,{children:"docs-source/sidebars.ts"})," file in order to be visible in the final documentation."]}),"\n",(0,t.jsx)(n.h2,{id:"build--deploy",children:"Build & deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The documentation is built in ",(0,t.jsx)(n.code,{children:"docs"})," directory (at the root of the repository) and deployed on GitHub pages."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"To build the doc, run the following command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run build\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The documention is deployed automatically on every commit to the ",(0,t.jsx)(n.code,{children:"main"})," branch.\nFor details, see the ",(0,t.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/settings/pages",children:"GitHub pages settings"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Finally, visit the URL ",(0,t.jsx)(n.a,{href:"https://zenika.github.io/feedzback/",children:"https://zenika.github.io/feedzback/"})," to see the online documentation."]}),"\n",(0,t.jsx)(n.h2,{id:"update",children:"Update"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["You can ",(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/installation#updating-your-docusaurus-version",children:"manually change the version number"})," in ",(0,t.jsx)(n.code,{children:"package.json"})," to the desired version."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["You can also start with a ",(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/installation#scaffold-project-website",children:"clean install"})," of Docusaurus and then restore:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./blog"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./docs"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./src"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./static"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./.prettierignore"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./.prettier.json"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./docusaurus.config.ts"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./sidebars.ts"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./package.json"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["install package: ",(0,t.jsx)(n.code,{children:"remark-deflist"})]}),"\n",(0,t.jsxs)(n.li,{children:["install package: ",(0,t.jsx)(n.code,{children:"@fontsource/nunito"})]}),"\n",(0,t.jsxs)(n.li,{children:["modify build script: ",(0,t.jsx)(n.code,{children:'"build": "docusaurus build --out-dir ../docs"'})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>o});var s=i(6540);const t={},c=s.createContext(t);function d(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/7ab81c4a.3f15462d.js b/docs/assets/js/7ab81c4a.3f15462d.js deleted file mode 100644 index 19908742..00000000 --- a/docs/assets/js/7ab81c4a.3f15462d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[852],{4718:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>d,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"documentation","title":"Documentation","description":"This documentation is powered by the Docusaurus framework.","source":"@site/docs/documentation.md","sourceDirName":".","slug":"/documentation","permalink":"/feedzback/docs/documentation","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/documentation.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Client app","permalink":"/feedzback/docs/update/client"}}');var t=i(4848),c=i(8453);const d={},o="Documentation",r={},l=[{value:"Installation",id:"installation",level:2},{value:"Contribute",id:"contribute",level:2},{value:"Build & deploy",id:"build--deploy",level:2},{value:"Update",id:"update",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"documentation",children:"Documentation"})}),"\n",(0,t.jsxs)(n.p,{children:["This documentation is powered by the ",(0,t.jsx)(n.a,{href:"https://docusaurus.io/",children:"Docusaurus"})," framework."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Open your IDE in ",(0,t.jsx)(n.code,{children:"./docs-source"})," directory and run the following commands:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install\nnpm start\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then visit the URL ",(0,t.jsx)(n.a,{href:"http://localhost:4100/feedzback/",children:"http://localhost:4100/feedzback/"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"contribute",children:"Contribute"}),"\n",(0,t.jsxs)(n.p,{children:["The documentation is written in markdown files located in the ",(0,t.jsx)(n.code,{children:"docs-source/docs"})," directory."]}),"\n",(0,t.jsxs)(n.p,{children:["New files must be referenced in ",(0,t.jsx)(n.code,{children:"docs-source/sidebars.ts"})," file in order to be visible in the final documentation."]}),"\n",(0,t.jsx)(n.h2,{id:"build--deploy",children:"Build & deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The documentation is built in ",(0,t.jsx)(n.code,{children:"docs"})," directory (at the root of the repository) and deployed on GitHub pages."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"To build the doc, run the following command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run build\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The documention is deployed automatically on every commit to the ",(0,t.jsx)(n.code,{children:"main"})," branch.\nFor details, see the ",(0,t.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/settings/pages",children:"GitHub pages settings"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Finally, visit the URL ",(0,t.jsx)(n.a,{href:"https://zenika.github.io/feedzback/",children:"https://zenika.github.io/feedzback/"})," to see the online documentation."]}),"\n",(0,t.jsx)(n.h2,{id:"update",children:"Update"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["You can ",(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/installation#updating-your-docusaurus-version",children:"manually change the version number"})," in ",(0,t.jsx)(n.code,{children:"package.json"})," to the desired version."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["You can also start with a ",(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/installation#scaffold-project-website",children:"clean install"})," of Docusaurus and then restore:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./blog"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./docs"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./src"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./static"})," directory"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./.prettierignore"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./.prettier.json"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./docusaurus.config.ts"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./sidebars.ts"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"./package.json"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["install package: ",(0,t.jsx)(n.code,{children:"remark-deflist"})]}),"\n",(0,t.jsxs)(n.li,{children:["install package: ",(0,t.jsx)(n.code,{children:"@fontsource/nunito"})]}),"\n",(0,t.jsxs)(n.li,{children:["modify build script: ",(0,t.jsx)(n.code,{children:'"build": "docusaurus build --out-dir ../docs"'})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>o});var s=i(6540);const t={},c=s.createContext(t);function d(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/814f3328.cde6d1e9.js b/docs/assets/js/814f3328.cde6d1e9.js deleted file mode 100644 index 98fb7204..00000000 --- a/docs/assets/js/814f3328.cde6d1e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[472],{5513:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Starting documentation","permalink":"/feedzback/blog/starting-documentation","unlisted":false,"date":"2024-03-11T00:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/814f3328.f8bc4c0b.js b/docs/assets/js/814f3328.f8bc4c0b.js new file mode 100644 index 00000000..f075aeaf --- /dev/null +++ b/docs/assets/js/814f3328.f8bc4c0b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[7472],{5513:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"Starting documentation","permalink":"/feedzback/blog/starting-documentation","unlisted":false,"date":"2024-03-11T00:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/8554.964cb29b.js b/docs/assets/js/8554.964cb29b.js new file mode 100644 index 00000000..69945960 --- /dev/null +++ b/docs/assets/js/8554.964cb29b.js @@ -0,0 +1 @@ +(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[8554],{7293:(e,t,n)=>{"use strict";n.d(t,{A:()=>L});var s=n(6540),a=n(4848);function o(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=t.filter((e=>e!==n)),c=n?.props.children;return{mdxAdmonitionTitle:c,rest:o.length>0?(0,a.jsx)(a.Fragment,{children:o}):null}}(e.children),o=e.title??t;return{...e,...o&&{title:o},children:n}}var c=n(4164),i=n(1312),r=n(7559);const l={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:t,className:n,children:s}=e;return(0,a.jsx)("div",{className:(0,c.A)(r.G.common.admonition,r.G.common.admonitionType(t),l.admonition,n),children:s})}function u(e){let{icon:t,title:n}=e;return(0,a.jsxs)("div",{className:l.admonitionHeading,children:[(0,a.jsx)("span",{className:l.admonitionIcon,children:t}),n]})}function m(e){let{children:t}=e;return t?(0,a.jsx)("div",{className:l.admonitionContent,children:t}):null}function h(e){const{type:t,icon:n,title:s,children:o,className:c}=e;return(0,a.jsxs)(d,{type:t,className:c,children:[s||n?(0,a.jsx)(u,{title:s,icon:n}):null,(0,a.jsx)(m,{children:o})]})}function p(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const f={icon:(0,a.jsx)(p,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function g(e){return(0,a.jsx)(h,{...f,...e,className:(0,c.A)("alert alert--secondary",e.className),children:e.children})}function x(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const j={icon:(0,a.jsx)(x,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function b(e){return(0,a.jsx)(h,{...j,...e,className:(0,c.A)("alert alert--success",e.className),children:e.children})}function v(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const N={icon:(0,a.jsx)(v,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function y(e){return(0,a.jsx)(h,{...N,...e,className:(0,c.A)("alert alert--info",e.className),children:e.children})}function A(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const k={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function B(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const C={icon:(0,a.jsx)(B,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const w={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const _={...{note:g,tip:b,info:y,warning:function(e){return(0,a.jsx)(h,{...k,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(h,{...C,...e,className:(0,c.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(g,{title:"secondary",...e}),important:e=>(0,a.jsx)(y,{title:"important",...e}),success:e=>(0,a.jsx)(b,{title:"success",...e}),caution:function(e){return(0,a.jsx)(h,{...w,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})}}};function L(e){const t=o(e),n=(s=t.type,_[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),_.info));var s;return(0,a.jsx)(n,{...t})}},4336:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});n(6540);var s=n(4164),a=n(1312),o=n(7559),c=n(8774);const i={iconEdit:"iconEdit_Z9Sw"};var r=n(4848);function l(e){let{className:t,...n}=e;return(0,r.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,s.A)(i.iconEdit,t),"aria-hidden":"true",...n,children:(0,r.jsx)("g",{children:(0,r.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function d(e){let{editUrl:t}=e;return(0,r.jsxs)(c.A,{to:t,className:o.G.common.editThisPage,children:[(0,r.jsx)(l,{}),(0,r.jsx)(a.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=n(6266);function m(e){let{lastUpdatedAt:t}=e;const n=new Date(t),s=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(n);return(0,r.jsx)(a.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,r.jsx)("b",{children:(0,r.jsx)("time",{dateTime:n.toISOString(),itemProp:"dateModified",children:s})})},children:" on {date}"})}function h(e){let{lastUpdatedBy:t}=e;return(0,r.jsx)(a.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,r.jsx)("b",{children:t})},children:" by {user}"})}function p(e){let{lastUpdatedAt:t,lastUpdatedBy:n}=e;return(0,r.jsxs)("span",{className:o.G.common.lastUpdated,children:[(0,r.jsx)(a.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t?(0,r.jsx)(m,{lastUpdatedAt:t}):"",byUser:n?(0,r.jsx)(h,{lastUpdatedBy:n}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const f={lastUpdated:"lastUpdated_JAkA"};function g(e){let{className:t,editUrl:n,lastUpdatedAt:a,lastUpdatedBy:o}=e;return(0,r.jsxs)("div",{className:(0,s.A)("row",t),children:[(0,r.jsx)("div",{className:"col",children:n&&(0,r.jsx)(d,{editUrl:n})}),(0,r.jsx)("div",{className:(0,s.A)("col",f.lastUpdated),children:(a||o)&&(0,r.jsx)(p,{lastUpdatedAt:a,lastUpdatedBy:o})})]})}},5533:(e,t,n)=>{"use strict";n.d(t,{A:()=>re});var s=n(6540),a=n(8453),o=n(5260),c=n(2303),i=n(4164),r=n(5293),l=n(6342);function d(){const{prism:e}=(0,l.p)(),{colorMode:t}=(0,r.G)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var u=n(7559),m=n(8426),h=n.n(m);const p=/title=(?<quote>["'])(?<title>.*?)\1/,f=/\{(?<range>[\d,-]+)\}/,g={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},x={...g,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},j=Object.keys(g);function b(e,t){const n=e.map((e=>{const{start:n,end:s}=x[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:s,magicComments:a,metastring:o}=t;if(o&&f.test(o)){const e=o.match(f).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,s=h()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(s),code:n}}if(void 0===s)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return b(["tex"],t);case"lua":case"haskell":case"sql":return b(["lua"],t);case"wasm":return b(["wasm"],t);case"vb":case"vba":case"visual-basic":return b(["vb","rem"],t);case"vbnet":return b(["vbnet","rem"],t);case"batch":return b(["rem"],t);case"basic":return b(["rem","f90"],t);case"fsharp":return b(["js","ml"],t);case"ocaml":case"sml":return b(["ml"],t);case"fortran":return b(["f90"],t);case"cobol":return b(["cobol"],t);default:return b(j,t)}}(s,a),i=n.split("\n"),r=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),l=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),d=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let h=0;h<i.length;){const e=i[h].match(c);if(!e){h+=1;continue}const t=e.slice(1).find((e=>void 0!==e));l[t]?r[l[t]].range+=`${h},`:d[t]?r[d[t]].start=h:u[t]&&(r[u[t]].range+=`${r[u[t]].start}-${h-1},`),i.splice(h,1)}n=i.join("\n");const m={};return Object.entries(r).forEach((e=>{let[t,{range:n}]=e;h()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const N={codeBlockContainer:"codeBlockContainer_Ckt0"};var y=n(4848);function A(e){let{as:t,...n}=e;const s=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[s,a]=e;const o=t[s];o&&"string"==typeof a&&(n[o]=a)})),n}(d());return(0,y.jsx)(t,{...n,style:s,className:(0,i.A)(n.className,N.codeBlockContainer,u.G.common.codeBlock)})}const k={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function B(e){let{children:t,className:n}=e;return(0,y.jsx)(A,{as:"pre",tabIndex:0,className:(0,i.A)(k.codeBlockStandalone,"thin-scrollbar",n),children:(0,y.jsx)("code",{className:k.codeBlockLines,children:t})})}var C=n(9532);const w={attributes:!0,characterData:!0,childList:!0,subtree:!0};function _(e,t){const[n,a]=(0,s.useState)(),o=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=w);const a=(0,C._q)(t),o=(0,C.Be)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,o),()=>t.disconnect()}),[e,a,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var L=n(1765);const E={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function T(e){let{line:t,classNames:n,showLineNumbers:s,getLineProps:a,getTokenProps:o}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const c=a({line:t,className:(0,i.A)(n,s&&E.codeLine)}),r=t.map(((e,t)=>(0,y.jsx)("span",{...o({token:e})},t)));return(0,y.jsxs)("span",{...c,children:[s?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)("span",{className:E.codeLineNumber}),(0,y.jsx)("span",{className:E.codeLineContent,children:r})]}):r,(0,y.jsx)("br",{})]})}var S=n(1312);function z(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function U(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const M={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(e){let{code:t,className:n}=e;const[a,o]=(0,s.useState)(!1),c=(0,s.useRef)(void 0),r=(0,s.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const s=document.createElement("textarea"),a=document.activeElement;s.value=e,s.setAttribute("readonly",""),s.style.contain="strict",s.style.position="absolute",s.style.left="-9999px",s.style.fontSize="12pt";const o=document.getSelection(),c=o.rangeCount>0&&o.getRangeAt(0);n.append(s),s.select(),s.selectionStart=0,s.selectionEnd=e.length;let i=!1;try{i=document.execCommand("copy")}catch{}s.remove(),c&&(o.removeAllRanges(),o.addRange(c)),a&&a.focus()}(t),o(!0),c.current=window.setTimeout((()=>{o(!1)}),1e3)}),[t]);return(0,s.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),(0,y.jsx)("button",{type:"button","aria-label":a?(0,S.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,S.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,S.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.A)("clean-btn",n,M.copyButton,a&&M.copyButtonCopied),onClick:r,children:(0,y.jsxs)("span",{className:M.copyButtonIcons,"aria-hidden":"true",children:[(0,y.jsx)(z,{className:M.copyButtonIcon}),(0,y.jsx)(U,{className:M.copyButtonSuccessIcon})]})})}function H(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const R={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function V(e){let{className:t,onClick:n,isEnabled:s}=e;const a=(0,S.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,y.jsx)("button",{type:"button",onClick:n,className:(0,i.A)("clean-btn",t,s&&R.wordWrapButtonEnabled),"aria-label":a,title:a,children:(0,y.jsx)(H,{className:R.wordWrapButtonIcon,"aria-hidden":"true"})})}function W(e){let{children:t,className:n="",metastring:a,title:o,showLineNumbers:c,language:r}=e;const{prism:{defaultLanguage:u,magicComments:m}}=(0,l.p)(),h=function(e){return e?.toLowerCase()}(r??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??u),f=d(),g=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),o=(0,s.useRef)(null),c=(0,s.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),i=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");a(n)}),[o]);return _(o,i),(0,s.useEffect)((()=>{i()}),[e,i]),(0,s.useEffect)((()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)})),[i]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:c}}(),x=function(e){return e?.match(p)?.groups.title??""}(a)||o,{lineClassNames:j,code:b}=v(t,{metastring:a,language:h,magicComments:m}),N=c??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return(0,y.jsxs)(A,{as:"div",className:(0,i.A)(n,h&&!n.includes(`language-${h}`)&&`language-${h}`),children:[x&&(0,y.jsx)("div",{className:k.codeBlockTitle,children:x}),(0,y.jsxs)("div",{className:k.codeBlockContent,children:[(0,y.jsx)(L.f4,{theme:f,code:b,language:h??"text",children:e=>{let{className:t,style:n,tokens:s,getLineProps:a,getTokenProps:o}=e;return(0,y.jsx)("pre",{tabIndex:0,ref:g.codeBlockRef,className:(0,i.A)(t,k.codeBlock,"thin-scrollbar"),style:n,children:(0,y.jsx)("code",{className:(0,i.A)(k.codeBlockLines,N&&k.codeBlockLinesWithNumbering),children:s.map(((e,t)=>(0,y.jsx)(T,{line:e,getLineProps:a,getTokenProps:o,classNames:j[t],showLineNumbers:N},t)))})})}}),(0,y.jsxs)("div",{className:k.buttonGroup,children:[(g.isEnabled||g.isCodeScrollable)&&(0,y.jsx)(V,{className:k.codeButton,onClick:()=>g.toggle(),isEnabled:g.isEnabled}),(0,y.jsx)(I,{className:k.codeButton,code:b})]})]})]})}function $(e){let{children:t,...n}=e;const a=(0,c.A)(),o=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof o?W:B;return(0,y.jsx)(i,{...n,children:o},String(a))}function D(e){return(0,y.jsx)("code",{...e})}var P=n(8774);var G=n(3427),q=n(1422);const O={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function F(e){return!!e&&("SUMMARY"===e.tagName||F(e.parentElement))}function Z(e,t){return!!e&&(e===t||Z(e.parentElement,t))}function J(e){let{summary:t,children:n,...a}=e;(0,G.A)().collectAnchor(a.id);const o=(0,c.A)(),r=(0,s.useRef)(null),{collapsed:l,setCollapsed:d}=(0,q.u)({initialState:!a.open}),[u,m]=(0,s.useState)(a.open),h=s.isValidElement(t)?t:(0,y.jsx)("summary",{children:t??"Details"});return(0,y.jsxs)("details",{...a,ref:r,open:u,"data-collapsed":l,className:(0,i.A)(O.details,o&&O.isBrowser,a.className),onMouseDown:e=>{F(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;F(t)&&Z(t,r.current)&&(e.preventDefault(),l?(d(!1),m(!0)):d(!0))},children:[h,(0,y.jsx)(q.N,{lazy:!1,collapsed:l,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{d(e),m(!e)},children:(0,y.jsx)("div",{className:O.collapsibleContent,children:n})})]})}const Y={details:"details_b_Ee"},K="alert alert--info";function Q(e){let{...t}=e;return(0,y.jsx)(J,{...t,className:(0,i.A)(K,Y.details,t.className)})}function X(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,y.jsx)(y.Fragment,{children:t.filter((e=>e!==n))});return(0,y.jsx)(Q,{...e,summary:n,children:a})}var ee=n(1107);function te(e){return(0,y.jsx)(ee.A,{...e})}const ne={containsTaskList:"containsTaskList_mC6p"};function se(e){if(void 0!==e)return(0,i.A)(e,e?.includes("contains-task-list")&&ne.containsTaskList)}const ae={img:"img_ev3q"};var oe=n(7293),ce=n(418);const ie={Head:o.A,details:X,Details:X,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,y.jsx)(D,{...e}):(0,y.jsx)($,{...e})},a:function(e){return(0,y.jsx)(P.A,{...e})},pre:function(e){return(0,y.jsx)(y.Fragment,{children:e.children})},ul:function(e){return(0,y.jsx)("ul",{...e,className:se(e.className)})},li:function(e){return(0,G.A)().collectAnchor(e.id),(0,y.jsx)("li",{...e})},img:function(e){return(0,y.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,i.A)(t,ae.img))});var t},h1:e=>(0,y.jsx)(te,{as:"h1",...e}),h2:e=>(0,y.jsx)(te,{as:"h2",...e}),h3:e=>(0,y.jsx)(te,{as:"h3",...e}),h4:e=>(0,y.jsx)(te,{as:"h4",...e}),h5:e=>(0,y.jsx)(te,{as:"h5",...e}),h6:e=>(0,y.jsx)(te,{as:"h6",...e}),admonition:oe.A,mermaid:ce.A};function re(e){let{children:t}=e;return(0,y.jsx)(a.x,{components:ie,children:t})}},9022:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var s=n(4164),a=n(8774),o=n(4848);function c(e){const{permalink:t,title:n,subLabel:c,isNext:i}=e;return(0,o.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",i?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[c&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:c}),(0,o.jsx)("div",{className:"pagination-nav__label",children:n})]})}},8046:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(6540);var s=n(4164),a=n(1312),o=n(8774);const c={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var i=n(4848);function r(e){let{permalink:t,label:n,count:a,description:r}=e;return(0,i.jsxs)(o.A,{href:t,title:r,className:(0,s.A)(c.tag,a?c.tagWithCount:c.tagRegular),children:[n,a&&(0,i.jsx)("span",{children:a})]})}const l={tags:"tags_jXut",tag:"tag_QGVx"};function d(e){let{tags:t}=e;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("b",{children:(0,i.jsx)(a.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,i.jsx)("ul",{className:(0,s.A)(l.tags,"padding--none","margin-left--sm"),children:t.map((e=>(0,i.jsx)("li",{className:l.tag,children:(0,i.jsx)(r,{...e})},e.permalink)))})]})}},6266:(e,t,n)=>{"use strict";n.d(t,{i:()=>a});var s=n(4586);function a(e){void 0===e&&(e={});const{i18n:{currentLocale:t}}=(0,s.A)(),n=function(){const{i18n:{currentLocale:e,localeConfigs:t}}=(0,s.A)();return t[e].calendar}();return new Intl.DateTimeFormat(t,{calendar:n,...e})}},8426:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,o]=t;if(s&&o){s=parseInt(s),o=parseInt(o);const e=s<o?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(o+=e);for(let t=s;t!==o;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},8453:(e,t,n)=>{"use strict";n.d(t,{R:()=>c,x:()=>i});var s=n(6540);const a={},o=s.createContext(a);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/94f84f1b.5d84e6c0.js b/docs/assets/js/94f84f1b.5d84e6c0.js deleted file mode 100644 index 12552367..00000000 --- a/docs/assets/js/94f84f1b.5d84e6c0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[441],{4886:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"technical-stack","title":"Technical stack","description":"Client app","source":"@site/docs/technical-stack.md","sourceDirName":".","slug":"/technical-stack","permalink":"/feedzback/docs/technical-stack","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-stack.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Audience","permalink":"/feedzback/docs/audience"},"next":{"title":"Installation","permalink":"/feedzback/docs/installation"}}');var a=n(4848),c=n(8453);const r={},o="Technical stack",i={},l=[{value:"Client app",id:"client-app",level:2},{value:"Server app",id:"server-app",level:2},{value:"NoSQL Database",id:"nosql-database",level:2},{value:"Documentation app",id:"documentation-app",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"technical-stack",children:"Technical stack"})}),"\n",(0,a.jsx)(t.h2,{id:"client-app",children:"Client app"}),"\n",(0,a.jsxs)(t.p,{children:["Powered by ",(0,a.jsx)(t.a,{href:"https://angular.dev",children:"Angular"})," framework."]}),"\n",(0,a.jsx)(t.h2,{id:"server-app",children:"Server app"}),"\n",(0,a.jsxs)(t.p,{children:["Powered by ",(0,a.jsx)(t.a,{href:"https://nestjs.com/",children:"NestJS"})," framework."]}),"\n",(0,a.jsx)(t.h2,{id:"nosql-database",children:"NoSQL Database"}),"\n",(0,a.jsxs)(t.p,{children:["Powered by ",(0,a.jsx)(t.a,{href:"https://firebase.google.com/docs/firestore",children:"Cloud Firestore"})," database."]}),"\n",(0,a.jsxs)(t.p,{children:["Cloud Firestore is one of the Google Firebase services.\nThe app also relies on other Firebase services like ",(0,a.jsx)(t.a,{href:"https://firebase.google.com/docs/auth",children:"Authentication"})," and ",(0,a.jsx)(t.a,{href:"https://firebase.google.com/docs/hosting",children:"Hosting"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"documentation-app",children:"Documentation app"}),"\n",(0,a.jsxs)(t.p,{children:["This documentation is powered by the ",(0,a.jsx)(t.a,{href:"https://docusaurus.io/",children:"Docusaurus"})," framework."]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(6540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/94f84f1b.701c8d3e.js b/docs/assets/js/94f84f1b.701c8d3e.js new file mode 100644 index 00000000..ff16338a --- /dev/null +++ b/docs/assets/js/94f84f1b.701c8d3e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[9441],{4886:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"technical-stack","title":"Technical stack","description":"Client app","source":"@site/docs/technical-stack.md","sourceDirName":".","slug":"/technical-stack","permalink":"/feedzback/docs/technical-stack","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-stack.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Audience","permalink":"/feedzback/docs/audience"},"next":{"title":"Installation","permalink":"/feedzback/docs/installation"}}');var a=n(4848),c=n(8453);const r={},o="Technical stack",i={},l=[{value:"Client app",id:"client-app",level:2},{value:"Server app",id:"server-app",level:2},{value:"NoSQL Database",id:"nosql-database",level:2},{value:"Documentation app",id:"documentation-app",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"technical-stack",children:"Technical stack"})}),"\n",(0,a.jsx)(t.h2,{id:"client-app",children:"Client app"}),"\n",(0,a.jsxs)(t.p,{children:["Powered by ",(0,a.jsx)(t.a,{href:"https://angular.dev",children:"Angular"})," framework."]}),"\n",(0,a.jsx)(t.h2,{id:"server-app",children:"Server app"}),"\n",(0,a.jsxs)(t.p,{children:["Powered by ",(0,a.jsx)(t.a,{href:"https://nestjs.com/",children:"NestJS"})," framework."]}),"\n",(0,a.jsx)(t.h2,{id:"nosql-database",children:"NoSQL Database"}),"\n",(0,a.jsxs)(t.p,{children:["Powered by ",(0,a.jsx)(t.a,{href:"https://firebase.google.com/docs/firestore",children:"Cloud Firestore"})," database."]}),"\n",(0,a.jsxs)(t.p,{children:["Cloud Firestore is one of the Google Firebase services.\nThe app also relies on other Firebase services like ",(0,a.jsx)(t.a,{href:"https://firebase.google.com/docs/auth",children:"Authentication"})," and ",(0,a.jsx)(t.a,{href:"https://firebase.google.com/docs/hosting",children:"Hosting"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"documentation-app",children:"Documentation app"}),"\n",(0,a.jsxs)(t.p,{children:["This documentation is powered by the ",(0,a.jsx)(t.a,{href:"https://docusaurus.io/",children:"Docusaurus"})," framework."]})]})}function h(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(6540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/9e4087bc.bd39f9cc.js b/docs/assets/js/9e4087bc.bd39f9cc.js deleted file mode 100644 index 0d0d90c3..00000000 --- a/docs/assets/js/9e4087bc.bd39f9cc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[711],{9331:(e,r,t)=>{t.r(r),t.d(r,{default:()=>m});t(6540);var a=t(8774),n=t(1312),s=t(1213),i=t(6266),c=t(781),l=t(1107),o=t(4848);function d(e){let{year:r,posts:t}=e;const n=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:r,children:r}),(0,o.jsx)("ul",{children:t.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(a.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,n.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h(e){let{years:r}=e;return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:r.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m(e){let{archive:r}=e;const t=(0,n.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,n.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const r=e.reduce(((e,r)=>{const t=r.metadata.date.split("-")[0],a=e.get(t)??[];return e.set(t,[r,...a])}),new Map);return Array.from(r,(e=>{let[r,t]=e;return{year:r,posts:t}}))}(r.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.be,{title:t,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:t}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:i.length>0&&(0,o.jsx)(h,{years:i})})]})]})}},6266:(e,r,t)=>{t.d(r,{i:()=>n});var a=t(4586);function n(e){void 0===e&&(e={});const{i18n:{currentLocale:r}}=(0,a.A)(),t=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,a.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:t,...e})}}}]); \ No newline at end of file diff --git a/docs/assets/js/9e4087bc.fe99dfe1.js b/docs/assets/js/9e4087bc.fe99dfe1.js new file mode 100644 index 00000000..04ea4d06 --- /dev/null +++ b/docs/assets/js/9e4087bc.fe99dfe1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2711],{9331:(e,r,t)=>{t.r(r),t.d(r,{default:()=>m});t(6540);var a=t(8774),n=t(1312),s=t(1213),i=t(6266),c=t(781),l=t(1107),o=t(4848);function d(e){let{year:r,posts:t}=e;const n=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:r,children:r}),(0,o.jsx)("ul",{children:t.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(a.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,n.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h(e){let{years:r}=e;return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:r.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m(e){let{archive:r}=e;const t=(0,n.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,n.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const r=e.reduce(((e,r)=>{const t=r.metadata.date.split("-")[0],a=e.get(t)??[];return e.set(t,[r,...a])}),new Map);return Array.from(r,(e=>{let[r,t]=e;return{year:r,posts:t}}))}(r.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.be,{title:t,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:t}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:i.length>0&&(0,o.jsx)(h,{years:i})})]})]})}},6266:(e,r,t)=>{t.d(r,{i:()=>n});var a=t(4586);function n(e){void 0===e&&(e={});const{i18n:{currentLocale:r}}=(0,a.A)(),t=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,a.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:t,...e})}}}]); \ No newline at end of file diff --git a/docs/assets/js/9f796194.167dc532.js b/docs/assets/js/9f796194.167dc532.js new file mode 100644 index 00000000..0e5889a1 --- /dev/null +++ b/docs/assets/js/9f796194.167dc532.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[5602],{8726:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"technical-guides/client/firebase-hosting","title":"Firebase Hosting","description":"The client app is deployed on Firebase Hosting which uses 2 configuration files.","source":"@site/docs/technical-guides/client/firebase-hosting.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/firebase-hosting","permalink":"/feedzback/docs/technical-guides/client/firebase-hosting","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/firebase-hosting.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Local dev","permalink":"/feedzback/docs/technical-guides/environments/local-dev"},"next":{"title":"Styles","permalink":"/feedzback/docs/technical-guides/client/styles"}}');var t=s(4848),c=s(8453);const r={},d="Firebase Hosting",l={},o=[{value:"<code>.firebaserc</code>",id:"firebaserc",level:2},{value:"<code>firebase.json</code>",id:"firebasejson",level:2},{value:"404 / Not found page",id:"404--not-found-page",level:2}];function a(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"firebase-hosting",children:"Firebase Hosting"})}),"\n",(0,t.jsx)(n.p,{children:"The client app is deployed on Firebase Hosting which uses 2 configuration files."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:".firebaserc"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"firebase.json"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The deployment is handled by Circle-CI, but let's understand how it actually works."}),"\n",(0,t.jsxs)(n.p,{children:["Assuming the client app has been built with the ",(0,t.jsx)(n.code,{children:"npm run build:dev"})," command (equivalent to the ",(0,t.jsx)(n.code,{children:"ng build"})," command with some options).\nThe built artefact is then available in the ",(0,t.jsx)(n.code,{children:"dist/client/browser"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"firebaserc",children:(0,t.jsx)(n.code,{children:".firebaserc"})}),"\n",(0,t.jsx)(n.p,{children:"This file describes the deploy targets."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "projects": {\n "dev": "feedzback-v2-dev"\n },\n "targets": {\n "feedzback-v2-dev": {\n "hosting": {\n "dev": ["feedzback-v2-dev"]\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Here, the short-name identifier ",(0,t.jsx)(n.code,{children:"dev"})," is associated to the ",(0,t.jsx)(n.em,{children:"Firebase project"})," named ",(0,t.jsx)(n.code,{children:"feedzback-v2-dev"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"firebasejson",children:(0,t.jsx)(n.code,{children:"firebase.json"})}),"\n",(0,t.jsxs)(n.p,{children:["This file describes the local location and runtime behavior of the ",(0,t.jsx)(n.em,{children:"Firebase Hosting resource"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hosting": [\n {\n "target": "dev",\n "public": "dist/client/browser",\n "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],\n "rewrites": [\n {\n "source": "/fr/**",\n "destination": "/fr/index.html"\n },\n {\n "source": "/en/**",\n "destination": "/en/index.html"\n }\n ]\n }\n ]\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Here, the same short-name identifier ",(0,t.jsx)(n.code,{children:"dev"})," is used as deploy target (see above)."]}),"\n",(0,t.jsx)(n.p,{children:"The configuration specifies that:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["the built artefact (",(0,t.jsx)(n.code,{children:"dist/client/browser"}),") needs to be deployed as Hosting resource, on the targeted Firebase project"]}),"\n",(0,t.jsx)(n.li,{children:"and because we are dealing with a Single-Page-Application (SPA), the Hosting resource needs to support URL rewriting"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"404--not-found-page",children:"404 / Not found page"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"404.html"})," file is served by Firebase Hosting when a user tries to access a page that doesn't exist.\nSo, this file needs to be added in the built artefact."]}),"\n",(0,t.jsxs)(n.p,{children:["This task is done be the ",(0,t.jsx)(n.code,{children:"post-build"})," NPM script:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "build:dev": "ng build -c development-remote && npm run post-build",\n "post-build": "cp src/404.html dist/client/browser/404.html"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The HTML page ",(0,t.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/404.html",children:(0,t.jsx)(n.code,{children:"src/404.html"})}),' simply redirects the user to "localized" page (',(0,t.jsx)(n.code,{children:"/fr"})," or ",(0,t.jsx)(n.code,{children:"/en"}),")."]}),"\n",(0,t.jsx)(n.p,{children:"For example :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["when trying to access the page:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"https://dev.feedzback.znk.io/request"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["the user will be redirected to one of these pages (depending on its current language settings):","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"https://dev.feedzback.znk.io/en/request"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"https://dev.feedzback.znk.io/fr/request"})}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(6540);const t={},c=i.createContext(t);function r(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/9f796194.5e47e116.js b/docs/assets/js/9f796194.5e47e116.js deleted file mode 100644 index a4db32fc..00000000 --- a/docs/assets/js/9f796194.5e47e116.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[602],{8726:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"technical-guides/client/firebase-hosting","title":"Firebase Hosting","description":"The client app is deployed on Firebase Hosting which uses 2 configuration files.","source":"@site/docs/technical-guides/client/firebase-hosting.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/firebase-hosting","permalink":"/feedzback/docs/technical-guides/client/firebase-hosting","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/firebase-hosting.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Local","permalink":"/feedzback/docs/technical-guides/environments/local"},"next":{"title":"Styles","permalink":"/feedzback/docs/technical-guides/client/styles"}}');var t=s(4848),c=s(8453);const r={},d="Firebase Hosting",l={},o=[{value:"<code>.firebaserc</code>",id:"firebaserc",level:2},{value:"<code>firebase.json</code>",id:"firebasejson",level:2},{value:"404 / Not found page",id:"404--not-found-page",level:2}];function a(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"firebase-hosting",children:"Firebase Hosting"})}),"\n",(0,t.jsx)(n.p,{children:"The client app is deployed on Firebase Hosting which uses 2 configuration files."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:".firebaserc"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"firebase.json"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The deployment is handled by Circle-CI, but let's understand how it actually works."}),"\n",(0,t.jsxs)(n.p,{children:["Assuming the client app has been built with the ",(0,t.jsx)(n.code,{children:"npm run build:dev"})," command (equivalent to the ",(0,t.jsx)(n.code,{children:"ng build"})," command with some options).\nThe built artefact is then available in the ",(0,t.jsx)(n.code,{children:"dist/client/browser"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"firebaserc",children:(0,t.jsx)(n.code,{children:".firebaserc"})}),"\n",(0,t.jsx)(n.p,{children:"This file describes the deploy targets."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "projects": {\n "dev": "feedzback-v2-dev"\n },\n "targets": {\n "feedzback-v2-dev": {\n "hosting": {\n "dev": ["feedzback-v2-dev"]\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Here, the short-name identifier ",(0,t.jsx)(n.code,{children:"dev"})," is associated to the ",(0,t.jsx)(n.em,{children:"Firebase project"})," named ",(0,t.jsx)(n.code,{children:"feedzback-v2-dev"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"firebasejson",children:(0,t.jsx)(n.code,{children:"firebase.json"})}),"\n",(0,t.jsxs)(n.p,{children:["This file describes the local location and runtime behavior of the ",(0,t.jsx)(n.em,{children:"Firebase Hosting resource"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hosting": [\n {\n "target": "dev",\n "public": "dist/client/browser",\n "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],\n "rewrites": [\n {\n "source": "/fr/**",\n "destination": "/fr/index.html"\n },\n {\n "source": "/en/**",\n "destination": "/en/index.html"\n }\n ]\n }\n ]\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Here, the same short-name identifier ",(0,t.jsx)(n.code,{children:"dev"})," is used as deploy target (see above)."]}),"\n",(0,t.jsx)(n.p,{children:"The configuration specifies that:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["the built artefact (",(0,t.jsx)(n.code,{children:"dist/client/browser"}),") needs to be deployed as Hosting resource, on the targeted Firebase project"]}),"\n",(0,t.jsx)(n.li,{children:"and because we are dealing with a Single-Page-Application (SPA), the Hosting resource needs to support URL rewriting"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"404--not-found-page",children:"404 / Not found page"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"404.html"})," file is served by Firebase Hosting when a user tries to access a page that doesn't exist.\nSo, this file needs to be added in the built artefact."]}),"\n",(0,t.jsxs)(n.p,{children:["This task is done be the ",(0,t.jsx)(n.code,{children:"post-build"})," NPM script:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "build:dev": "ng build -c development-remote && npm run post-build",\n "post-build": "cp src/404.html dist/client/browser/404.html"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The HTML page ",(0,t.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/404.html",children:(0,t.jsx)(n.code,{children:"src/404.html"})}),' simply redirects the user to "localized" page (',(0,t.jsx)(n.code,{children:"/fr"})," or ",(0,t.jsx)(n.code,{children:"/en"}),")."]}),"\n",(0,t.jsx)(n.p,{children:"For example :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["when trying to access the page:","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"https://dev.feedzback.znk.io/request"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["the user will be redirected to one of these pages (depending on its current language settings):","\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"https://dev.feedzback.znk.io/en/request"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"https://dev.feedzback.znk.io/fr/request"})}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(6540);const t={},c=i.createContext(t);function r(e){const n=i.useContext(c);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/a55ba532.123c641d.js b/docs/assets/js/a55ba532.123c641d.js new file mode 100644 index 00000000..0df6065d --- /dev/null +++ b/docs/assets/js/a55ba532.123c641d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[6097],{1498:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/feedzback/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/a55ba532.fc22b8fe.js b/docs/assets/js/a55ba532.fc22b8fe.js deleted file mode 100644 index 63e1efc6..00000000 --- a/docs/assets/js/a55ba532.fc22b8fe.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[97],{1498:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/feedzback/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/a6aa9e1f.5360020e.js b/docs/assets/js/a6aa9e1f.5360020e.js new file mode 100644 index 00000000..6c6d5070 --- /dev/null +++ b/docs/assets/js/a6aa9e1f.5360020e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[7643],{2052:(e,t,n)=>{n.r(t),n.d(t,{default:()=>A});n(6540);var r=n(4164),a=n(4586),s=n(1213),l=n(7559),o=n(8027),i=n(1312),c=n(9022),d=n(4848);function u(e){const{metadata:t}=e,{previousPage:n,nextPage:r}=t;return(0,d.jsxs)("nav",{className:"pagination-nav","aria-label":(0,i.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[n&&(0,d.jsx)(c.A,{permalink:n,title:(0,d.jsx)(i.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),r&&(0,d.jsx)(c.A,{permalink:r,title:(0,d.jsx)(i.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}var m=n(1463),g=n(4096),h=n(5856);function p(e){let{items:t,component:n=h.A}=e;return(0,d.jsx)(d.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,d.jsx)(g.in,{content:t,children:(0,d.jsx)(n,{children:(0,d.jsx)(t,{})})},t.metadata.permalink)}))})}var x=n(5260);function j(e){const t=(0,g.kJ)(e);return(0,d.jsx)(x.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function f(e){const{metadata:t}=e,{siteConfig:{title:n}}=(0,a.A)(),{blogDescription:r,blogTitle:l,permalink:o}=t,i="/"===o?n:l;return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(s.be,{title:i,description:r}),(0,d.jsx)(m.A,{tag:"blog_posts_list"})]})}function b(e){const{metadata:t,items:n,sidebar:r}=e;return(0,d.jsxs)(o.A,{sidebar:r,children:[(0,d.jsx)(p,{items:n}),(0,d.jsx)(u,{metadata:t})]})}function A(e){return(0,d.jsxs)(s.e3,{className:(0,r.A)(l.G.wrapper.blogPages,l.G.page.blogListPage),children:[(0,d.jsx)(f,{...e}),(0,d.jsx)(j,{...e}),(0,d.jsx)(b,{...e})]})}},5856:(e,t,n)=>{n.d(t,{A:()=>$});var r=n(6540),a=n(4164),s=n(4096),l=n(4848);function o(e){let{children:t,className:n}=e;return(0,l.jsx)("article",{className:n,children:t})}var i=n(8774);const c={title:"title_f1Hy"};function d(e){let{className:t}=e;const{metadata:n,isBlogPostPage:r}=(0,s.e7)(),{permalink:o,title:d}=n,u=r?"h1":"h2";return(0,l.jsx)(u,{className:(0,a.A)(c.title,t),children:r?d:(0,l.jsx)(i.A,{to:o,children:d})})}var u=n(1312),m=n(4586);const g=["zero","one","two","few","many","other"];function h(e){return g.filter((t=>e.includes(t)))}const p={locale:"en",pluralForms:h(["one","other"]),select:e=>1===e?"one":"other"};function x(){const{i18n:{currentLocale:e}}=(0,m.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:h(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),p}}),[e])}function j(){const e=x();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const a=n.select(t),s=n.pluralForms.indexOf(a);return r[Math.min(s,r.length-1)]}(n,t,e)}}var f=n(6266);const b={container:"container_mt6G"};function A(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=j();return t=>{const n=Math.ceil(t);return e(n,(0,u.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,l.jsx)(l.Fragment,{children:n(t)})}function v(e){let{date:t,formattedDate:n}=e;return(0,l.jsx)("time",{dateTime:t,children:n})}function N(){return(0,l.jsx)(l.Fragment,{children:" \xb7 "})}function w(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:r,readingTime:o}=n,i=(0,f.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,l.jsxs)("div",{className:(0,a.A)(b.container,"margin-vert--md",t),children:[(0,l.jsx)(v,{date:r,formattedDate:(c=r,i.format(new Date(c)))}),void 0!==o&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(N,{}),(0,l.jsx)(A,{readingTime:o})]})]});var c}var T=n(6913);const k={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function y(e){let{className:t}=e;const{metadata:{authors:n},assets:r}=(0,s.e7)();if(0===n.length)return null;const o=n.every((e=>{let{name:t}=e;return!t})),i=1===n.length;return(0,l.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",o?k.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,l.jsx)("div",{className:(0,a.A)(!o&&(i?"col col--12":"col col--6"),o?k.imageOnlyAuthorCol:k.authorCol),children:(0,l.jsx)(T.A,{author:{...e,imageURL:r.authorsImageUrls[t]??e.imageURL}})},t)))})}function P(){return(0,l.jsxs)("header",{children:[(0,l.jsx)(d,{}),(0,l.jsx)(w,{}),(0,l.jsx)(y,{})]})}var F=n(440),R=n(5533);function O(e){let{children:t,className:n}=e;const{isBlogPostPage:r}=(0,s.e7)();return(0,l.jsx)("div",{id:r?F.LU:void 0,className:(0,a.A)("markdown",n),children:(0,l.jsx)(R.A,{children:t})})}var U=n(7559),_=n(4336),C=n(8046);function M(){return(0,l.jsx)("b",{children:(0,l.jsx)(u.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function B(e){const{blogPostTitle:t,...n}=e;return(0,l.jsx)(i.A,{"aria-label":(0,u.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,l.jsx)(M,{})})}function L(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:r,editUrl:o,hasTruncateMarker:i,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&i,m=n.length>0;if(!(m||u||o))return null;if(t){const e=!!(o||d||c);return(0,l.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,a.A)("row","margin-top--sm",U.G.blog.blogFooterEditMetaRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(C.A,{tags:n})})}),e&&(0,l.jsx)(_.A,{className:(0,a.A)("margin-top--sm",U.G.blog.blogFooterEditMetaRow),editUrl:o,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,l.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,a.A)("col",{"col--9":u}),children:(0,l.jsx)(C.A,{tags:n})}),u&&(0,l.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":m}),children:(0,l.jsx)(B,{blogPostTitle:r,to:e.permalink})})]})}function $(e){let{children:t,className:n}=e;const r=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,l.jsxs)(o,{className:(0,a.A)(r,n),children:[(0,l.jsx)(P,{}),(0,l.jsx)(O,{children:t}),(0,l.jsx)(L,{})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a6aa9e1f.d577f68a.js b/docs/assets/js/a6aa9e1f.d577f68a.js deleted file mode 100644 index 0fa41a36..00000000 --- a/docs/assets/js/a6aa9e1f.d577f68a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[643],{2052:(e,t,n)=>{n.r(t),n.d(t,{default:()=>A});n(6540);var r=n(4164),a=n(4586),s=n(1213),l=n(7559),o=n(8027),i=n(1312),c=n(9022),d=n(4848);function u(e){const{metadata:t}=e,{previousPage:n,nextPage:r}=t;return(0,d.jsxs)("nav",{className:"pagination-nav","aria-label":(0,i.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[n&&(0,d.jsx)(c.A,{permalink:n,title:(0,d.jsx)(i.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),r&&(0,d.jsx)(c.A,{permalink:r,title:(0,d.jsx)(i.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}var m=n(1463),g=n(4096),h=n(5856);function p(e){let{items:t,component:n=h.A}=e;return(0,d.jsx)(d.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,d.jsx)(g.in,{content:t,children:(0,d.jsx)(n,{children:(0,d.jsx)(t,{})})},t.metadata.permalink)}))})}var x=n(5260);function j(e){const t=(0,g.kJ)(e);return(0,d.jsx)(x.A,{children:(0,d.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function f(e){const{metadata:t}=e,{siteConfig:{title:n}}=(0,a.A)(),{blogDescription:r,blogTitle:l,permalink:o}=t,i="/"===o?n:l;return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(s.be,{title:i,description:r}),(0,d.jsx)(m.A,{tag:"blog_posts_list"})]})}function b(e){const{metadata:t,items:n,sidebar:r}=e;return(0,d.jsxs)(o.A,{sidebar:r,children:[(0,d.jsx)(p,{items:n}),(0,d.jsx)(u,{metadata:t})]})}function A(e){return(0,d.jsxs)(s.e3,{className:(0,r.A)(l.G.wrapper.blogPages,l.G.page.blogListPage),children:[(0,d.jsx)(f,{...e}),(0,d.jsx)(j,{...e}),(0,d.jsx)(b,{...e})]})}},5856:(e,t,n)=>{n.d(t,{A:()=>$});var r=n(6540),a=n(4164),s=n(4096),l=n(4848);function o(e){let{children:t,className:n}=e;return(0,l.jsx)("article",{className:n,children:t})}var i=n(8774);const c={title:"title_f1Hy"};function d(e){let{className:t}=e;const{metadata:n,isBlogPostPage:r}=(0,s.e7)(),{permalink:o,title:d}=n,u=r?"h1":"h2";return(0,l.jsx)(u,{className:(0,a.A)(c.title,t),children:r?d:(0,l.jsx)(i.A,{to:o,children:d})})}var u=n(1312),m=n(4586);const g=["zero","one","two","few","many","other"];function h(e){return g.filter((t=>e.includes(t)))}const p={locale:"en",pluralForms:h(["one","other"]),select:e=>1===e?"one":"other"};function x(){const{i18n:{currentLocale:e}}=(0,m.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:h(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),p}}),[e])}function j(){const e=x();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const a=n.select(t),s=n.pluralForms.indexOf(a);return r[Math.min(s,r.length-1)]}(n,t,e)}}var f=n(6266);const b={container:"container_mt6G"};function A(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=j();return t=>{const n=Math.ceil(t);return e(n,(0,u.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,l.jsx)(l.Fragment,{children:n(t)})}function v(e){let{date:t,formattedDate:n}=e;return(0,l.jsx)("time",{dateTime:t,children:n})}function N(){return(0,l.jsx)(l.Fragment,{children:" \xb7 "})}function w(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:r,readingTime:o}=n,i=(0,f.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,l.jsxs)("div",{className:(0,a.A)(b.container,"margin-vert--md",t),children:[(0,l.jsx)(v,{date:r,formattedDate:(c=r,i.format(new Date(c)))}),void 0!==o&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(N,{}),(0,l.jsx)(A,{readingTime:o})]})]});var c}var T=n(6913);const k={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function y(e){let{className:t}=e;const{metadata:{authors:n},assets:r}=(0,s.e7)();if(0===n.length)return null;const o=n.every((e=>{let{name:t}=e;return!t})),i=1===n.length;return(0,l.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",o?k.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,l.jsx)("div",{className:(0,a.A)(!o&&(i?"col col--12":"col col--6"),o?k.imageOnlyAuthorCol:k.authorCol),children:(0,l.jsx)(T.A,{author:{...e,imageURL:r.authorsImageUrls[t]??e.imageURL}})},t)))})}function P(){return(0,l.jsxs)("header",{children:[(0,l.jsx)(d,{}),(0,l.jsx)(w,{}),(0,l.jsx)(y,{})]})}var F=n(440),R=n(5533);function O(e){let{children:t,className:n}=e;const{isBlogPostPage:r}=(0,s.e7)();return(0,l.jsx)("div",{id:r?F.LU:void 0,className:(0,a.A)("markdown",n),children:(0,l.jsx)(R.A,{children:t})})}var U=n(7559),_=n(4336),C=n(8046);function M(){return(0,l.jsx)("b",{children:(0,l.jsx)(u.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function B(e){const{blogPostTitle:t,...n}=e;return(0,l.jsx)(i.A,{"aria-label":(0,u.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,l.jsx)(M,{})})}function L(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:r,editUrl:o,hasTruncateMarker:i,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&i,m=n.length>0;if(!(m||u||o))return null;if(t){const e=!!(o||d||c);return(0,l.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,a.A)("row","margin-top--sm",U.G.blog.blogFooterEditMetaRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(C.A,{tags:n})})}),e&&(0,l.jsx)(_.A,{className:(0,a.A)("margin-top--sm",U.G.blog.blogFooterEditMetaRow),editUrl:o,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,l.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,a.A)("col",{"col--9":u}),children:(0,l.jsx)(C.A,{tags:n})}),u&&(0,l.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":m}),children:(0,l.jsx)(B,{blogPostTitle:r,to:e.permalink})})]})}function $(e){let{children:t,className:n}=e;const r=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,l.jsxs)(o,{className:(0,a.A)(r,n),children:[(0,l.jsx)(P,{}),(0,l.jsx)(O,{children:t}),(0,l.jsx)(L,{})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a7456010.82a19219.js b/docs/assets/js/a7456010.82a19219.js deleted file mode 100644 index 9a4cc9b3..00000000 --- a/docs/assets/js/a7456010.82a19219.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[235],{8552:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/a7456010.9c88af94.js b/docs/assets/js/a7456010.9c88af94.js new file mode 100644 index 00000000..75d92745 --- /dev/null +++ b/docs/assets/js/a7456010.9c88af94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[1235],{8552:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-pages","id":"default"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/a7bd4aaa.35527830.js b/docs/assets/js/a7bd4aaa.35527830.js deleted file mode 100644 index c4be7651..00000000 --- a/docs/assets/js/a7bd4aaa.35527830.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[98],{1723:(n,e,s)=>{s.r(e),s.d(e,{default:()=>l});s(6540);var r=s(1213);function o(n,e){return`docs-${n}-${e}`}var c=s(3025),t=s(2831),i=s(1463),a=s(4848);function u(n){const{version:e}=n;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.A,{version:e.version,tag:o(e.pluginId,e.version)}),(0,a.jsx)(r.be,{children:e.noIndex&&(0,a.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function d(n){const{version:e,route:s}=n;return(0,a.jsx)(r.e3,{className:e.className,children:(0,a.jsx)(c.n,{version:e,children:(0,t.v)(s.routes)})})}function l(n){return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(u,{...n}),(0,a.jsx)(d,{...n})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a7bd4aaa.59f97c80.js b/docs/assets/js/a7bd4aaa.59f97c80.js new file mode 100644 index 00000000..2262902f --- /dev/null +++ b/docs/assets/js/a7bd4aaa.59f97c80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[7098],{1723:(n,e,s)=>{s.r(e),s.d(e,{default:()=>l});s(6540);var r=s(1213);function o(n,e){return`docs-${n}-${e}`}var c=s(3025),t=s(2831),i=s(1463),a=s(4848);function u(n){const{version:e}=n;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.A,{version:e.version,tag:o(e.pluginId,e.version)}),(0,a.jsx)(r.be,{children:e.noIndex&&(0,a.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function d(n){const{version:e,route:s}=n;return(0,a.jsx)(r.e3,{className:e.className,children:(0,a.jsx)(c.n,{version:e,children:(0,t.v)(s.routes)})})}function l(n){return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(u,{...n}),(0,a.jsx)(d,{...n})]})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a94703ab.99db49cf.js b/docs/assets/js/a94703ab.99db49cf.js deleted file mode 100644 index dd515db6..00000000 --- a/docs/assets/js/a94703ab.99db49cf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[48],{1377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(6540),o=n(4164),i=n(1213),s=n(7559),l=n(6972),r=n(609),c=n(1312),d=n(3104),u=n(5062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(4848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(3109),x=n(6347),f=n(4581),j=n(6342),v=n(3465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(5041),C=n(9532);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(1422),B=n(9169),y=n(8774),w=n(2303);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&f&&k(!0)}),[h,N,c,k,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(6654),H=n(3186);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function z(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const Y="sidebar_njMd",K="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(Y,s&&K,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(z,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(5600),Z=n(9876);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(3363);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},3363:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var a=n(4164),o=n(1312),i=n(1107),s=n(4848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/a94703ab.b9bef984.js b/docs/assets/js/a94703ab.b9bef984.js new file mode 100644 index 00000000..6a847ef5 --- /dev/null +++ b/docs/assets/js/a94703ab.b9bef984.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[9048],{1377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(6540),o=n(4164),i=n(1213),s=n(7559),l=n(6972),r=n(609),c=n(1312),d=n(3104),u=n(5062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(4848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(3109),x=n(6347),f=n(4581),j=n(6342),v=n(3465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(5041),C=n(9532);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(1422),B=n(9169),y=n(8774),w=n(2303);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&f&&k(!0)}),[h,N,c,k,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(6654),H=n(3186);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function z(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const Y="sidebar_njMd",K="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(Y,s&&K,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(z,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(5600),Z=n(9876);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(3363);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},3363:(e,t,n)=>{n.d(t,{A:()=>l});n(6540);var a=n(4164),o=n(1312),i=n(1107),s=n(4848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/aba21aa0.02885303.js b/docs/assets/js/aba21aa0.02885303.js deleted file mode 100644 index 9239dc43..00000000 --- a/docs/assets/js/aba21aa0.02885303.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[742],{7093:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/aba21aa0.7552c333.js b/docs/assets/js/aba21aa0.7552c333.js new file mode 100644 index 00000000..0466f6ab --- /dev/null +++ b/docs/assets/js/aba21aa0.7552c333.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[5742],{7093:e=>{e.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/acecf23e.1c159d27.js b/docs/assets/js/acecf23e.1c159d27.js deleted file mode 100644 index 9a274996..00000000 --- a/docs/assets/js/acecf23e.1c159d27.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[903],{1912:e=>{e.exports=JSON.parse('{"blogBasePath":"/feedzback/blog","blogTitle":"Blog","authorsListPath":"/feedzback/blog/authors"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/acecf23e.34446eb8.js b/docs/assets/js/acecf23e.34446eb8.js new file mode 100644 index 00000000..650b85a7 --- /dev/null +++ b/docs/assets/js/acecf23e.34446eb8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[1903],{1912:e=>{e.exports=JSON.parse('{"blogBasePath":"/feedzback/blog","blogTitle":"Blog","authorsListPath":"/feedzback/blog/authors"}')}}]); \ No newline at end of file diff --git a/docs/assets/js/b92ecb7a.0516f577.js b/docs/assets/js/b92ecb7a.aa025ba5.js similarity index 99% rename from docs/assets/js/b92ecb7a.0516f577.js rename to docs/assets/js/b92ecb7a.aa025ba5.js index 2ed6e776..9d897eee 100644 --- a/docs/assets/js/b92ecb7a.0516f577.js +++ b/docs/assets/js/b92ecb7a.aa025ba5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[516],{1622:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"update/client","title":"Client app","description":"You can update the Angular framework dependencies by following the instructions provided by Angular.","source":"@site/docs/update/client.md","sourceDirName":"update","slug":"/update/client","permalink":"/feedzback/docs/update/client","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/update/client.md","tags":[],"version":"current","frontMatter":{"title":"Client app"},"sidebar":"default","previous":{"title":"Usage analytics","permalink":"/feedzback/docs/usage-analytics"},"next":{"title":"Documentation","permalink":"/feedzback/docs/documentation"}}');var t=s(4848),a=s(8453);const r={title:"Client app"},l="Update client app",d={},c=[{value:"Create Angular app",id:"create-angular-app",level:2},{value:"Generate environments",id:"generate-environments",level:2},{value:"Add Localize",id:"add-localize",level:2},{value:"Add Material",id:"add-material",level:2},{value:"Add Tailwind",id:"add-tailwind",level:2},{value:"Add ESLint and Prettier",id:"add-eslint-and-prettier",level:2},{value:"Using Jest instead of Karma/Jasmine",id:"using-jest-instead-of-karmajasmine",level:2},{value:"Add other packages",id:"add-other-packages",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"update-client-app",children:"Update client app"})}),"\n",(0,t.jsxs)(n.p,{children:["You can update the Angular framework dependencies by following the ",(0,t.jsx)(n.a,{href:"https://angular.dev/update",children:"instructions provided by Angular"}),".\nOther dependencies can be updated manually."]}),"\n",(0,t.jsx)(n.p,{children:"But to make it short, just run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng update @angular/core @angular/cli @angular/localize @angular/material\n"})}),"\n",(0,t.jsx)(n.p,{children:"The rest of the document describes how to recreate all the dependencies from scratch.\nThis is very useful for understanding the links between dependencies."}),"\n",(0,t.jsx)(n.h2,{id:"create-angular-app",children:"Create Angular app"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install -g @angular/cli\n\nng new client --style scss --view-encapsulation None --ssr false\n"})}),"\n",(0,t.jsx)(n.h2,{id:"generate-environments",children:"Generate environments"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng generate environments\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-localize",children:"Add Localize"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng add @angular/localize\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-material",children:"Add Material"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng add @angular/material --theme custom --animations --typography\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Move generated content (related to Material) from ",(0,t.jsx)(n.code,{children:"src/styles.scss"})," to ",(0,t.jsx)(n.code,{children:"src/styles/material.scss"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"src/styles.scss"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scss",children:"@import './styles/material.scss';\n\nhtml,\nbody {\n height: 100%;\n}\nbody {\n margin: 0;\n font-family: Nunito, sans-serif;\n}\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Nunito"})," font dependency is listed in ",(0,t.jsx)(n.a,{href:"#add-other-packages",children:"other packages"})," below."]})}),"\n",(0,t.jsx)(n.h2,{id:"add-tailwind",children:"Add Tailwind"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install -D tailwindcss postcss autoprefixer\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"tailwind.config.ts"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import type { Config } from 'tailwindcss';\n\nexport default {\n content: ['./src/**/*.{html,ts}'],\n\n corePlugins: {\n // Warning: Tailwind \"Preflight\" breaks some Angular material components\n //\n // Learn more about this issue and a hack to solve it:\n // https://github.com/tailwindlabs/tailwindcss/discussions/9993\n //\n // The hack is available here: `src/styles/tailwind.css`\n preflight: false,\n },\n\n theme: {\n extend: {},\n },\n\n plugins: [],\n} satisfies Config;\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"src/styles/tailwind.css"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-css",children:"@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"src/styles.scss"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scss",children:"@import './styles/tailwind.css';\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-eslint-and-prettier",children:"Add ESLint and Prettier"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng add @angular-eslint/schematics\n\nnpm i -D prettier eslint-config-prettier eslint-plugin-prettier prettier-plugin-organize-imports prettier-plugin-tailwindcss\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"eslint.config.js"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');\n\nmodule.exports = tseslint.config(\n {\n rules: {\n // Note: the following rule is an addon (by default, type definitions use `interface`, but we prefer to use `type`)\n '@typescript-eslint/consistent-type-definitions': ['error', 'type'],\n },\n },\n eslintPluginPrettierRecommended\n);\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Only the lines added are reported here."})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:".prettierrc.json"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "printWidth": 120,\n "singleQuote": true,\n "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"],\n "overrides": [\n {\n "files": "*.html",\n "options": {\n "parser": "angular"\n }\n }\n ]\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:".prettierignore"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-txt",children:"/.angular\n/coverage\n/dist\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"package.json"})," scripts:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "format": "prettier --write .",\n "format:check": "prettier --check ."\n }\n}\n'})}),"\n",(0,t.jsx)(n.h2,{id:"using-jest-instead-of-karmajasmine",children:"Using Jest instead of Karma/Jasmine"}),"\n",(0,t.jsx)(n.p,{children:"First, remove all packages related to Karma and Jasmine. Next, install Jest related packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm i -D jest @types/jest @angular-builders/jest ts-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"tsconfig.spec.json"})," and ",(0,t.jsx)(n.code,{children:"tsconfig.json"})," files:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "compilerOptions": {\n "types": ["jest"]\n }\n}\n'})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["You need to make this change even for the ",(0,t.jsx)(n.code,{children:"tsconfig.json"})," file, as it is used by the IDE."]})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"angular.json"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "projects": {\n "client": {\n "architect": {\n "test": {\n "builder": "@angular-builders/jest:run",\n "options": {\n "configPath": "jest.config.ts"\n }\n }\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"jest.config.ts"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import type { Config } from 'jest';\n\nexport default {\n passWithNoTests: true,\n setupFiles: ['./setup-jest.ts'],\n} satisfies Config;\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"setup-jest.ts"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import '@angular/localize/init';\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-other-packages",children:"Add other packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm i @fontsource/nunito canvas-confetti firebase js-cookie @material-symbols/font-600\n\nnpm i -D @types/canvas-confetti @types/js-cookie\n"})})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var i=s(6540);const t={},a=i.createContext(t);function r(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[516],{1622:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"update/client","title":"Client app","description":"You can update the Angular framework dependencies by following the instructions provided by Angular.","source":"@site/docs/update/client.md","sourceDirName":"update","slug":"/update/client","permalink":"/feedzback/docs/update/client","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/update/client.md","tags":[],"version":"current","frontMatter":{"title":"Client app"},"sidebar":"default","previous":{"title":"Usage analytics","permalink":"/feedzback/docs/usage-analytics"},"next":{"title":"Documentation","permalink":"/feedzback/docs/documentation"}}');var t=s(4848),a=s(8453);const r={title:"Client app"},l="Update client app",d={},c=[{value:"Create Angular app",id:"create-angular-app",level:2},{value:"Generate environments",id:"generate-environments",level:2},{value:"Add Localize",id:"add-localize",level:2},{value:"Add Material",id:"add-material",level:2},{value:"Add Tailwind",id:"add-tailwind",level:2},{value:"Add ESLint and Prettier",id:"add-eslint-and-prettier",level:2},{value:"Using Jest instead of Karma/Jasmine",id:"using-jest-instead-of-karmajasmine",level:2},{value:"Add other packages",id:"add-other-packages",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"update-client-app",children:"Update client app"})}),"\n",(0,t.jsxs)(n.p,{children:["You can update the Angular framework dependencies by following the ",(0,t.jsx)(n.a,{href:"https://angular.dev/update",children:"instructions provided by Angular"}),".\nOther dependencies can be updated manually."]}),"\n",(0,t.jsx)(n.p,{children:"But to make it short, just run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng update @angular/core @angular/cli @angular/localize @angular/material\n"})}),"\n",(0,t.jsx)(n.p,{children:"The rest of the document describes how to recreate all the dependencies from scratch.\nThis is very useful for understanding the links between dependencies."}),"\n",(0,t.jsx)(n.h2,{id:"create-angular-app",children:"Create Angular app"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install -g @angular/cli\n\nng new client --style scss --view-encapsulation None --ssr false\n"})}),"\n",(0,t.jsx)(n.h2,{id:"generate-environments",children:"Generate environments"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng generate environments\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-localize",children:"Add Localize"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng add @angular/localize\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-material",children:"Add Material"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng add @angular/material --theme custom --animations --typography\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Move generated content (related to Material) from ",(0,t.jsx)(n.code,{children:"src/styles.scss"})," to ",(0,t.jsx)(n.code,{children:"src/styles/material.scss"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"src/styles.scss"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scss",children:"@import './styles/material.scss';\n\nhtml,\nbody {\n height: 100%;\n}\nbody {\n margin: 0;\n font-family: Nunito, sans-serif;\n}\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Nunito"})," font dependency is listed in ",(0,t.jsx)(n.a,{href:"#add-other-packages",children:"other packages"})," below."]})}),"\n",(0,t.jsx)(n.h2,{id:"add-tailwind",children:"Add Tailwind"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install -D tailwindcss postcss autoprefixer\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"tailwind.config.ts"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import type { Config } from 'tailwindcss';\n\nexport default {\n content: ['./src/**/*.{html,ts}'],\n\n corePlugins: {\n // Warning: Tailwind \"Preflight\" breaks some Angular material components\n //\n // Learn more about this issue and a hack to solve it:\n // https://github.com/tailwindlabs/tailwindcss/discussions/9993\n //\n // The hack is available here: `src/styles/tailwind.css`\n preflight: false,\n },\n\n theme: {\n extend: {},\n },\n\n plugins: [],\n} satisfies Config;\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"src/styles/tailwind.css"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-css",children:"@tailwind base;\n@tailwind components;\n@tailwind utilities;\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"src/styles.scss"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-scss",children:"@import './styles/tailwind.css';\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-eslint-and-prettier",children:"Add ESLint and Prettier"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"ng add @angular-eslint/schematics\n\nnpm i -D prettier eslint-config-prettier eslint-plugin-prettier prettier-plugin-organize-imports prettier-plugin-tailwindcss\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"eslint.config.js"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');\n\nmodule.exports = tseslint.config(\n {\n rules: {\n // Note: the following rule is an addon (by default, type definitions use `interface`, but we prefer to use `type`)\n '@typescript-eslint/consistent-type-definitions': ['error', 'type'],\n },\n },\n eslintPluginPrettierRecommended\n);\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Only the lines added are reported here."})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:".prettierrc.json"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "printWidth": 120,\n "singleQuote": true,\n "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-tailwindcss"],\n "overrides": [\n {\n "files": "*.html",\n "options": {\n "parser": "angular"\n }\n }\n ]\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:".prettierignore"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-txt",children:"/.angular\n/coverage\n/dist\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"package.json"})," scripts:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "format": "prettier --write .",\n "format:check": "prettier --check ."\n }\n}\n'})}),"\n",(0,t.jsx)(n.h2,{id:"using-jest-instead-of-karmajasmine",children:"Using Jest instead of Karma/Jasmine"}),"\n",(0,t.jsx)(n.p,{children:"First, remove all packages related to Karma and Jasmine. Next, install Jest related packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm i -D jest @types/jest @angular-builders/jest ts-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"tsconfig.spec.json"})," and ",(0,t.jsx)(n.code,{children:"tsconfig.json"})," files:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "compilerOptions": {\n "types": ["jest"]\n }\n}\n'})}),"\n",(0,t.jsx)(n.admonition,{type:"info",children:(0,t.jsxs)(n.p,{children:["You need to make this change even for the ",(0,t.jsx)(n.code,{children:"tsconfig.json"})," file, as it is used by the IDE."]})}),"\n",(0,t.jsxs)(n.p,{children:["Update ",(0,t.jsx)(n.code,{children:"angular.json"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "projects": {\n "client": {\n "architect": {\n "test": {\n "builder": "@angular-builders/jest:run",\n "options": {\n "configPath": "jest.config.ts"\n }\n }\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"jest.config.ts"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import type { Config } from 'jest';\n\nexport default {\n passWithNoTests: true,\n setupFiles: ['./setup-jest.ts'],\n} satisfies Config;\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Add ",(0,t.jsx)(n.code,{children:"setup-jest.ts"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ts",children:"import '@angular/localize/init';\n"})}),"\n",(0,t.jsx)(n.h2,{id:"add-other-packages",children:"Add other packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm i @fontsource/nunito canvas-confetti firebase js-cookie @material-symbols/font-600\n\nnpm i -D @types/canvas-confetti @types/js-cookie\n"})})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var i=s(6540);const t={},a=i.createContext(t);function r(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/c25608c0.2f327134.js b/docs/assets/js/c25608c0.2f327134.js new file mode 100644 index 00000000..19cac9cd --- /dev/null +++ b/docs/assets/js/c25608c0.2f327134.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[3144],{5703:(e,n,c)=>{c.r(n),c.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"technical-guides/client/icons","title":"Icons","description":"Material icons","source":"@site/docs/technical-guides/client/icons.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/icons","permalink":"/feedzback/docs/technical-guides/client/icons","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/icons.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Styles","permalink":"/feedzback/docs/technical-guides/client/styles"},"next":{"title":"Demo","permalink":"/feedzback/docs/technical-guides/client/demo"}}');var i=c(4848),o=c(8453);const s={},r="Icons",a={},l=[{value:"Material icons",id:"material-icons",level:2},{value:"IconDirective",id:"icondirective",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"icons",children:"Icons"})}),"\n",(0,i.jsx)(n.h2,{id:"material-icons",children:"Material icons"}),"\n",(0,i.jsxs)(n.p,{children:["The Material component ",(0,i.jsx)(n.code,{children:"<mat-icon>"})," is configured to use the icons from the NPM package ",(0,i.jsx)(n.code,{children:"@material-symbols/font-600"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["For more details, see the file ",(0,i.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/shared/icon/icon.provider.ts",children:(0,i.jsx)(n.code,{children:"src/app/shared/icon/icon.provider.ts"})}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"icondirective",children:"IconDirective"}),"\n",(0,i.jsxs)(n.p,{children:["The Material icon component ",(0,i.jsx)(n.code,{children:"<mat-icon>"})," has some limitations when it comes to resizing icons.\nUse the ",(0,i.jsx)(n.code,{children:"IconDirective"})," directive to overcome this problem."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { Component } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { IconDirective } from './shared/icon';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [MatIconModule, IconDirective],\n template: `\n <h1>\n <mat-icon appIcon size=\"xl\" pull=\"left\" animation=\"beat\">home</mat-icon>\n Home\n </h1>\n `,\n})\nexport class AppComponent {}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,c)=>{c.d(n,{R:()=>s,x:()=>r});var t=c(6540);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/c25608c0.dde76f92.js b/docs/assets/js/c25608c0.dde76f92.js deleted file mode 100644 index 5e22e717..00000000 --- a/docs/assets/js/c25608c0.dde76f92.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[144],{5703:(e,n,c)=>{c.r(n),c.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"technical-guides/client/icons","title":"Icons","description":"Material icons","source":"@site/docs/technical-guides/client/icons.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/icons","permalink":"/feedzback/docs/technical-guides/client/icons","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/icons.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Styles","permalink":"/feedzback/docs/technical-guides/client/styles"},"next":{"title":"Demo","permalink":"/feedzback/docs/technical-guides/client/demo"}}');var i=c(4848),o=c(8453);const s={},r="Icons",a={},l=[{value:"Material icons",id:"material-icons",level:2},{value:"IconDirective",id:"icondirective",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"icons",children:"Icons"})}),"\n",(0,i.jsx)(n.h2,{id:"material-icons",children:"Material icons"}),"\n",(0,i.jsxs)(n.p,{children:["The Material component ",(0,i.jsx)(n.code,{children:"<mat-icon>"})," is configured to use the icons from the NPM package ",(0,i.jsx)(n.code,{children:"@material-symbols/font-600"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["For more details, see the file ",(0,i.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/shared/icon/icon.provider.ts",children:(0,i.jsx)(n.code,{children:"src/app/shared/icon/icon.provider.ts"})}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"icondirective",children:"IconDirective"}),"\n",(0,i.jsxs)(n.p,{children:["The Material icon component ",(0,i.jsx)(n.code,{children:"<mat-icon>"})," has some limitations when it comes to resizing icons.\nUse the ",(0,i.jsx)(n.code,{children:"IconDirective"})," directive to overcome this problem."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-ts",children:"import { Component } from '@angular/core';\nimport { MatIconModule } from '@angular/material/icon';\nimport { IconDirective } from './shared/icon';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [MatIconModule, IconDirective],\n template: `\n <h1>\n <mat-icon appIcon size=\"xl\" pull=\"left\" animation=\"beat\">home</mat-icon>\n Home\n </h1>\n `,\n})\nexport class AppComponent {}\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,c)=>{c.d(n,{R:()=>s,x:()=>r});var t=c(6540);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/c4f5d8e4.3fa3f160.js b/docs/assets/js/c4f5d8e4.3fa3f160.js new file mode 100644 index 00000000..3881d0a4 --- /dev/null +++ b/docs/assets/js/c4f5d8e4.3fa3f160.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2634],{1459:(e,n,t)=>{t.r(n),t.d(n,{default:()=>h});var s=t(4164),a=t(8774),c=t(4586),o=t(781),r=t(1107);const i={heroBanner:"heroBanner_qdFl",container:"container_bfhl",buttons:"buttons_AeoN"};var l=t(4848);function d(){const{siteConfig:e}=(0,c.A)();return(0,l.jsx)("header",{className:(0,s.A)("hero",i.heroBanner),children:(0,l.jsxs)("div",{className:(0,s.A)("container",i.container),children:[(0,l.jsx)("img",{src:"./img/logo-feedzback.svg",width:212,height:112,alt:""}),(0,l.jsx)(r.A,{as:"h1",className:"hero__title",children:"Documentation"}),(0,l.jsx)("p",{className:"hero__subtitle",children:e.tagline}),(0,l.jsx)("div",{className:i.buttons,children:(0,l.jsx)(a.A,{className:"button button--secondary button--lg",to:"/docs/installation",children:"Get started"})})]})})}function h(){return(0,l.jsx)(o.A,{title:"Documentation",children:(0,l.jsx)(d,{})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/c4f5d8e4.c2f4e0ab.js b/docs/assets/js/c4f5d8e4.c2f4e0ab.js deleted file mode 100644 index 3501ba5a..00000000 --- a/docs/assets/js/c4f5d8e4.c2f4e0ab.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[634],{1459:(e,n,t)=>{t.r(n),t.d(n,{default:()=>h});var s=t(4164),a=t(8774),c=t(4586),o=t(781),r=t(1107);const i={heroBanner:"heroBanner_qdFl",container:"container_bfhl",buttons:"buttons_AeoN"};var l=t(4848);function d(){const{siteConfig:e}=(0,c.A)();return(0,l.jsx)("header",{className:(0,s.A)("hero",i.heroBanner),children:(0,l.jsxs)("div",{className:(0,s.A)("container",i.container),children:[(0,l.jsx)("img",{src:"./img/logo-feedzback.svg",width:212,height:112,alt:""}),(0,l.jsx)(r.A,{as:"h1",className:"hero__title",children:"Documentation"}),(0,l.jsx)("p",{className:"hero__subtitle",children:e.tagline}),(0,l.jsx)("div",{className:i.buttons,children:(0,l.jsx)(a.A,{className:"button button--secondary button--lg",to:"/docs/installation",children:"Get started"})})]})})}function h(){return(0,l.jsx)(o.A,{title:"Documentation",children:(0,l.jsx)(d,{})})}}}]); \ No newline at end of file diff --git a/docs/assets/js/c5702bff.4e7b7752.js b/docs/assets/js/c5702bff.4e7b7752.js new file mode 100644 index 00000000..de2b2008 --- /dev/null +++ b/docs/assets/js/c5702bff.4e7b7752.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[7990],{4008:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"technical-guides/client/styles","title":"Styles","description":"Global styles","source":"@site/docs/technical-guides/client/styles.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/styles","permalink":"/feedzback/docs/technical-guides/client/styles","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/styles.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Firebase Hosting","permalink":"/feedzback/docs/technical-guides/client/firebase-hosting"},"next":{"title":"Icons","permalink":"/feedzback/docs/technical-guides/client/icons"}}');var l=s(4848),i=s(8453);const a={},c="Styles",o={},r=[{value:"Global styles",id:"global-styles",level:2},{value:"Component styles",id:"component-styles",level:2},{value:"Material",id:"material",level:2},{value:"Tailwindcss",id:"tailwindcss",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"styles",children:"Styles"})}),"\n",(0,l.jsx)(n.h2,{id:"global-styles",children:"Global styles"}),"\n",(0,l.jsxs)(n.p,{children:["The entry point of the global styles is as usual for an Angular application: ",(0,l.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/styles.scss",children:"client/src/styles.scss"})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scss",children:"// ----- Base -----\n\n@import './styles/fonts';\n@import './styles/tailwind.css';\n@import './styles/material';\n@import './styles/base';\n\n// ----- Special `.gbl-*` styles -----\n\n@import './styles/common';\n@import './styles/info';\n@import './styles/landing';\n@import './styles/forms';\n"})}),"\n",(0,l.jsxs)(n.p,{children:["All special global styles starts with ",(0,l.jsx)(n.code,{children:".gbl-*"})," prefix."]}),"\n",(0,l.jsx)(n.h2,{id:"component-styles",children:"Component styles"}),"\n",(0,l.jsxs)(n.p,{children:["All component styles starts with ",(0,l.jsx)(n.code,{children:".app-*"})," prefix."]}),"\n",(0,l.jsxs)(n.p,{children:["Component styles are encapsulated manually following the ",(0,l.jsx)(n.a,{href:"https://getbem.com/introduction/",children:"BEM"})," convention (",(0,l.jsx)(n.strong,{children:"B"}),"lock-",(0,l.jsx)(n.strong,{children:"E"}),"lement-",(0,l.jsx)(n.strong,{children:"M"}),"odifier)."]}),"\n",(0,l.jsx)(n.p,{children:"Here's an example with the header component:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",metastring:'title="client/src/app/header/header.component.ts"',children:"import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'app-header',\n host: { class: 'app-header' }, // Component root css class\n standalone: true,\n templateUrl: './header.component.html',\n styleUrl: './header.component.scss',\n encapsulation: ViewEncapsulation.None, // No framework encapsulation\n})\nexport class HeaderComponent {}\n"})}),"\n",(0,l.jsx)(n.p,{children:"This is what the final markup looks like when rendered in the browser:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-html",children:'\x3c!-- Block --\x3e\n<app-header class="app-header">\n \x3c!-- Element --\x3e\n <div class="app-header__logo">...</div>\n \x3c!-- Element and Modifier --\x3e\n <nav class="app-header__menu app-header__menu--visible">...</nav>\n ...\n</app-header>\n'})}),"\n",(0,l.jsx)(n.p,{children:"And the Sass styles should looks like this:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scss",metastring:'title="client/src/app/header/header.component.scss"',children:"@use '../app.scss' as app;\n\n.app-header {\n &__logo {\n // ...\n }\n &__menu {\n // ...\n &--visible {\n // ...\n }\n }\n}\n"})}),"\n",(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/app.scss",children:(0,l.jsx)(n.code,{children:"src/app/app.scss"})})," file gives you access to the global Sass variables and mixins in the component styles."]})}),"\n",(0,l.jsx)(n.h2,{id:"material",children:"Material"}),"\n",(0,l.jsxs)(n.p,{children:["Material design typography is enabled for the entire HTML page using the ",(0,l.jsx)(n.code,{children:".mat-typography"})," css class on the body tag:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-html",metastring:'title="client/src/index.html"',children:'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <title>FeedZback\n \n \n \n \n \n \n \n\n'})}),"\n",(0,l.jsxs)(n.p,{children:["Only the styles of the Material components that are used in the application are included.\nSee ",(0,l.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/styles/material/index.scss",children:"here"})," for more infos."]}),"\n",(0,l.jsx)(n.h2,{id:"tailwindcss",children:"Tailwindcss"}),"\n",(0,l.jsxs)(n.p,{children:["Tailwind is only used in Angular component templates for utility classes like: ",(0,l.jsx)(n.code,{children:"ms-4"}),", ",(0,l.jsx)(n.code,{children:"me-4"}),", ",(0,l.jsx)(n.code,{children:"mb-4"}),", ",(0,l.jsx)(n.code,{children:"flex"}),", ",(0,l.jsx)(n.code,{children:"items-center"}),", ",(0,l.jsx)(n.code,{children:"justify-center"}),", ...\nThe main styles are written in Angular component styles following the ",(0,l.jsx)(n.strong,{children:"BEM"})," convention."]}),"\n",(0,l.jsxs)(n.p,{children:['Currently, Tailwind "Preflight" breaks some Angular material components.\nIt also conflicts with the global ',(0,l.jsx)(n.code,{children:".mat-typography"}),".\nTherefore it has been disabled:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",metastring:'title="client/tailwind.config.ts"',children:"import type { Config } from 'tailwindcss';\n\nexport default {\n corePlugins: {\n // Warning: Tailwind \"Preflight\" breaks some Angular material components\n //\n // Learn more about this issue and a hack to solve it:\n // https://github.com/tailwindlabs/tailwindcss/discussions/9993\n preflight: false,\n },\n} satisfies Config;\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>c});var t=s(6540);const l={},i=t.createContext(l);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/c5702bff.e6cec9bd.js b/docs/assets/js/c5702bff.e6cec9bd.js deleted file mode 100644 index 388752ca..00000000 --- a/docs/assets/js/c5702bff.e6cec9bd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[990],{4008:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>r});const t=JSON.parse('{"id":"technical-guides/client/styles","title":"Styles","description":"Global styles","source":"@site/docs/technical-guides/client/styles.md","sourceDirName":"technical-guides/client","slug":"/technical-guides/client/styles","permalink":"/feedzback/docs/technical-guides/client/styles","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/client/styles.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Firebase Hosting","permalink":"/feedzback/docs/technical-guides/client/firebase-hosting"},"next":{"title":"Icons","permalink":"/feedzback/docs/technical-guides/client/icons"}}');var l=s(4848),i=s(8453);const a={},c="Styles",o={},r=[{value:"Global styles",id:"global-styles",level:2},{value:"Component styles",id:"component-styles",level:2},{value:"Material",id:"material",level:2},{value:"Tailwindcss",id:"tailwindcss",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"styles",children:"Styles"})}),"\n",(0,l.jsx)(n.h2,{id:"global-styles",children:"Global styles"}),"\n",(0,l.jsxs)(n.p,{children:["The entry point of the global styles is as usual for an Angular application: ",(0,l.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/styles.scss",children:"client/src/styles.scss"})]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scss",children:"// ----- Base -----\n\n@import './styles/fonts';\n@import './styles/tailwind.css';\n@import './styles/material';\n@import './styles/base';\n\n// ----- Special `.gbl-*` styles -----\n\n@import './styles/common';\n@import './styles/info';\n@import './styles/landing';\n@import './styles/forms';\n"})}),"\n",(0,l.jsxs)(n.p,{children:["All special global styles starts with ",(0,l.jsx)(n.code,{children:".gbl-*"})," prefix."]}),"\n",(0,l.jsx)(n.h2,{id:"component-styles",children:"Component styles"}),"\n",(0,l.jsxs)(n.p,{children:["All component styles starts with ",(0,l.jsx)(n.code,{children:".app-*"})," prefix."]}),"\n",(0,l.jsxs)(n.p,{children:["Component styles are encapsulated manually following the ",(0,l.jsx)(n.a,{href:"https://getbem.com/introduction/",children:"BEM"})," convention (",(0,l.jsx)(n.strong,{children:"B"}),"lock-",(0,l.jsx)(n.strong,{children:"E"}),"lement-",(0,l.jsx)(n.strong,{children:"M"}),"odifier)."]}),"\n",(0,l.jsx)(n.p,{children:"Here's an example with the header component:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",metastring:'title="client/src/app/header/header.component.ts"',children:"import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'app-header',\n host: { class: 'app-header' }, // Component root css class\n standalone: true,\n templateUrl: './header.component.html',\n styleUrl: './header.component.scss',\n encapsulation: ViewEncapsulation.None, // No framework encapsulation\n})\nexport class HeaderComponent {}\n"})}),"\n",(0,l.jsx)(n.p,{children:"This is what the final markup looks like when rendered in the browser:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-html",children:'\x3c!-- Block --\x3e\n\n \x3c!-- Element --\x3e\n \n \x3c!-- Element and Modifier --\x3e\n \n ...\n\n'})}),"\n",(0,l.jsx)(n.p,{children:"And the Sass styles should looks like this:"}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-scss",metastring:'title="client/src/app/header/header.component.scss"',children:"@use '../app.scss' as app;\n\n.app-header {\n &__logo {\n // ...\n }\n &__menu {\n // ...\n &--visible {\n // ...\n }\n }\n}\n"})}),"\n",(0,l.jsx)(n.admonition,{type:"note",children:(0,l.jsxs)(n.p,{children:["The ",(0,l.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/app.scss",children:(0,l.jsx)(n.code,{children:"src/app/app.scss"})})," file gives you access to the global Sass variables and mixins in the component styles."]})}),"\n",(0,l.jsx)(n.h2,{id:"material",children:"Material"}),"\n",(0,l.jsxs)(n.p,{children:["Material design typography is enabled for the entire HTML page using the ",(0,l.jsx)(n.code,{children:".mat-typography"})," css class on the body tag:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-html",metastring:'title="client/src/index.html"',children:'\n\n \n \n FeedZback\n \n \n \n \n \n \n \n\n'})}),"\n",(0,l.jsxs)(n.p,{children:["Only the styles of the Material components that are used in the application are included.\nSee ",(0,l.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/styles/material/index.scss",children:"here"})," for more infos."]}),"\n",(0,l.jsx)(n.h2,{id:"tailwindcss",children:"Tailwindcss"}),"\n",(0,l.jsxs)(n.p,{children:["Tailwind is only used in Angular component templates for utility classes like: ",(0,l.jsx)(n.code,{children:"ms-4"}),", ",(0,l.jsx)(n.code,{children:"me-4"}),", ",(0,l.jsx)(n.code,{children:"mb-4"}),", ",(0,l.jsx)(n.code,{children:"flex"}),", ",(0,l.jsx)(n.code,{children:"items-center"}),", ",(0,l.jsx)(n.code,{children:"justify-center"}),", ...\nThe main styles are written in Angular component styles following the ",(0,l.jsx)(n.strong,{children:"BEM"})," convention."]}),"\n",(0,l.jsxs)(n.p,{children:['Currently, Tailwind "Preflight" breaks some Angular material components.\nIt also conflicts with the global ',(0,l.jsx)(n.code,{children:".mat-typography"}),".\nTherefore it has been disabled:"]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-ts",metastring:'title="client/tailwind.config.ts"',children:"import type { Config } from 'tailwindcss';\n\nexport default {\n corePlugins: {\n // Warning: Tailwind \"Preflight\" breaks some Angular material components\n //\n // Learn more about this issue and a hack to solve it:\n // https://github.com/tailwindlabs/tailwindcss/discussions/9993\n preflight: false,\n },\n} satisfies Config;\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>c});var t=s(6540);const l={},i=t.createContext(l);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/ccc49370.0689cd21.js b/docs/assets/js/ccc49370.0689cd21.js new file mode 100644 index 00000000..5d960304 --- /dev/null +++ b/docs/assets/js/ccc49370.0689cd21.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[3249],{5856:(e,t,n)=>{n.d(t,{A:()=>F});var a=n(6540),r=n(4164),s=n(4096),l=n(4848);function o(e){let{children:t,className:n}=e;return(0,l.jsx)("article",{className:n,children:t})}var i=n(8774);const c={title:"title_f1Hy"};function d(e){let{className:t}=e;const{metadata:n,isBlogPostPage:a}=(0,s.e7)(),{permalink:o,title:d}=n,u=a?"h1":"h2";return(0,l.jsx)(u,{className:(0,r.A)(c.title,t),children:a?d:(0,l.jsx)(i.A,{to:o,children:d})})}var u=n(1312),m=n(4586);const h=["zero","one","two","few","many","other"];function g(e){return h.filter((t=>e.includes(t)))}const f={locale:"en",pluralForms:g(["one","other"]),select:e=>1===e?"one":"other"};function x(){const{i18n:{currentLocale:e}}=(0,m.A)();return(0,a.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:g(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),f}}),[e])}function p(){const e=x();return{selectMessage:(t,n)=>function(e,t,n){const a=e.split("|");if(1===a.length)return a[0];a.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const r=n.select(t),s=n.pluralForms.indexOf(r);return a[Math.min(s,a.length-1)]}(n,t,e)}}var v=n(6266);const j={container:"container_mt6G"};function b(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=p();return t=>{const n=Math.ceil(t);return e(n,(0,u.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,l.jsx)(l.Fragment,{children:n(t)})}function A(e){let{date:t,formattedDate:n}=e;return(0,l.jsx)("time",{dateTime:t,children:n})}function N(){return(0,l.jsx)(l.Fragment,{children:" \xb7 "})}function L(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:a,readingTime:o}=n,i=(0,v.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,l.jsxs)("div",{className:(0,r.A)(j.container,"margin-vert--md",t),children:[(0,l.jsx)(A,{date:a,formattedDate:(c=a,i.format(new Date(c)))}),void 0!==o&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(N,{}),(0,l.jsx)(b,{readingTime:o})]})]});var c}var y=n(6913);const C={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function _(e){let{className:t}=e;const{metadata:{authors:n},assets:a}=(0,s.e7)();if(0===n.length)return null;const o=n.every((e=>{let{name:t}=e;return!t})),i=1===n.length;return(0,l.jsx)("div",{className:(0,r.A)("margin-top--md margin-bottom--sm",o?C.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,l.jsx)("div",{className:(0,r.A)(!o&&(i?"col col--12":"col col--6"),o?C.imageOnlyAuthorCol:C.authorCol),children:(0,l.jsx)(y.A,{author:{...e,imageURL:a.authorsImageUrls[t]??e.imageURL}})},t)))})}function k(){return(0,l.jsxs)("header",{children:[(0,l.jsx)(d,{}),(0,l.jsx)(L,{}),(0,l.jsx)(_,{})]})}var w=n(440),H=n(5533);function T(e){let{children:t,className:n}=e;const{isBlogPostPage:a}=(0,s.e7)();return(0,l.jsx)("div",{id:a?w.LU:void 0,className:(0,r.A)("markdown",n),children:(0,l.jsx)(H.A,{children:t})})}var O=n(7559),P=n(4336),I=n(8046);function M(){return(0,l.jsx)("b",{children:(0,l.jsx)(u.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function B(e){const{blogPostTitle:t,...n}=e;return(0,l.jsx)(i.A,{"aria-label":(0,u.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,l.jsx)(M,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:a,editUrl:o,hasTruncateMarker:i,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&i,m=n.length>0;if(!(m||u||o))return null;if(t){const e=!!(o||d||c);return(0,l.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,r.A)("row","margin-top--sm",O.G.blog.blogFooterEditMetaRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(I.A,{tags:n})})}),e&&(0,l.jsx)(P.A,{className:(0,r.A)("margin-top--sm",O.G.blog.blogFooterEditMetaRow),editUrl:o,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,l.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,r.A)("col",{"col--9":u}),children:(0,l.jsx)(I.A,{tags:n})}),u&&(0,l.jsx)("div",{className:(0,r.A)("col text--right",{"col--3":m}),children:(0,l.jsx)(B,{blogPostTitle:a,to:e.permalink})})]})}function F(e){let{children:t,className:n}=e;const a=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,l.jsxs)(o,{className:(0,r.A)(a,n),children:[(0,l.jsx)(k,{}),(0,l.jsx)(T,{children:t}),(0,l.jsx)(R,{})]})}},3858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(6540);var a=n(4164),r=n(1213),s=n(7559),l=n(4096),o=n(8027),i=n(5856),c=n(1312),d=n(9022),u=n(4848);function m(e){const{nextItem:t,prevItem:n}=e;return(0,u.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,u.jsx)(d.A,{...n,subLabel:(0,u.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,u.jsx)(d.A,{...t,subLabel:(0,u.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function h(){const{assets:e,metadata:t}=(0,l.e7)(),{title:n,description:a,date:s,tags:o,authors:i,frontMatter:c}=t,{keywords:d}=c,m=e.image??c.image;return(0,u.jsxs)(r.be,{title:c.title_meta??n,description:a,keywords:d,image:m,children:[(0,u.jsx)("meta",{property:"og:type",content:"article"}),(0,u.jsx)("meta",{property:"article:published_time",content:s}),i.some((e=>e.url))&&(0,u.jsx)("meta",{property:"article:author",content:i.map((e=>e.url)).filter(Boolean).join(",")}),o.length>0&&(0,u.jsx)("meta",{property:"article:tag",content:o.map((e=>e.label)).join(",")})]})}var g=n(5260);function f(){const e=(0,l.J_)();return(0,u.jsx)(g.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var x=n(7763),p=n(6896);function v(e){let{sidebar:t,children:n}=e;const{metadata:a,toc:r}=(0,l.e7)(),{nextItem:s,prevItem:c,frontMatter:d}=a,{hide_table_of_contents:h,toc_min_heading_level:g,toc_max_heading_level:f}=d;return(0,u.jsxs)(o.A,{sidebar:t,toc:!h&&r.length>0?(0,u.jsx)(x.A,{toc:r,minHeadingLevel:g,maxHeadingLevel:f}):void 0,children:[(0,u.jsx)(p.A,{metadata:a}),(0,u.jsx)(i.A,{children:n}),(s||c)&&(0,u.jsx)(m,{nextItem:s,prevItem:c})]})}function j(e){const t=e.content;return(0,u.jsx)(l.in,{content:e.content,isBlogPostPage:!0,children:(0,u.jsxs)(r.e3,{className:(0,a.A)(s.G.wrapper.blogPages,s.G.page.blogPostPage),children:[(0,u.jsx)(h,{}),(0,u.jsx)(f,{}),(0,u.jsx)(v,{sidebar:e.sidebar,children:(0,u.jsx)(t,{})})]})})}},6896:(e,t,n)=>{n.d(t,{A:()=>p});n(6540);var a=n(4164),r=n(1312),s=n(5260),l=n(4848);function o(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function i(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,l.jsx)(s.A,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function d(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function u(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}var m=n(7559),h=n(7293);function g(e){let{className:t}=e;return(0,l.jsx)(h.A,{type:"caution",title:(0,l.jsx)(d,{}),className:(0,a.A)(t,m.G.common.draftBanner),children:(0,l.jsx)(u,{})})}function f(e){let{className:t}=e;return(0,l.jsx)(h.A,{type:"caution",title:(0,l.jsx)(o,{}),className:(0,a.A)(t,m.G.common.unlistedBanner),children:(0,l.jsx)(i,{})})}function x(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c,{}),(0,l.jsx)(f,{...e})]})}function p(e){let{metadata:t}=e;const{unlisted:n,frontMatter:a}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||a.unlisted)&&(0,l.jsx)(x,{}),a.draft&&(0,l.jsx)(g,{})]})}},7763:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var a=n(4164),r=n(5195);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var l=n(4848);const o="table-of-contents__link toc-highlight",i="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,l.jsx)("div",{className:(0,a.A)(s.tableOfContents,"thin-scrollbar",t),children:(0,l.jsx)(r.A,{...n,linkClassName:o,linkActiveClassName:i})})}},5195:(e,t,n)=>{n.d(t,{A:()=>f});var a=n(6540),r=n(6342);function s(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...r}=e;n>=0?t[n].children.push(r):a.push(r)})),a}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function o(e){const t=e.getBoundingClientRect();return t.top===t.bottom?o(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>o(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:r,minHeadingLevel:s,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let r=t;r<=n;r+=1)a.push(`h${r}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:s,maxHeadingLevel:l}),c=i(o,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(r),e.classList.add(r),t.current=e):e.classList.remove(r)}(e,e===d)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}var u=n(8774),m=n(4848);function h(e){let{toc:t,className:n,linkClassName:a,isChild:r}=e;return t.length?(0,m.jsx)("ul",{className:r?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:a})]},e.id)))}):null}const g=a.memo(h);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:o="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const f=(0,r.p)(),x=c??f.tableOfContents.minHeadingLevel,p=u??f.tableOfContents.maxHeadingLevel,v=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:r}=e;return(0,a.useMemo)((()=>l({toc:s(t),minHeadingLevel:n,maxHeadingLevel:r})),[t,n,r])}({toc:t,minHeadingLevel:x,maxHeadingLevel:p});return d((0,a.useMemo)((()=>{if(o&&i)return{linkClassName:o,linkActiveClassName:i,minHeadingLevel:x,maxHeadingLevel:p}}),[o,i,x,p])),(0,m.jsx)(g,{toc:v,className:n,linkClassName:o,...h})}}}]); \ No newline at end of file diff --git a/docs/assets/js/ccc49370.37080a12.js b/docs/assets/js/ccc49370.37080a12.js deleted file mode 100644 index 687312a3..00000000 --- a/docs/assets/js/ccc49370.37080a12.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[249],{5856:(e,t,n)=>{n.d(t,{A:()=>F});var a=n(6540),r=n(4164),s=n(4096),l=n(4848);function o(e){let{children:t,className:n}=e;return(0,l.jsx)("article",{className:n,children:t})}var i=n(8774);const c={title:"title_f1Hy"};function d(e){let{className:t}=e;const{metadata:n,isBlogPostPage:a}=(0,s.e7)(),{permalink:o,title:d}=n,u=a?"h1":"h2";return(0,l.jsx)(u,{className:(0,r.A)(c.title,t),children:a?d:(0,l.jsx)(i.A,{to:o,children:d})})}var u=n(1312),m=n(4586);const h=["zero","one","two","few","many","other"];function g(e){return h.filter((t=>e.includes(t)))}const f={locale:"en",pluralForms:g(["one","other"]),select:e=>1===e?"one":"other"};function x(){const{i18n:{currentLocale:e}}=(0,m.A)();return(0,a.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:g(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),f}}),[e])}function p(){const e=x();return{selectMessage:(t,n)=>function(e,t,n){const a=e.split("|");if(1===a.length)return a[0];a.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const r=n.select(t),s=n.pluralForms.indexOf(r);return a[Math.min(s,a.length-1)]}(n,t,e)}}var v=n(6266);const j={container:"container_mt6G"};function b(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=p();return t=>{const n=Math.ceil(t);return e(n,(0,u.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,l.jsx)(l.Fragment,{children:n(t)})}function A(e){let{date:t,formattedDate:n}=e;return(0,l.jsx)("time",{dateTime:t,children:n})}function N(){return(0,l.jsx)(l.Fragment,{children:" \xb7 "})}function L(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:a,readingTime:o}=n,i=(0,v.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,l.jsxs)("div",{className:(0,r.A)(j.container,"margin-vert--md",t),children:[(0,l.jsx)(A,{date:a,formattedDate:(c=a,i.format(new Date(c)))}),void 0!==o&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(N,{}),(0,l.jsx)(b,{readingTime:o})]})]});var c}var y=n(6913);const C={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function _(e){let{className:t}=e;const{metadata:{authors:n},assets:a}=(0,s.e7)();if(0===n.length)return null;const o=n.every((e=>{let{name:t}=e;return!t})),i=1===n.length;return(0,l.jsx)("div",{className:(0,r.A)("margin-top--md margin-bottom--sm",o?C.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,l.jsx)("div",{className:(0,r.A)(!o&&(i?"col col--12":"col col--6"),o?C.imageOnlyAuthorCol:C.authorCol),children:(0,l.jsx)(y.A,{author:{...e,imageURL:a.authorsImageUrls[t]??e.imageURL}})},t)))})}function k(){return(0,l.jsxs)("header",{children:[(0,l.jsx)(d,{}),(0,l.jsx)(L,{}),(0,l.jsx)(_,{})]})}var w=n(440),H=n(5533);function T(e){let{children:t,className:n}=e;const{isBlogPostPage:a}=(0,s.e7)();return(0,l.jsx)("div",{id:a?w.LU:void 0,className:(0,r.A)("markdown",n),children:(0,l.jsx)(H.A,{children:t})})}var O=n(7559),P=n(4336),I=n(8046);function M(){return(0,l.jsx)("b",{children:(0,l.jsx)(u.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function B(e){const{blogPostTitle:t,...n}=e;return(0,l.jsx)(i.A,{"aria-label":(0,u.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,l.jsx)(M,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:a,editUrl:o,hasTruncateMarker:i,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&i,m=n.length>0;if(!(m||u||o))return null;if(t){const e=!!(o||d||c);return(0,l.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,r.A)("row","margin-top--sm",O.G.blog.blogFooterEditMetaRow),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(I.A,{tags:n})})}),e&&(0,l.jsx)(P.A,{className:(0,r.A)("margin-top--sm",O.G.blog.blogFooterEditMetaRow),editUrl:o,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,l.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,l.jsx)("div",{className:(0,r.A)("col",{"col--9":u}),children:(0,l.jsx)(I.A,{tags:n})}),u&&(0,l.jsx)("div",{className:(0,r.A)("col text--right",{"col--3":m}),children:(0,l.jsx)(B,{blogPostTitle:a,to:e.permalink})})]})}function F(e){let{children:t,className:n}=e;const a=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,l.jsxs)(o,{className:(0,r.A)(a,n),children:[(0,l.jsx)(k,{}),(0,l.jsx)(T,{children:t}),(0,l.jsx)(R,{})]})}},3858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(6540);var a=n(4164),r=n(1213),s=n(7559),l=n(4096),o=n(8027),i=n(5856),c=n(1312),d=n(9022),u=n(4848);function m(e){const{nextItem:t,prevItem:n}=e;return(0,u.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,u.jsx)(d.A,{...n,subLabel:(0,u.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,u.jsx)(d.A,{...t,subLabel:(0,u.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function h(){const{assets:e,metadata:t}=(0,l.e7)(),{title:n,description:a,date:s,tags:o,authors:i,frontMatter:c}=t,{keywords:d}=c,m=e.image??c.image;return(0,u.jsxs)(r.be,{title:c.title_meta??n,description:a,keywords:d,image:m,children:[(0,u.jsx)("meta",{property:"og:type",content:"article"}),(0,u.jsx)("meta",{property:"article:published_time",content:s}),i.some((e=>e.url))&&(0,u.jsx)("meta",{property:"article:author",content:i.map((e=>e.url)).filter(Boolean).join(",")}),o.length>0&&(0,u.jsx)("meta",{property:"article:tag",content:o.map((e=>e.label)).join(",")})]})}var g=n(5260);function f(){const e=(0,l.J_)();return(0,u.jsx)(g.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var x=n(7763),p=n(6896);function v(e){let{sidebar:t,children:n}=e;const{metadata:a,toc:r}=(0,l.e7)(),{nextItem:s,prevItem:c,frontMatter:d}=a,{hide_table_of_contents:h,toc_min_heading_level:g,toc_max_heading_level:f}=d;return(0,u.jsxs)(o.A,{sidebar:t,toc:!h&&r.length>0?(0,u.jsx)(x.A,{toc:r,minHeadingLevel:g,maxHeadingLevel:f}):void 0,children:[(0,u.jsx)(p.A,{metadata:a}),(0,u.jsx)(i.A,{children:n}),(s||c)&&(0,u.jsx)(m,{nextItem:s,prevItem:c})]})}function j(e){const t=e.content;return(0,u.jsx)(l.in,{content:e.content,isBlogPostPage:!0,children:(0,u.jsxs)(r.e3,{className:(0,a.A)(s.G.wrapper.blogPages,s.G.page.blogPostPage),children:[(0,u.jsx)(h,{}),(0,u.jsx)(f,{}),(0,u.jsx)(v,{sidebar:e.sidebar,children:(0,u.jsx)(t,{})})]})})}},6896:(e,t,n)=>{n.d(t,{A:()=>p});n(6540);var a=n(4164),r=n(1312),s=n(5260),l=n(4848);function o(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function i(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,l.jsx)(s.A,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function d(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function u(){return(0,l.jsx)(r.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}var m=n(7559),h=n(7293);function g(e){let{className:t}=e;return(0,l.jsx)(h.A,{type:"caution",title:(0,l.jsx)(d,{}),className:(0,a.A)(t,m.G.common.draftBanner),children:(0,l.jsx)(u,{})})}function f(e){let{className:t}=e;return(0,l.jsx)(h.A,{type:"caution",title:(0,l.jsx)(o,{}),className:(0,a.A)(t,m.G.common.unlistedBanner),children:(0,l.jsx)(i,{})})}function x(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c,{}),(0,l.jsx)(f,{...e})]})}function p(e){let{metadata:t}=e;const{unlisted:n,frontMatter:a}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||a.unlisted)&&(0,l.jsx)(x,{}),a.draft&&(0,l.jsx)(g,{})]})}},7763:(e,t,n)=>{n.d(t,{A:()=>c});n(6540);var a=n(4164),r=n(5195);const s={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var l=n(4848);const o="table-of-contents__link toc-highlight",i="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,l.jsx)("div",{className:(0,a.A)(s.tableOfContents,"thin-scrollbar",t),children:(0,l.jsx)(r.A,{...n,linkClassName:o,linkActiveClassName:i})})}},5195:(e,t,n)=>{n.d(t,{A:()=>f});var a=n(6540),r=n(6342);function s(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...r}=e;n>=0?t[n].children.push(r):a.push(r)})),a}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function o(e){const t=e.getBoundingClientRect();return t.top===t.bottom?o(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>o(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:r,minHeadingLevel:s,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let r=t;r<=n;r+=1)a.push(`h${r}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:s,maxHeadingLevel:l}),c=i(o,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(r),e.classList.add(r),t.current=e):e.classList.remove(r)}(e,e===d)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}var u=n(8774),m=n(4848);function h(e){let{toc:t,className:n,linkClassName:a,isChild:r}=e;return t.length?(0,m.jsx)("ul",{className:r?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:a})]},e.id)))}):null}const g=a.memo(h);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:o="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const f=(0,r.p)(),x=c??f.tableOfContents.minHeadingLevel,p=u??f.tableOfContents.maxHeadingLevel,v=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:r}=e;return(0,a.useMemo)((()=>l({toc:s(t),minHeadingLevel:n,maxHeadingLevel:r})),[t,n,r])}({toc:t,minHeadingLevel:x,maxHeadingLevel:p});return d((0,a.useMemo)((()=>{if(o&&i)return{linkClassName:o,linkActiveClassName:i,minHeadingLevel:x,maxHeadingLevel:p}}),[o,i,x,p])),(0,m.jsx)(g,{toc:v,className:n,linkClassName:o,...h})}}}]); \ No newline at end of file diff --git a/docs/assets/js/dfa15f88.2be00124.js b/docs/assets/js/dfa15f88.2be00124.js new file mode 100644 index 00000000..8eedd4d9 --- /dev/null +++ b/docs/assets/js/dfa15f88.2be00124.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[6314],{2062:e=>{e.exports=JSON.parse('{"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null,"count":1}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/dfa15f88.eab7e294.js b/docs/assets/js/dfa15f88.eab7e294.js deleted file mode 100644 index ec472c71..00000000 --- a/docs/assets/js/dfa15f88.eab7e294.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[314],{2062:e=>{e.exports=JSON.parse('{"authors":[{"name":"St\xe9phane Francel","title":"Tech lead of FeedZback","url":"https://github.com/avine","imageURL":"https://avatars.githubusercontent.com/u/1133214?v=4","key":"stephane.francel","page":null,"count":1}]}')}}]); \ No newline at end of file diff --git a/docs/assets/js/e327052b.000c169e.js b/docs/assets/js/e327052b.000c169e.js deleted file mode 100644 index dfe1d831..00000000 --- a/docs/assets/js/e327052b.000c169e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[187],{2455:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"business-cases/feedback-draft","title":"Feedback draft","description":"User story","source":"@site/docs/business-cases/feedback-draft.md","sourceDirName":"business-cases","slug":"/business-cases/feedback-draft","permalink":"/feedzback/docs/business-cases/feedback-draft","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/feedback-draft.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Give spontaneous feedback","permalink":"/feedzback/docs/business-cases/give-spontaneous-feedback"},"next":{"title":"Shared feedback","permalink":"/feedzback/docs/business-cases/shared-feedback"}}');var c=s(4848),a=s(8453);const i={},d="Feedback draft",r={},o=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"feedbackRequest drafts",id:"feedbackrequest-drafts",level:3},{value:"feedback drafts",id:"feedback-drafts",level:3},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"feedback-draft",children:"Feedback draft"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"When I reply to a feedback request or give spontaneous feedback, if I can't complete my feedback in one go, I'd like to be able to save it as a draft and continue later."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["The drafts are stored in the ",(0,c.jsx)(n.code,{children:"feedbackDraft"})," Firestore collection."]}),"\n",(0,c.jsxs)(n.p,{children:["In this collection, the document ID is the ",(0,c.jsx)(n.code,{children:"giverEmail"})," (who wrote and saved the draft), whether he is internal or external to the Zenika organisation."]}),"\n",(0,c.jsxs)(n.p,{children:["For a given ",(0,c.jsx)(n.code,{children:"giverEmail"}),", there can be 2 nested collections:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"feedbackRequest"}),": contains drafts saved when replying to a feedback request"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"feedback"}),": contains drafts saved when giving a spontaneous feedback"]}),"\n"]}),"\n",(0,c.jsxs)(n.h3,{id:"feedbackrequest-drafts",children:[(0,c.jsx)(n.code,{children:"feedbackRequest"})," drafts"]}),"\n",(0,c.jsxs)(n.p,{children:["In this collection, the document ID is the ",(0,c.jsx)(n.code,{children:"tokenId"})," and the document contains the following fields:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequestDraft: FeedbackRequestDraft = {\n token: '123secret', // Redondant data - same value as the document ID itself\n receiverEmail: 'pinochio@zenika.com', // Redondant data - already available in the original `FeedbackRequest` document\n\n // ----------------------------\n // The relevant data start here\n positive: 'You did great...', // Might be empty because its just a draft\n negative: '', // Might be empty...\n comment: '', // Might be empty...\n};\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["The redundant field ",(0,c.jsx)(n.code,{children:"receiverEmail"})," has been added to be able to display the list of drafts by recipient."]})}),"\n",(0,c.jsxs)(n.h3,{id:"feedback-drafts",children:[(0,c.jsx)(n.code,{children:"feedback"})," drafts"]}),"\n",(0,c.jsxs)(n.p,{children:["In this collection, the document ID is the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," and the document contains the following fields:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackDraft: FeedbackDraft = {\n receiverEmail: 'pinochio@zenika.com', // Redondant data - same value as the document ID itself\n\n // ----------------------------\n // The relevant data start here\n positive: 'You did great...', // Might be empty because its just a draft\n negative: '', // Might be empty...\n comment: '', // Might be empty...\n shared: true,\n};\n"})}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"GiveRequestedFeedbackComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback-draft/give-feedback-draft.component.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackDraftComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback-draft/give-feedback-draft.service.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackDraftService"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"giveRequestedDraft"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"giveDraft"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(6540);const c={},a=t.createContext(c);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/e327052b.a76936ab.js b/docs/assets/js/e327052b.a76936ab.js new file mode 100644 index 00000000..91a0f603 --- /dev/null +++ b/docs/assets/js/e327052b.a76936ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[4187],{2455:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>t,toc:()=>o});const t=JSON.parse('{"id":"business-cases/feedback-draft","title":"Feedback draft","description":"User story","source":"@site/docs/business-cases/feedback-draft.md","sourceDirName":"business-cases","slug":"/business-cases/feedback-draft","permalink":"/feedzback/docs/business-cases/feedback-draft","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/feedback-draft.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Give spontaneous feedback","permalink":"/feedzback/docs/business-cases/give-spontaneous-feedback"},"next":{"title":"Shared feedback","permalink":"/feedzback/docs/business-cases/shared-feedback"}}');var c=s(4848),a=s(8453);const i={},d="Feedback draft",r={},o=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"feedbackRequest drafts",id:"feedbackrequest-drafts",level:3},{value:"feedback drafts",id:"feedback-drafts",level:3},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"feedback-draft",children:"Feedback draft"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"When I reply to a feedback request or give spontaneous feedback, if I can't complete my feedback in one go, I'd like to be able to save it as a draft and continue later."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["The drafts are stored in the ",(0,c.jsx)(n.code,{children:"feedbackDraft"})," Firestore collection."]}),"\n",(0,c.jsxs)(n.p,{children:["In this collection, the document ID is the ",(0,c.jsx)(n.code,{children:"giverEmail"})," (who wrote and saved the draft), whether he is internal or external to the Zenika organisation."]}),"\n",(0,c.jsxs)(n.p,{children:["For a given ",(0,c.jsx)(n.code,{children:"giverEmail"}),", there can be 2 nested collections:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"feedbackRequest"}),": contains drafts saved when replying to a feedback request"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"feedback"}),": contains drafts saved when giving a spontaneous feedback"]}),"\n"]}),"\n",(0,c.jsxs)(n.h3,{id:"feedbackrequest-drafts",children:[(0,c.jsx)(n.code,{children:"feedbackRequest"})," drafts"]}),"\n",(0,c.jsxs)(n.p,{children:["In this collection, the document ID is the ",(0,c.jsx)(n.code,{children:"tokenId"})," and the document contains the following fields:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackRequestDraft: FeedbackRequestDraft = {\n token: '123secret', // Redondant data - same value as the document ID itself\n receiverEmail: 'pinochio@zenika.com', // Redondant data - already available in the original `FeedbackRequest` document\n\n // ----------------------------\n // The relevant data start here\n positive: 'You did great...', // Might be empty because its just a draft\n negative: '', // Might be empty...\n comment: '', // Might be empty...\n};\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["The redundant field ",(0,c.jsx)(n.code,{children:"receiverEmail"})," has been added to be able to display the list of drafts by recipient."]})}),"\n",(0,c.jsxs)(n.h3,{id:"feedback-drafts",children:[(0,c.jsx)(n.code,{children:"feedback"})," drafts"]}),"\n",(0,c.jsxs)(n.p,{children:["In this collection, the document ID is the ",(0,c.jsx)(n.code,{children:"receiverEmail"})," and the document contains the following fields:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",children:"const feedbackDraft: FeedbackDraft = {\n receiverEmail: 'pinochio@zenika.com', // Redondant data - same value as the document ID itself\n\n // ----------------------------\n // The relevant data start here\n positive: 'You did great...', // Might be empty because its just a draft\n negative: '', // Might be empty...\n comment: '', // Might be empty...\n shared: true,\n};\n"})}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-requested-feedback/give-requested-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"GiveRequestedFeedbackComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback-draft/give-feedback-draft.component.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackDraftComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/give-feedback/give-feedback/give-feedback-draft/give-feedback-draft.service.ts",children:(0,c.jsx)(n.code,{children:"GiveFeedbackDraftService"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"giveRequestedDraft"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"giveDraft"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(6540);const c={},a=t.createContext(c);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/e618cfd2.bfb1e00e.js b/docs/assets/js/e618cfd2.bfb1e00e.js new file mode 100644 index 00000000..c8644a67 --- /dev/null +++ b/docs/assets/js/e618cfd2.bfb1e00e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[5104],{1692:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"usage-analytics","title":"Usage analytics","description":"1. The plugin Stream Firestore to BigQuery streams every change in the firestore DB into a BigQuery table (including the user e-mails which are personal data, but the feedback itself is encrypted)","source":"@site/docs/usage-analytics.md","sourceDirName":".","slug":"/usage-analytics","permalink":"/feedzback/docs/usage-analytics","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/usage-analytics.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"CircleCI","permalink":"/feedzback/docs/ci-cd/circle-ci"},"next":{"title":"Client app","permalink":"/feedzback/docs/update/client"}}');var i=t(4848),o=t(8453);const a={},c="Usage analytics",r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installation",id:"installation",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"usage-analytics",children:"Usage analytics"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["The plugin ",(0,i.jsx)(n.em,{children:"Stream Firestore to BigQuery"})," streams every change in the firestore DB into a BigQuery table (including the user e-mails which are personal data, but the feedback itself is encrypted)"]}),"\n",(0,i.jsxs)(n.li,{children:["A Cloud function runs a query that aggregates data into another dataset called ",(0,i.jsx)(n.code,{children:"feedzback_usage"})," every day, removing personal data. Using a service account ",(0,i.jsx)(n.code,{children:"analytics-editor"})," that has access to all data in BQ"]}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.a,{href:"https://lookerstudio.google.com/s/mZFWci2C24Q",children:"Looker Studio report"})," query the tables from ",(0,i.jsx)(n.code,{children:"feedzback_usage"})," using a service-account ",(0,i.jsx)(n.code,{children:"analytics-viewer"})," which has access only to ",(0,i.jsx)(n.code,{children:"feedzback_usage"})," and does not have access to personal data."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"This document describes the installation instructions."})}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsx)(n.p,{children:"Be an owner of the project."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, find the zone of your Firestore database."}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"gcloud firestore databases list\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['Activate the plugin "',(0,i.jsx)(n.a,{href:"https://extensions.dev/extensions/firebase/firestore-bigquery-export",children:"Stream Firestore to BigQuery"}),'" in your project']}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["This will enable the APIs","\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"BigQuery API"}),"\n",(0,i.jsx)(n.li,{children:"Cloud Tasks API"}),"\n",(0,i.jsx)(n.li,{children:"Eventarc API"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["In the Configuration step, configure the extension as follow","\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Cloud functions location : Same as your firestore location (or closest if not available)"}),"\n",(0,i.jsxs)(n.li,{children:["BigQuery dataset location : Same as your firestore location (or closest if not available). Remember this as your ",(0,i.jsx)(n.code,{children:"$ANALYTICS_GCP_ZONE"})]}),"\n",(0,i.jsx)(n.li,{children:"Collection path : feedback"}),"\n",(0,i.jsx)(n.li,{children:"Dataset ID : firestore_export"}),"\n",(0,i.jsx)(n.li,{children:"Table ID : feedback"}),"\n",(0,i.jsxs)(n.li,{children:["Import existing Firestore documents into BigQuery ? : Yes (If you forgot to check it use ",(0,i.jsx)(n.a,{href:"https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md",children:"this"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Existing documents collection : feedback"}),"\n",(0,i.jsxs)(n.li,{children:["Leave other parameters as default, do not check ",(0,i.jsx)(n.code,{children:"Enable events"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"In Circle CI, go to the /Organization settings/Context page of your project and add the environment variable $ANALYTICS_GCP_ZONE ."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"In Cloud Shell, tell the shell where is your analytics zone"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# The zone of the existing firestore db. Due to a misconfiguration it is in Montreal for the dev environment.\nexport ANALYTICS_GCP_ZONE=""\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, Allow CircleCI to deploy Cloud functions. Every change in the function will be deployed the same way as the rest of the codebase."}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:circleci@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/cloudfunctions.developer"\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \\\n--member="serviceAccount:circleci@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \\\n--role="roles/iam.serviceAccountUser"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["Wait for the ",(0,i.jsx)(n.code,{children:"firestore_export"})," dataset to be created by the extension"]}),"\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, create the service accounts and the bigquery dataset"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# Create feedzback_usage that will only store non-personal data\nbq --location=$ANALYTICS_GCP_ZONE mk --dataset ${GOOGLE_CLOUD_PROJECT}:feedzback_usage\n\n\ngcloud iam service-accounts create analytics-editor --display-name="Service account to read or write analytics based on the firestore export"\ngcloud iam service-accounts create analytics-viewer --display-name="Service account dedicated to looker studio to allow it to read only feedzback_usage"\n\n# Allow analytics-editor to read and write on the firestore_export. It can be done in the web console or using the following lines\nbq show --format=prettyjson ${GOOGLE_CLOUD_PROJECT}:firestore_export > /tmp/firestore_export.json\njq \'.access += [{"role" : "READER", "userByEmail" : "analytics-editor@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"},{"role" : "WRITER", "userByEmail" : "analytics-editor@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"} ]\' /tmp/firestore_export.json > /tmp/firestore_export_updated.json\nbq update --source /tmp/firestore_export_updated.json firestore_export\n\n# Allow analytics-editor to use BQ\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:analytics-editor@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/bigquery.user"\n\n# Allow analytics-viewer to create queries in BQ\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:analytics-viewer@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/bigquery.user"\n\n# Modify feedzback_usage so it is owned by analytics-editor and readable by analytics-viewer\nbq show --format=prettyjson ${GOOGLE_CLOUD_PROJECT}:feedzback_usage > /tmp/feedzback_usage.json\njq \'.access += [{"role" : "READER", "userByEmail" : "analytics-viewer@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"},{"role" : "OWNER", "userByEmail" : "analytics-editor@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"}]\' /tmp/feedzback_usage.json > /tmp/feedzback_usage_updated.json\nbq update --source /tmp/feedzback_usage_updated.json feedzback_usage\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsx)(n.li,{children:"On your computer Create the tag for your revision and push it. The CI should deploy the cloud function"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git tag \ngit push --tags\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, configure Cloud Scheduler for a daily export. If it does not work make sure circle-ci has deployed the cloud function"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# If asked to enable cloudscheduler API, say yes\ngcloud scheduler jobs create http daily_usage_export \\\n--location=${ANALYTICS_GCP_ZONE} \\\n--schedule=\'0 0 * * *\' \\\n--uri "https://${ANALYTICS_GCP_ZONE}-${GOOGLE_CLOUD_PROJECT}.cloudfunctions.net/create-analytics" \\\n--http-method=POST \\\n--oidc-service-account-email="analytics-editor@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \\\n--oidc-token-audience="https://${ANALYTICS_GCP_ZONE}-${GOOGLE_CLOUD_PROJECT}.cloudfunctions.net/create-analytics"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"8",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://app.circleci.com/pipelines/github/Zenika/feedzback",children:"Wait for the CI"})," to have deployed the cloud function"]}),"\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, give the analytics-editor service account the rights to invoke cloud function. Then run it once once to initialize the database"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'gcloud functions add-invoker-policy-binding create-analytics --member="serviceAccount:analytics-editor@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --region="${ANALYTICS_GCP_ZONE}"\n\ngcloud functions call create-analytics --gen2 --region=${ANALYTICS_GCP_ZONE}\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"10",children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, grant looker studio the right to use service accounts to retrieve data"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# NB : the value of member can be found here : https://lookerstudio.google.com/serviceAgentHelp\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:service-org-506755999458@gcp-sa-datastudio.iam.gserviceaccount.com" --role="roles/iam.serviceAccountTokenCreator"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"11",children:["\n",(0,i.jsxs)(n.li,{children:["Modify ",(0,i.jsx)(n.a,{href:"https://lookerstudio.google.com/s/mZFWci2C24Q",children:"the looker studio report"})," to include your analysis. ",(0,i.jsxs)(n.strong,{children:["Make sure each datasource uses the service account ",(0,i.jsx)(n.code,{children:"analytics-viewer@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"})]}),". By default it uses your google account which has the owner rights."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>c});var s=t(6540);const i={},o=s.createContext(i);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/e618cfd2.eb0e1c88.js b/docs/assets/js/e618cfd2.eb0e1c88.js deleted file mode 100644 index 3ad3c67d..00000000 --- a/docs/assets/js/e618cfd2.eb0e1c88.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[104],{1692:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"usage-analytics","title":"Usage analytics","description":"1. The plugin Stream Firestore to BigQuery streams every change in the firestore DB into a BigQuery table (including the user e-mails which are personal data, but the feedback itself is encrypted)","source":"@site/docs/usage-analytics.md","sourceDirName":".","slug":"/usage-analytics","permalink":"/feedzback/docs/usage-analytics","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/usage-analytics.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"CircleCI","permalink":"/feedzback/docs/ci-cd/circle-ci"},"next":{"title":"Client app","permalink":"/feedzback/docs/update/client"}}');var i=t(4848),o=t(8453);const a={},c="Usage analytics",r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installation",id:"installation",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"usage-analytics",children:"Usage analytics"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["The plugin ",(0,i.jsx)(n.em,{children:"Stream Firestore to BigQuery"})," streams every change in the firestore DB into a BigQuery table (including the user e-mails which are personal data, but the feedback itself is encrypted)"]}),"\n",(0,i.jsxs)(n.li,{children:["A Cloud function runs a query that aggregates data into another dataset called ",(0,i.jsx)(n.code,{children:"feedzback_usage"})," every day, removing personal data. Using a service account ",(0,i.jsx)(n.code,{children:"analytics-editor"})," that has access to all data in BQ"]}),"\n",(0,i.jsxs)(n.li,{children:["A ",(0,i.jsx)(n.a,{href:"https://lookerstudio.google.com/s/mZFWci2C24Q",children:"Looker Studio report"})," query the tables from ",(0,i.jsx)(n.code,{children:"feedzback_usage"})," using a service-account ",(0,i.jsx)(n.code,{children:"analytics-viewer"})," which has access only to ",(0,i.jsx)(n.code,{children:"feedzback_usage"})," and does not have access to personal data."]}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"This document describes the installation instructions."})}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsx)(n.p,{children:"Be an owner of the project."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, find the zone of your Firestore database."}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"gcloud firestore databases list\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['Activate the plugin "',(0,i.jsx)(n.a,{href:"https://extensions.dev/extensions/firebase/firestore-bigquery-export",children:"Stream Firestore to BigQuery"}),'" in your project']}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["This will enable the APIs","\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"BigQuery API"}),"\n",(0,i.jsx)(n.li,{children:"Cloud Tasks API"}),"\n",(0,i.jsx)(n.li,{children:"Eventarc API"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["In the Configuration step, configure the extension as follow","\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Cloud functions location : Same as your firestore location (or closest if not available)"}),"\n",(0,i.jsxs)(n.li,{children:["BigQuery dataset location : Same as your firestore location (or closest if not available). Remember this as your ",(0,i.jsx)(n.code,{children:"$ANALYTICS_GCP_ZONE"})]}),"\n",(0,i.jsx)(n.li,{children:"Collection path : feedback"}),"\n",(0,i.jsx)(n.li,{children:"Dataset ID : firestore_export"}),"\n",(0,i.jsx)(n.li,{children:"Table ID : feedback"}),"\n",(0,i.jsxs)(n.li,{children:["Import existing Firestore documents into BigQuery ? : Yes (If you forgot to check it use ",(0,i.jsx)(n.a,{href:"https://github.com/firebase/extensions/blob/master/firestore-bigquery-export/guides/IMPORT_EXISTING_DOCUMENTS.md",children:"this"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Existing documents collection : feedback"}),"\n",(0,i.jsxs)(n.li,{children:["Leave other parameters as default, do not check ",(0,i.jsx)(n.code,{children:"Enable events"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"In Circle CI, go to the /Organization settings/Context page of your project and add the environment variable $ANALYTICS_GCP_ZONE ."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"In Cloud Shell, tell the shell where is your analytics zone"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# The zone of the existing firestore db. Due to a misconfiguration it is in Montreal for the dev environment.\nexport ANALYTICS_GCP_ZONE=""\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, Allow CircleCI to deploy Cloud functions. Every change in the function will be deployed the same way as the rest of the codebase."}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:circleci@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/cloudfunctions.developer"\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \\\n--member="serviceAccount:circleci@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \\\n--role="roles/iam.serviceAccountUser"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["Wait for the ",(0,i.jsx)(n.code,{children:"firestore_export"})," dataset to be created by the extension"]}),"\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, create the service accounts and the bigquery dataset"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# Create feedzback_usage that will only store non-personal data\nbq --location=$ANALYTICS_GCP_ZONE mk --dataset ${GOOGLE_CLOUD_PROJECT}:feedzback_usage\n\n\ngcloud iam service-accounts create analytics-editor --display-name="Service account to read or write analytics based on the firestore export"\ngcloud iam service-accounts create analytics-viewer --display-name="Service account dedicated to looker studio to allow it to read only feedzback_usage"\n\n# Allow analytics-editor to read and write on the firestore_export. It can be done in the web console or using the following lines\nbq show --format=prettyjson ${GOOGLE_CLOUD_PROJECT}:firestore_export > /tmp/firestore_export.json\njq \'.access += [{"role" : "READER", "userByEmail" : "analytics-editor@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"},{"role" : "WRITER", "userByEmail" : "analytics-editor@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"} ]\' /tmp/firestore_export.json > /tmp/firestore_export_updated.json\nbq update --source /tmp/firestore_export_updated.json firestore_export\n\n# Allow analytics-editor to use BQ\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:analytics-editor@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/bigquery.user"\n\n# Allow analytics-viewer to create queries in BQ\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:analytics-viewer@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/bigquery.user"\n\n# Modify feedzback_usage so it is owned by analytics-editor and readable by analytics-viewer\nbq show --format=prettyjson ${GOOGLE_CLOUD_PROJECT}:feedzback_usage > /tmp/feedzback_usage.json\njq \'.access += [{"role" : "READER", "userByEmail" : "analytics-viewer@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"},{"role" : "OWNER", "userByEmail" : "analytics-editor@\'${GOOGLE_CLOUD_PROJECT}\'.iam.gserviceaccount.com"}]\' /tmp/feedzback_usage.json > /tmp/feedzback_usage_updated.json\nbq update --source /tmp/feedzback_usage_updated.json feedzback_usage\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsx)(n.li,{children:"On your computer Create the tag for your revision and push it. The CI should deploy the cloud function"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"git tag \ngit push --tags\n"})}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, configure Cloud Scheduler for a daily export. If it does not work make sure circle-ci has deployed the cloud function"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# If asked to enable cloudscheduler API, say yes\ngcloud scheduler jobs create http daily_usage_export \\\n--location=${ANALYTICS_GCP_ZONE} \\\n--schedule=\'0 0 * * *\' \\\n--uri "https://${ANALYTICS_GCP_ZONE}-${GOOGLE_CLOUD_PROJECT}.cloudfunctions.net/create-analytics" \\\n--http-method=POST \\\n--oidc-service-account-email="analytics-editor@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \\\n--oidc-token-audience="https://${ANALYTICS_GCP_ZONE}-${GOOGLE_CLOUD_PROJECT}.cloudfunctions.net/create-analytics"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"8",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"https://app.circleci.com/pipelines/github/Zenika/feedzback",children:"Wait for the CI"})," to have deployed the cloud function"]}),"\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, give the analytics-editor service account the rights to invoke cloud function. Then run it once once to initialize the database"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'gcloud functions add-invoker-policy-binding create-analytics --member="serviceAccount:analytics-editor@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --region="${ANALYTICS_GCP_ZONE}"\n\ngcloud functions call create-analytics --gen2 --region=${ANALYTICS_GCP_ZONE}\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"10",children:["\n",(0,i.jsx)(n.li,{children:"In Cloud Shell, grant looker studio the right to use service accounts to retrieve data"}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'# NB : the value of member can be found here : https://lookerstudio.google.com/serviceAgentHelp\ngcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:service-org-506755999458@gcp-sa-datastudio.iam.gserviceaccount.com" --role="roles/iam.serviceAccountTokenCreator"\n'})}),"\n",(0,i.jsxs)(n.ol,{start:"11",children:["\n",(0,i.jsxs)(n.li,{children:["Modify ",(0,i.jsx)(n.a,{href:"https://lookerstudio.google.com/s/mZFWci2C24Q",children:"the looker studio report"})," to include your analysis. ",(0,i.jsxs)(n.strong,{children:["Make sure each datasource uses the service account ",(0,i.jsx)(n.code,{children:"analytics-viewer@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"})]}),". By default it uses your google account which has the owner rights."]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>c});var s=t(6540);const i={},o=s.createContext(i);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/f13cb29e.7108a97f.js b/docs/assets/js/f13cb29e.7108a97f.js new file mode 100644 index 00000000..7653f8c2 --- /dev/null +++ b/docs/assets/js/f13cb29e.7108a97f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[2748],{7018:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"technical-guides/e2e-testing","title":"E2E testing","description":"E2E tests are performed using Playwright.","source":"@site/docs/technical-guides/e2e-testing.md","sourceDirName":"technical-guides","slug":"/technical-guides/e2e-testing","permalink":"/feedzback/docs/technical-guides/e2e-testing","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/e2e-testing.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Swagger","permalink":"/feedzback/docs/technical-guides/server/swagger"},"next":{"title":"Quick start","permalink":"/feedzback/docs/ci-cd/quick-start"}}');var r=t(4848),s=t(8453);const a={},o="E2E testing",c={},l=[{value:"NPM scripts",id:"npm-scripts",level:2},{value:"Playwright configuration",id:"playwright-configuration",level:2},{value:"Running Playwright",id:"running-playwright",level:2},{value:"Method 1",id:"method-1",level:3},{value:"Method 2",id:"method-2",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"e2e-testing",children:"E2E testing"})}),"\n",(0,r.jsxs)(n.p,{children:["E2E tests are performed using ",(0,r.jsx)(n.a,{href:"https://playwright.dev/",children:"Playwright"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"npm-scripts",children:"NPM scripts"}),"\n",(0,r.jsxs)(n.p,{children:["To run the tests, open a terminal in ",(0,r.jsx)(n.code,{children:"/client"})," directory and run the following command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run e2e:test\n"})}),"\n",(0,r.jsxs)(n.p,{children:["All scripts related to E2E tests start with ",(0,r.jsx)(n.code,{children:'"e2e:*"'}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",metastring:'title="/client/package.json"',children:'{\n "scripts": {\n "e2e:test": "playwright test",\n "e2e:report": "playwright show-report",\n "e2e:ui": "playwright test --ui",\n "e2e:codegen": "playwright codegen"\n }\n}\n'})}),"\n",(0,r.jsx)(n.h2,{id:"playwright-configuration",children:"Playwright configuration"}),"\n",(0,r.jsx)(n.p,{children:"Here's part of the Playwright configuration:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",metastring:'title="/client/playwright.config.ts"',children:"import { defineConfig } from '@playwright/test';\n\nexport default defineConfig({\n // Tests are located in the following directory\n testDir: './e2e',\n\n // Run your local dev server before starting the tests\n webServer: {\n command: 'npm run stack:e2e',\n port: 4200,\n reuseExistingServer: !process.env['CI'],\n },\n});\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Before starting the tests, Playwright executes the command ",(0,r.jsx)(n.code,{children:"npm run stack:e2e"})," and waits for the application to be available on port ",(0,r.jsx)(n.code,{children:"4200"}),".\nDue to the ",(0,r.jsx)(n.code,{children:"reuseExistingServer"})," option (enabled for non-CI environment), the command will not be executed if the application is already available."]}),"\n",(0,r.jsxs)(n.p,{children:["Therefore, you can run the command ",(0,r.jsx)(n.code,{children:"npm run stack:e2e"})," in one terminal, wait for the application to be available on port ",(0,r.jsx)(n.code,{children:"4200"}),", and then run the command ",(0,r.jsx)(n.code,{children:"npm run e2e:test"})," in another terminal.\nIn this case, Playwright will skip the ",(0,r.jsx)(n.code,{children:"webServer.command"}),", starting the tests immediately."]}),"\n",(0,r.jsx)(n.h2,{id:"running-playwright",children:"Running Playwright"}),"\n",(0,r.jsx)(n.h3,{id:"method-1",children:"Method 1"}),"\n",(0,r.jsx)(n.p,{children:"To have Playwright start the app and the tests, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run e2e:test\n"})}),"\n",(0,r.jsxs)(n.admonition,{type:"warning",children:[(0,r.jsxs)(n.p,{children:["At the end of the tests, Playwright may not stop the ",(0,r.jsx)(n.code,{children:"webServer"}),' properly.\nIf this happens, look for a "ghost" process named ',(0,r.jsx)(n.code,{children:"java"})," and kill it manually."]}),(0,r.jsx)(n.p,{children:"To avoid this problem, use the method 2 instead."})]}),"\n",(0,r.jsx)(n.h3,{id:"method-2",children:"Method 2"}),"\n",(0,r.jsx)(n.p,{children:"To start the app once and then have Playwright only start the tests, run the following commands in two separate terminals:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run stack:e2e # First terminal\n"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"npm run e2e:test # Second terminal\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsxs)(n.p,{children:["As an alternative to the above command in the first terminal, run ",(0,r.jsx)(n.code,{children:"npm run stack:emulators"}),' instead, to start the app in "watch" mode.']})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(6540);const r={},s=i.createContext(r);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/f427953d.807b981f.js b/docs/assets/js/f427953d.807b981f.js new file mode 100644 index 00000000..a13d8fad --- /dev/null +++ b/docs/assets/js/f427953d.807b981f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[5407],{947:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"business-cases/archiving","title":"Archiving","description":"User story","source":"@site/docs/business-cases/archiving.md","sourceDirName":"business-cases","slug":"/business-cases/archiving","permalink":"/feedzback/docs/business-cases/archiving","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/archiving.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Shared feedback","permalink":"/feedzback/docs/business-cases/shared-feedback"},"next":{"title":"Ubiquitous language","permalink":"/feedzback/docs/ubiquitous-language"}}');var c=s(4848),r=s(8453);const t={},a="Archiving",d={},o=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"archiving",children:"Archiving"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"After a month, I'd like to be able to archive a feedback request that has not been replied.\nOnce archived, the feedback request can no longer be replied."}),"\n",(0,c.jsx)(n.p,{children:"I'd like to be able to archive the feedbacks I've received or sent after reading them."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["Archived feedback should not simply be deleted from the database, as they are used for statistical purposes.\nInstead, there is an ",(0,c.jsx)(n.code,{children:"archived"})," field in the each feedback."]}),"\n",(0,c.jsxs)(n.p,{children:["The difficulty is that the feedback document is shared between the ",(0,c.jsx)(n.code,{children:"giverEmail"})," and the ",(0,c.jsx)(n.code,{children:"receiverEmail"}),".\nAs a result, the ",(0,c.jsx)(n.code,{children:"archived"})," field cannot be a simple boolean.\nInstead, this field has a numeric value with the following meaning:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",metastring:'title="server/src/feedback/feedback-db/feedback-db.types.ts"',children:"// Explanation of possible values for field `Feedback['archived']`:\n// == 0 -> archived for no-one\n// == 1 -> archived for the receiver\n// == 2 -> archived for the giver\n// == 3 -> archived for both the receiver and the giver\n\nexport const FeedbackArchived = {\n No: 0,\n Receiver: 1,\n Giver: 2,\n Both: 3,\n} as const;\n"})}),"\n",(0,c.jsx)(n.p,{children:'To archive a feedback (requested, given or received), i have to click on the button "Archive" in the feedback details page:'}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-txt",children:"/history/id/\n"})}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/feedback-details/feedback-details.component.ts",children:(0,c.jsx)(n.code,{children:"FeedbackDetailsComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/shared/feedback/pending-feedback/pending-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"PendingFeedbackComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/shared/feedback/done-feedback/done-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"DoneFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"archive-request"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"archive"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var i=s(6540);const c={},r=i.createContext(c);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/f427953d.d47a0edd.js b/docs/assets/js/f427953d.d47a0edd.js deleted file mode 100644 index 6cf4044d..00000000 --- a/docs/assets/js/f427953d.d47a0edd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[407],{947:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>i,toc:()=>o});const i=JSON.parse('{"id":"business-cases/archiving","title":"Archiving","description":"User story","source":"@site/docs/business-cases/archiving.md","sourceDirName":"business-cases","slug":"/business-cases/archiving","permalink":"/feedzback/docs/business-cases/archiving","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/business-cases/archiving.md","tags":[],"version":"current","frontMatter":{},"sidebar":"default","previous":{"title":"Shared feedback","permalink":"/feedzback/docs/business-cases/shared-feedback"},"next":{"title":"Ubiquitous language","permalink":"/feedzback/docs/ubiquitous-language"}}');var c=s(4848),r=s(8453);const t={},a="Archiving",d={},o=[{value:"User story",id:"user-story",level:2},{value:"Technical specifications",id:"technical-specifications",level:2},{value:"Links",id:"links",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"archiving",children:"Archiving"})}),"\n",(0,c.jsx)(n.h2,{id:"user-story",children:"User story"}),"\n",(0,c.jsx)(n.p,{children:"After a month, I'd like to be able to archive a feedback request that has not been replied.\nOnce archived, the feedback request can no longer be replied."}),"\n",(0,c.jsx)(n.p,{children:"I'd like to be able to archive the feedbacks I've received or sent after reading them."}),"\n",(0,c.jsx)(n.h2,{id:"technical-specifications",children:"Technical specifications"}),"\n",(0,c.jsxs)(n.p,{children:["Archived feedback should not simply be deleted from the database, as they are used for statistical purposes.\nInstead, there is an ",(0,c.jsx)(n.code,{children:"archived"})," field in the each feedback."]}),"\n",(0,c.jsxs)(n.p,{children:["The difficulty is that the feedback document is shared between the ",(0,c.jsx)(n.code,{children:"giverEmail"})," and the ",(0,c.jsx)(n.code,{children:"receiverEmail"}),".\nAs a result, the ",(0,c.jsx)(n.code,{children:"archived"})," field cannot be a simple boolean.\nInstead, this field has a numeric value with the following meaning:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-ts",metastring:'title="server/src/feedback/feedback-db/feedback-db.types.ts"',children:"// Explanation of possible values for field `Feedback['archived']`:\n// == 0 -> archived for no-one\n// == 1 -> archived for the receiver\n// == 2 -> archived for the giver\n// == 3 -> archived for both the receiver and the giver\n\nexport const FeedbackArchived = {\n No: 0,\n Receiver: 1,\n Giver: 2,\n Both: 3,\n} as const;\n"})}),"\n",(0,c.jsx)(n.p,{children:'To archive a feedback (requested, given or received), i have to click on the button "Archive" in the feedback details page:'}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-txt",children:"/history/id/\n"})}),"\n",(0,c.jsx)(n.h2,{id:"links",children:"Links"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Client"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/feedback-details/feedback-details.component.ts",children:(0,c.jsx)(n.code,{children:"FeedbackDetailsComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/shared/feedback/pending-feedback/pending-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"PendingFeedbackComponent"})})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/client/src/app/shared/feedback/done-feedback/done-feedback.component.ts",children:(0,c.jsx)(n.code,{children:"DoneFeedbackComponent"})})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.strong,{children:"Server"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/Zenika/feedzback/blob/main/server/src/feedback/feedback.controller.ts",children:(0,c.jsx)(n.code,{children:"FeedbackController"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"archive-request"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"archive"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>a});var i=s(6540);const c={},r=i.createContext(c);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/f71db62a.cf52463b.js b/docs/assets/js/f71db62a.cf52463b.js new file mode 100644 index 00000000..ed29e84c --- /dev/null +++ b/docs/assets/js/f71db62a.cf52463b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[4930],{149:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"technical-guides/environments/local-dev","title":"Local dev","description":"As explained in the installation guide, you can run the client and server apps locally, for development purposes.","source":"@site/docs/technical-guides/environments/local-dev.md","sourceDirName":"technical-guides/environments","slug":"/technical-guides/environments/local-dev","permalink":"/feedzback/docs/technical-guides/environments/local-dev","draft":false,"unlisted":false,"editUrl":"https://github.com/Zenika/feedzback/tree/main/docs-source/docs/technical-guides/environments/local-dev.md","tags":[],"version":"current","frontMatter":{"title":"Local dev"},"sidebar":"default","previous":{"title":"Overview","permalink":"/feedzback/docs/technical-guides/environments/overview"},"next":{"title":"Firebase Hosting","permalink":"/feedzback/docs/technical-guides/client/firebase-hosting"}}');var s=t(4848),i=t(8453);const o={title:"Local dev"},a="Local dev environment",c={},l=[{value:"*:emulators scripts",id:"emulators-scripts",level:2},{value:"*:e2e scripts",id:"e2e-scripts",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"local-dev-environment",children:"Local dev environment"})}),"\n",(0,s.jsxs)(n.p,{children:["As explained in the ",(0,s.jsx)(n.a,{href:"/docs/installation",children:"installation guide"}),", you can run the ",(0,s.jsx)(n.em,{children:"client"})," and ",(0,s.jsx)(n.em,{children:"server"})," apps locally, for development purposes.\nBut you are still connecting to the remote ",(0,s.jsx)(n.code,{children:"feedzback-v2-dev"})," Firebase project for Authentication and Firestore services."]}),"\n",(0,s.jsxs)(n.p,{children:["The good news is that you can run the entire stack locally, using the ",(0,s.jsx)(n.a,{href:"https://firebase.google.com/docs/emulator-suite",children:"Firebase emulator suite"}),"!"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["All scripts related to Firebase emulator can be found in the ",(0,s.jsx)(n.code,{children:"/client/package.json"})," file."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsx)(n.p,{children:"When using the Firebase emulator, the Google Auth provider is no longer available.\nOnly the Email/Password provider is enabled."})}),"\n",(0,s.jsxs)(n.h2,{id:"emulators-scripts",children:[(0,s.jsx)(n.code,{children:"*:emulators"})," scripts"]}),"\n",(0,s.jsxs)(n.p,{children:["In this execution context, the ",(0,s.jsx)(n.em,{children:"client"})," and ",(0,s.jsx)(n.em,{children:"server"}),' apps are running in "watch" mode.']}),"\n",(0,s.jsxs)(n.p,{children:["Only the Firebase ",(0,s.jsx)(n.em,{children:"Auth"})," and ",(0,s.jsx)(n.em,{children:"Firestore"})," emulators are started. The ",(0,s.jsx)(n.em,{children:"Hosting"})," emulator is not used in this context."]}),"\n",(0,s.jsx)(n.p,{children:"Here are the NPM scripts for this execution context:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:'title="/client/package.json"',children:'{\n "scripts": {\n // Start Firebase "Auth" and "Firestore" emulators\n "firebase:emulators": "firebase emulators:start --only auth:dev,firestore:dev --import ./firebase-emulators-data",\n\n // Start the server app in "watch" mode\n "server:emulators": "npm --prefix ../server run start:emulators",\n\n // Start the client app in "watch" mode\n "start:emulators": "ng serve -c development-emulators",\n\n // ----------------------------------------\n // Run all the previous scripts in parallel\n "stack:emulators": "concurrently \\"npm run firebase:emulators\\" \\"npm run server:emulators\\" \\"npm run start:emulators\\""\n }\n}\n'})}),"\n",(0,s.jsxs)(n.h2,{id:"e2e-scripts",children:[(0,s.jsx)(n.code,{children:"*:e2e"})," scripts"]}),"\n",(0,s.jsxs)(n.p,{children:["In this execution context, the ",(0,s.jsx)(n.em,{children:"client"})," and ",(0,s.jsx)(n.em,{children:"server"})," apps are built before running."]}),"\n",(0,s.jsxs)(n.p,{children:["This time, not only are the Firebase ",(0,s.jsx)(n.em,{children:"Auth"})," and ",(0,s.jsx)(n.em,{children:"Firestore"})," emulators started, but so is the ",(0,s.jsx)(n.em,{children:"Hosting"})," emulator that serves the client app.\nTherefore, the client app must be built beforehand, to be available in the ",(0,s.jsx)(n.code,{children:"/client/dist/browser"})," directory."]}),"\n",(0,s.jsxs)(n.p,{children:["This environment is the closest to the production environment (with the exception of the authentication method) and is therefore ideal for ",(0,s.jsx)(n.a,{href:"/docs/technical-guides/e2e-testing",children:"E2E testing"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Here are the NPM scripts for this execution context:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:'title="/client/package.json"',children:'{\n "scripts": {\n // Start Firebase "Auth", "Firestore" and "Hosting" emulators\n "firebase:e2e": "firebase emulators:start --only auth:dev,firestore:dev,hosting:dev --import ./firebase-emulators-data",\n\n // Build and start the server app (see "/server/package.json" scripts for details)\n "server:e2e": "npm --prefix ../server run start:e2e",\n\n // Only build the client app (it will be served by Firebase "Hosting")\n "prestack:e2e": "npm run build:e2e",\n\n // ----------------------------------------\n // Run all the previous scripts in parallel\n "stack:e2e": "concurrently \\"npm run firebase:e2e\\" \\"npm run server:e2e\\""\n }\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var r=t(6540);const s={},i=r.createContext(s);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/main.1583c06c.js b/docs/assets/js/main.1583c06c.js new file mode 100644 index 00000000..ce47f37b --- /dev/null +++ b/docs/assets/js/main.1583c06c.js @@ -0,0 +1,2 @@ +/*! For license information please see main.1583c06c.js.LICENSE.txt */ +(self.webpackChunkfeedzback_docs=self.webpackChunkfeedzback_docs||[]).push([[8792],{8328:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});n(6540);var r=n(3259),a=n.n(r),o=n(4054);const i={"1379c009":[()=>n.e(8931).then(n.bind(n,6872)),"@site/docs/business-cases/shared-feedback.md",6872],15415093:[()=>n.e(7595).then(n.bind(n,2607)),"@site/docs/audience.md",2607],17896441:[()=>Promise.all([n.e(1869),n.e(8554),n.e(8401)]).then(n.bind(n,575)),"@theme/DocItem",575],"182d926d":[()=>n.e(6089).then(n.bind(n,7193)),"@site/docs/business-cases/give-spontaneous-feedback.md",7193],"184f8cc3":[()=>n.e(9135).then(n.bind(n,1504)),"@site/docs/business-cases/request-feedback.md",1504],"1ccd811d":[()=>n.e(3464).then(n.bind(n,5528)),"@site/docs/ubiquitous-language.md",5528],"296d963c":[()=>n.e(8429).then(n.bind(n,4624)),"@site/docs/technical-guides/client/demo.md",4624],"33a49de8":[()=>n.e(3842).then(n.bind(n,4479)),"@site/docs/technical-guides/server/swagger.md",4479],"36994c47":[()=>n.e(9858).then(n.t.bind(n,5516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",5516],"36f2e543":[()=>n.e(2137).then(n.bind(n,1572)),"@site/docs/ci-cd/quick-start.md",1572],"3b8c55ea":[()=>n.e(6803).then(n.bind(n,7248)),"@site/docs/installation.md",7248],"470ecfa7":[()=>n.e(238).then(n.bind(n,8280)),"@site/docs/technical-guides/environments/overview.md",8280],"47caca0e":[()=>n.e(905).then(n.bind(n,1357)),"@site/docs/technical-guides/client/cookies.md",1357],"4a707512":[()=>n.e(6102).then(n.bind(n,5931)),"@site/docs/ci-cd/circle-ci.md",5931],"4f3f1eb6":[()=>n.e(3136).then(n.bind(n,2305)),"@site/blog/2024-03-11-starting-documentation.md?truncated=true",2305],"5656e821":[()=>n.e(4939).then(n.bind(n,446)),"@site/docs/technical-guides/client/i18n.md",446],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"621db11d":[()=>Promise.all([n.e(1869),n.e(1531),n.e(4212)]).then(n.bind(n,8790)),"@theme/Blog/Pages/BlogAuthorsListPage",8790],"634558fb":[()=>n.e(2172).then(n.bind(n,2252)),"@site/docs/business-cases/reply-to-feedback-request.md",2252],"6c28a435":[()=>n.e(4347).then(n.t.bind(n,4248,19)),"@generated/docusaurus-plugin-content-docs/default/p/feedzback-docs-26a.json",4248],"6e9c3c91":[()=>n.e(7368).then(n.t.bind(n,8317,19)),"@generated/docusaurus-plugin-content-blog/default/p/feedzback-blog-archive-070.json",8317],75212946:[()=>n.e(9317).then(n.bind(n,5551)),"@site/blog/2024-03-11-starting-documentation.md",5551],"7ab81c4a":[()=>n.e(2852).then(n.bind(n,4718)),"@site/docs/documentation.md",4718],"814f3328":[()=>n.e(7472).then(n.t.bind(n,5513,19)),"~blog/default/blog-post-list-prop-default.json",5513],"94f84f1b":[()=>n.e(9441).then(n.bind(n,4886)),"@site/docs/technical-stack.md",4886],"9e4087bc":[()=>n.e(2711).then(n.bind(n,9331)),"@theme/BlogArchivePage",9331],"9f796194":[()=>n.e(5602).then(n.bind(n,8726)),"@site/docs/technical-guides/client/firebase-hosting.md",8726],a55ba532:[()=>n.e(6097).then(n.t.bind(n,1498,19)),"@generated/docusaurus-plugin-content-blog/default/p/feedzback-blog-46c.json",1498],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(8554),n.e(1531),n.e(7643)]).then(n.bind(n,2052)),"@theme/BlogListPage",2052],a7456010:[()=>n.e(1235).then(n.t.bind(n,8552,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",8552],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,1723)),"@theme/DocVersionRoot",1723],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,1377)),"@theme/DocRoot",1377],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,7093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",7093],acecf23e:[()=>n.e(1903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],b92ecb7a:[()=>n.e(516).then(n.bind(n,1622)),"@site/docs/update/client.md",1622],c25608c0:[()=>n.e(3144).then(n.bind(n,5703)),"@site/docs/technical-guides/client/icons.md",5703],c4f5d8e4:[()=>Promise.all([n.e(1869),n.e(2634)]).then(n.bind(n,1459)),"@site/src/pages/index.js",1459],c5702bff:[()=>n.e(7990).then(n.bind(n,4008)),"@site/docs/technical-guides/client/styles.md",4008],ccc49370:[()=>Promise.all([n.e(1869),n.e(8554),n.e(1531),n.e(3249)]).then(n.bind(n,3858)),"@theme/BlogPostPage",3858],dfa15f88:[()=>n.e(6314).then(n.t.bind(n,2062,19)),"@generated/docusaurus-plugin-content-blog/default/p/feedzback-blog-authors-95d.json",2062],e327052b:[()=>n.e(4187).then(n.bind(n,2455)),"@site/docs/business-cases/feedback-draft.md",2455],e618cfd2:[()=>n.e(5104).then(n.bind(n,1692)),"@site/docs/usage-analytics.md",1692],f13cb29e:[()=>n.e(2748).then(n.bind(n,7018)),"@site/docs/technical-guides/e2e-testing.md",7018],f427953d:[()=>n.e(5407).then(n.bind(n,947)),"@site/docs/business-cases/archiving.md",947],f71db62a:[()=>n.e(4930).then(n.bind(n,149)),"@site/docs/technical-guides/environments/local-dev.md",149]};var l=n(4848);function s(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,l.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,l.jsx)("p",{children:String(t)}),(0,l.jsx)("div",{children:(0,l.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,l.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,l.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,l.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,l.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,l.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,l.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,l.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(6921),u=n(3102);function d(e,t){if("*"===e)return a()({loading:s,loader:()=>n.e(2237).then(n.bind(n,2237)),modules:["@theme/NotFound"],webpack:()=>[2237],render(e,t){const n=e.default;return(0,l.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,l.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},f=[],p=[],h=(0,c.A)(r);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],f.push(r[1]),p.push(r[2]))})),a().Map({loading:s,loader:d,modules:f,webpack:()=>p,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const l=n.split(".");l.slice(0,-1).forEach((e=>{i=i[e]})),i[l[l.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;delete a.__context;const s=a.__props;return delete a.__props,(0,l.jsx)(u.W,{value:i,children:(0,l.jsx)(o,{...a,...s,...n})})}})}const f=[{path:"/feedzback/blog",component:d("/feedzback/blog","1c3"),exact:!0},{path:"/feedzback/blog/archive",component:d("/feedzback/blog/archive","412"),exact:!0},{path:"/feedzback/blog/authors",component:d("/feedzback/blog/authors","a24"),exact:!0},{path:"/feedzback/blog/starting-documentation",component:d("/feedzback/blog/starting-documentation","ac2"),exact:!0},{path:"/feedzback/docs",component:d("/feedzback/docs","a6c"),routes:[{path:"/feedzback/docs",component:d("/feedzback/docs","4e6"),routes:[{path:"/feedzback/docs",component:d("/feedzback/docs","572"),routes:[{path:"/feedzback/docs/audience",component:d("/feedzback/docs/audience","b9e"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/business-cases/archiving",component:d("/feedzback/docs/business-cases/archiving","f7d"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/business-cases/feedback-draft",component:d("/feedzback/docs/business-cases/feedback-draft","e3a"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/business-cases/give-spontaneous-feedback",component:d("/feedzback/docs/business-cases/give-spontaneous-feedback","ac0"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/business-cases/reply-to-feedback-request",component:d("/feedzback/docs/business-cases/reply-to-feedback-request","2ce"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/business-cases/request-feedback",component:d("/feedzback/docs/business-cases/request-feedback","f64"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/business-cases/shared-feedback",component:d("/feedzback/docs/business-cases/shared-feedback","3c8"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/ci-cd/circle-ci",component:d("/feedzback/docs/ci-cd/circle-ci","4b3"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/ci-cd/quick-start",component:d("/feedzback/docs/ci-cd/quick-start","ea4"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/documentation",component:d("/feedzback/docs/documentation","a06"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/installation",component:d("/feedzback/docs/installation","393"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/client/cookies",component:d("/feedzback/docs/technical-guides/client/cookies","ee2"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/client/demo",component:d("/feedzback/docs/technical-guides/client/demo","1ce"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/client/firebase-hosting",component:d("/feedzback/docs/technical-guides/client/firebase-hosting","e18"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/client/i18n",component:d("/feedzback/docs/technical-guides/client/i18n","2b3"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/client/icons",component:d("/feedzback/docs/technical-guides/client/icons","daf"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/client/styles",component:d("/feedzback/docs/technical-guides/client/styles","365"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/e2e-testing",component:d("/feedzback/docs/technical-guides/e2e-testing","b7e"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/environments/local-dev",component:d("/feedzback/docs/technical-guides/environments/local-dev","931"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/environments/overview",component:d("/feedzback/docs/technical-guides/environments/overview","0f9"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-guides/server/swagger",component:d("/feedzback/docs/technical-guides/server/swagger","55f"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/technical-stack",component:d("/feedzback/docs/technical-stack","ed3"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/ubiquitous-language",component:d("/feedzback/docs/ubiquitous-language","129"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/update/client",component:d("/feedzback/docs/update/client","bc6"),exact:!0,sidebar:"default"},{path:"/feedzback/docs/usage-analytics",component:d("/feedzback/docs/usage-analytics","741"),exact:!0,sidebar:"default"}]}]}]},{path:"/feedzback/",component:d("/feedzback/","c84"),exact:!0},{path:"*",component:d("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>o,x:()=>i});var r=n(6540),a=n(4848);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},7815:(e,t,n)=>{"use strict";var r=n(6540),a=n(5338),o=n(545),i=n(4625),l=n(4784),s=n(8193);const c=[n(119),n(6134),n(6294),n(1043)];var u=n(8328),d=n(6347),f=n(2831),p=n(4848);function h(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var g=n(5260),m=n(4586),b=n(6025),y=n(6342),v=n(1213),k=n(2131),w=n(4090);const x="default";var S=n(440),E=n(1463);function _(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,m.A)(),r=(0,k.o)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(g.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function C(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,m.A)(),{pathname:r}=(0,d.zy)();return e+(0,S.Ks)((0,b.Ay)(r),{trailingSlash:n,baseUrl:t})}(),a=t?`${n}${t}`:r;return(0,p.jsxs)(g.A,{children:[(0,p.jsx)("meta",{property:"og:url",content:a}),(0,p.jsx)("link",{rel:"canonical",href:a})]})}function A(){const{i18n:{currentLocale:e}}=(0,m.A)(),{metadata:t,image:n}=(0,y.p)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(g.A,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:w.w})]}),n&&(0,p.jsx)(v.be,{image:n}),(0,p.jsx)(C,{}),(0,p.jsx)(_,{}),(0,p.jsx)(E.A,{tag:x,locale:e}),(0,p.jsx)(g.A,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;var N=n(6125),O=n(6988),P=n(205);function j(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const L=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,P.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),j("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function R(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,f.u)(u.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.A.canUseDOM?j("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=j("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),R(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(L,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(d.qh,{location:t,render:()=>e})})}}const z=I,D="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",M="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${D}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}((0,d.zy)());return(0,p.jsx)(z,{location:e,children:G})}function K(){return(0,p.jsx)(V.A,{children:(0,p.jsx)(O.l,{children:(0,p.jsxs)(N.x,{children:[(0,p.jsxs)(h,{children:[(0,p.jsx)(H,{}),(0,p.jsx)(A,{}),(0,p.jsx)(U,{}),(0,p.jsx)(Y,{})]}),(0,p.jsx)(q,{})]})})})}var Q=n(4054);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var X=n(6921);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,f.u)(u.A,e).flatMap((e=>{return t=e.route.path,Object.entries(Q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,X.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),R(e))},re=Object.freeze(ne);function ae(e){let{children:t}=e;return"hash"===l.default.future.experimental_router?(0,p.jsx)(i.I9,{children:t}):(0,p.jsx)(i.Kd,{children:t})}const oe=Boolean(!0);if(s.A.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(o.vd,{children:(0,p.jsx)(ae,{children:(0,p.jsx)(K,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(oe)window.docusaurusRoot=a.hydrateRoot(e,t,{onRecoverableError:n});else{const r=a.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};R(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>f});var r=n(6540),a=n(4784);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/feedzback/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/feedzback/docs","mainDocId":"audience","docs":[{"id":"audience","path":"/feedzback/docs/audience","sidebar":"default"},{"id":"business-cases/archiving","path":"/feedzback/docs/business-cases/archiving","sidebar":"default"},{"id":"business-cases/feedback-draft","path":"/feedzback/docs/business-cases/feedback-draft","sidebar":"default"},{"id":"business-cases/give-spontaneous-feedback","path":"/feedzback/docs/business-cases/give-spontaneous-feedback","sidebar":"default"},{"id":"business-cases/reply-to-feedback-request","path":"/feedzback/docs/business-cases/reply-to-feedback-request","sidebar":"default"},{"id":"business-cases/request-feedback","path":"/feedzback/docs/business-cases/request-feedback","sidebar":"default"},{"id":"business-cases/shared-feedback","path":"/feedzback/docs/business-cases/shared-feedback","sidebar":"default"},{"id":"ci-cd/circle-ci","path":"/feedzback/docs/ci-cd/circle-ci","sidebar":"default"},{"id":"ci-cd/quick-start","path":"/feedzback/docs/ci-cd/quick-start","sidebar":"default"},{"id":"documentation","path":"/feedzback/docs/documentation","sidebar":"default"},{"id":"installation","path":"/feedzback/docs/installation","sidebar":"default"},{"id":"technical-guides/client/cookies","path":"/feedzback/docs/technical-guides/client/cookies","sidebar":"default"},{"id":"technical-guides/client/demo","path":"/feedzback/docs/technical-guides/client/demo","sidebar":"default"},{"id":"technical-guides/client/firebase-hosting","path":"/feedzback/docs/technical-guides/client/firebase-hosting","sidebar":"default"},{"id":"technical-guides/client/i18n","path":"/feedzback/docs/technical-guides/client/i18n","sidebar":"default"},{"id":"technical-guides/client/icons","path":"/feedzback/docs/technical-guides/client/icons","sidebar":"default"},{"id":"technical-guides/client/styles","path":"/feedzback/docs/technical-guides/client/styles","sidebar":"default"},{"id":"technical-guides/e2e-testing","path":"/feedzback/docs/technical-guides/e2e-testing","sidebar":"default"},{"id":"technical-guides/environments/local-dev","path":"/feedzback/docs/technical-guides/environments/local-dev","sidebar":"default"},{"id":"technical-guides/environments/overview","path":"/feedzback/docs/technical-guides/environments/overview","sidebar":"default"},{"id":"technical-guides/server/swagger","path":"/feedzback/docs/technical-guides/server/swagger","sidebar":"default"},{"id":"technical-stack","path":"/feedzback/docs/technical-stack","sidebar":"default"},{"id":"ubiquitous-language","path":"/feedzback/docs/ubiquitous-language","sidebar":"default"},{"id":"update/client","path":"/feedzback/docs/update/client","sidebar":"default"},{"id":"usage-analytics","path":"/feedzback/docs/usage-analytics","sidebar":"default"}],"draftIds":[],"sidebars":{"default":{"link":{"path":"/feedzback/docs/audience","label":"audience"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(2654);const s=JSON.parse('{"docusaurusVersion":"3.6.3","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.6.3"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.6.3"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.6.3"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.6.3"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.6.3"}}}');var c=n(4848);const u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},d=r.createContext(u);function f(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});var r=n(6540),a=n(8193),o=n(5260),i=n(440),l=n(781),s=n(3102),c=n(4848);function u(e){let{error:t,tryAgain:n}=e;return(0,c.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,c.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,c.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,c.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,i.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,c.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function f(e){let{children:t}=e;return(0,c.jsx)(s.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function p(e){let{error:t,tryAgain:n}=e;return(0,c.jsx)(f,{children:(0,c.jsxs)(g,{fallback:()=>(0,c.jsx)(u,{error:t,tryAgain:n}),children:[(0,c.jsx)(o.A,{children:(0,c.jsx)("title",{children:"Page Error"})}),(0,c.jsx)(l.A,{children:(0,c.jsx)(u,{error:t,tryAgain:n})})]})})}const h=e=>(0,c.jsx)(p,{...e});class g extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??h)(e)}return e??null}}},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(545),a=n(4848);function o(e){return(0,a.jsx)(r.mg,{...e})}},8774:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),a=n(4625),o=n(440),i=n(4586),l=n(6654),s=n(8193),c=n(3427),u=n(6025),d=n(4848);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:h,isActive:g,"data-noBrokenLinkCheck":m,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:v}=(0,i.A)(),{trailingSlash:k,baseUrl:w}=v,x=v.future.experimental_router,{withBaseUrl:S}=(0,u.hH)(),E=(0,c.A)(),_=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>_.current));const C=f||p;const A=(0,l.A)(C),T=C?.replace("pathname://","");let N=void 0!==T?(O=T,b&&(e=>e.startsWith("/"))(O)?S(O):O):void 0;var O;"hash"===x&&N?.startsWith("./")&&(N=N?.slice(1)),N&&A&&(N=(0,o.Ks)(N,{trailingSlash:k,baseUrl:w}));const P=(0,r.useRef)(!1),j=n?a.k2:a.N_,L=s.A.canUseIntersectionObserver,R=(0,r.useRef)(),I=()=>{P.current||null==N||(window.docusaurus.preload(N),P.current=!0)};(0,r.useEffect)((()=>(!L&&A&&s.A.canUseDOM&&null!=N&&window.docusaurus.prefetch(N),()=>{L&&R.current&&R.current.disconnect()})),[R,N,L,A]);const z=N?.startsWith("#")??!1,D=!y.target||"_self"===y.target,F=!N||!A||!D||z&&"hash"!==x;m||!z&&F||E.collectLink(N),y.id&&E.collectAnchor(y.id);const M={};return F?(0,d.jsx)("a",{ref:_,href:N,...C&&!A&&{target:"_blank",rel:"noopener noreferrer"},...y,...M}):(0,d.jsx)(j,{...y,onMouseEnter:I,onTouchStart:I,innerRef:e=>{_.current=e,L&&e&&A&&(R.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(R.current.unobserve(e),R.current.disconnect(),null!=N&&window.docusaurus.prefetch(N))}))})),R.current.observe(e))},to:N,...n&&{isActive:g,activeClassName:h},...M})}const p=r.forwardRef(f)},418:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r=()=>null},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>c,T:()=>s});var r=n(6540),a=n(4848);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(2654);function l(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return o(l({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=l({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>a,z:()=>r})},6025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>l,hH:()=>i});var r=n(6540),a=n(4586),o=n(6654);function i(){const{siteConfig:e}=(0,a.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,l=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:a=!1,absolute:i=!1}={},router:l}=e;if(!r||r.startsWith("#")||(0,o.z)(r))return r;if("hash"===l)return r.startsWith("/")?`.${r}`:`./${r}`;if(a)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const s=r.startsWith(n)?r:n+r.replace(/^\//,"");return i?t+s:s}({siteUrl:n,baseUrl:t,url:e,options:r,router:i})),[n,t,i]);return{withBaseUrl:l}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},3427:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(6540);n(4848);const a=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),o=()=>(0,r.useContext)(a);function i(){return o()}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6988);function o(){return(0,r.useContext)(a.o)}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6125);function o(){return(0,r.useContext)(a.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540);const a=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect},6803:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(3102);function o(){const e=r.useContext(a.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>o});var r=n(6540),a=n(4848);const o=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(o),l=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,a.jsx)(o.Provider,{value:l,children:t})}},3886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>m,g1:()=>y});var r=n(6540),a=n(4070),o=n(7065),i=n(6342),l=n(679),s=n(9532),c=n(4848);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,l.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,l.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,l.Wf)(u(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function h(){const e=(0,a.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=h();return(0,c.jsx)(p.Provider,{value:n,children:t})}function m(e){let{children:t}=e;return(0,c.jsx)(g,{children:t})}function b(){const e=(0,r.useContext)(p);if(!e)throw new s.dV("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=o.W);const t=(0,a.ht)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},609:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,t:()=>c});var r=n(6540),a=n(9532),o=n(4848);const i=Symbol("EmptyContext"),l=r.createContext(i);function s(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(l.Provider,{value:i,children:t})}function c(){const e=(0,r.useContext)(l);if(e===i)throw new a.dV("DocsSidebarProvider");return e}},6972:(e,t,n)=>{"use strict";n.d(t,{B5:()=>S,Nr:()=>f,OF:()=>v,QB:()=>x,Vd:()=>k,Y:()=>b,fW:()=>w,w8:()=>g});var r=n(6540),a=n(6347),o=n(2831),i=n(4070),l=n(9169),s=n(1682),c=n(3886),u=n(3025),d=n(609);function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}const p=(e,t)=>void 0!==e&&(0,l.ys)(e,t),h=(e,t)=>e.some((e=>g(e,t)));function g(e,t){return"link"===e.type?p(e.href,t):"category"===e.type&&(p(e.href,t)||h(e.items,t))}function m(e,t){switch(e.type){case"category":return g(e,t)||e.items.some((e=>m(e,t)));case"link":return!e.unlisted||g(e,t);default:return!0}}function b(e,t){return(0,r.useMemo)((()=>e.filter((e=>m(e,t)))),[e,t])}function y(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,l.ys)(o.href,n)||e(o.items))||"link"===o.type&&(0,l.ys)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function v(){const e=(0,d.t)(),{pathname:t}=(0,a.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?y({sidebarItems:e.items,pathname:t}):null}function k(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,c.g1)(e),a=(0,i.r7)(e);return(0,r.useMemo)((()=>(0,s.sb)([t,n,a].filter(Boolean))),[t,n,a])}function w(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function x(e,t){const n=k(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,s.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function S(e){let{route:t}=e;const n=(0,a.zy)(),r=(0,u.r)(),i=t.routes,l=i.find((e=>(0,a.B6)(n.pathname,e)));if(!l)return null;const s=l.sidebar,c=s?r.docsSidebars[s]:void 0;return{docElement:(0,o.v)(i),sidebarName:s,sidebarItems:c}}},3025:(e,t,n)=>{"use strict";n.d(t,{n:()=>l,r:()=>s});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function l(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(null===e)throw new a.dV("DocsVersionProvider");return e}},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>g,vT:()=>f,Gy:()=>u,HW:()=>m,ht:()=>d,r7:()=>h,jh:()=>p});var r=n(6347),a=n(4586),o=n(7065);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const c={},u=()=>i("docusaurus-plugin-content-docs")??c,d=e=>{try{return function(e,t,n){void 0===t&&(t=o.W),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function f(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function p(e){return d(e).versions}function h(e){const t=d(e);return l(t)}function g(e){const t=d(e),{pathname:n}=(0,r.zy)();return s(t,n)}function m(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(5947),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},6134:(e,t,n)=>{"use strict";var r=n(1765),a=n(4784);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t,o=globalThis.Prism;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(9700),n(1170)(`./prism-${e}`)})),delete globalThis.Prism,void 0!==o&&(globalThis.Prism=e)}(r.My)},1107:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(6540);var r=n(4164),a=n(1312),o=n(6342),i=n(8774),l=n(3427);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var c=n(4848);function u(e){let{as:t,id:n,...u}=e;const d=(0,l.A)(),{navbar:{hideOnScroll:f}}=(0,o.p)();if("h1"===t||!n)return(0,c.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const p=(0,a.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,c.jsxs)(t,{...u,className:(0,r.A)("anchor",f?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,c.jsx)(i.A,{className:"hash-link",to:`#${n}`,"aria-label":p,title:p,children:"\u200b"})]})}},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(4848);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,a.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,a.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},781:(e,t,n)=>{"use strict";n.d(t,{A:()=>pt});var r=n(6540),a=n(4164),o=n(7489),i=n(1213),l=n(6347),s=n(1312),c=n(5062),u=n(4848);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,l.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,c.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const h=(0,s.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??h,{containerRef:n,onClick:r}=p();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":h,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var m=n(7559),b=n(4090);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(g,{className:y.skipToContent})}var k=n(6342),w=n(5041);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:a,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.A)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,k.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,a.A)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const A={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function T(){const{announcementBar:e}=(0,k.p)(),{isActive:t,close:n}=(0,w.M)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,u.jsxs)("div",{className:A.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,u.jsx)("div",{className:A.announcementBarPlaceholder}),(0,u.jsx)(C,{className:A.announcementBarContent}),o&&(0,u.jsx)(E,{onClick:n,className:A.announcementBarClose})]})}var N=n(9876),O=n(3104);var P=n(9532),j=n(5600);const L=r.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,N.M)(),t=(0,j.YL)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,P.ZC)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,u.jsx)(L.Provider,{value:n,children:t})}function I(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function z(){const e=(0,r.useContext)(L);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,j.YL)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:I(o)})),[a,o,t])}function D(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=z();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,a.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(5293),M=n(2303);function B(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function H(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,M.A)(),l=(0,s.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,s.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,s.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,a.A)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,a.A)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:l,"aria-label":l,"aria-live":"polite","aria-pressed":"dark"===r?"true":"false",children:[(0,u.jsx)(B,{className:(0,a.A)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,a.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const V=r.memo(H),W={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function q(e){let{className:t}=e;const n=(0,k.p)().navbar.style,r=(0,k.p)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,F.G)();return r?null:(0,u.jsx)(V,{className:t,buttonClassName:"dark"===n?W.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var G=n(3465);function Y(){return(0,u.jsx)(G.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,N.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,s.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Q(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(Y,{}),(0,u.jsx)(q,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Z=n(8774),X=n(6025),J=n(6654);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(3186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:a,label:o,html:i,isDropdownLink:l,prependBaseUrlToHref:s,...c}=e;const d=(0,X.Ay)(r),f=(0,X.Ay)(t),p=(0,X.Ay)(a,{forcePrependBaseUrl:!0}),h=o&&a&&!(0,J.A)(a),g=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[o,h&&(0,u.jsx)(te.A,{...l&&{width:12,height:12}})]})};return a?(0,u.jsx)(Z.A,{href:s?p:a,...c,...g}):(0,u.jsx)(Z.A,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},...c,...g})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const o=(0,u.jsx)(ne,{className:(0,a.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:o}):o}function ae(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,a.A)("menu__link",t),...r})})}function oe(e){let{mobile:t=!1,position:n,...r}=e;const a=t?ae:re;return(0,u.jsx)(a,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(1422),le=n(9169),se=n(4586);const ce={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,le.ys)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:o,onClick:i,...l}=e;const s=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[s]),(0,u.jsxs)("div",{ref:s,className:(0,a.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:l.to?void 0:"#",className:(0,a.A)("navbar__link",o),...l,onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:l.children??l.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(_e,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function fe(e){let{items:t,className:n,position:o,onClick:i,...s}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.A)(),{pathname:t}=(0,l.zy)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:f,toggleCollapsed:p,setCollapsed:h}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&h(!d)}),[c,d,h]),(0,u.jsxs)("li",{className:(0,a.A)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,u.jsx)(ne,{role:"button",className:(0,a.A)(ce.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...s,onClick:e=>{e.preventDefault(),p()},children:s.children??s.label}),(0,u.jsx)(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:t.map(((e,t)=>(0,r.createElement)(_e,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?fe:de;return(0,u.jsx)(r,{...n})}var he=n(2131);function ge(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const me="iconLanguage_nlXk";var be=n(418);const ye={navbarSearchContainer:"navbarSearchContainer_Bca1"};function ve(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,a.A)(n,ye.navbarSearchContainer),children:t})}var ke=n(4070),we=n(6972);var xe=n(3886);function Se(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Ee={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:a="",...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,se.A)(),f=(0,he.o)(),{search:p,hash:h}=(0,l.zy)(),g=[...n,...c.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${h}${a}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],m=t?(0,s.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(pe,{...o,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(ge,{className:me}),m]}),items:g})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(ve,{className:n,children:(0,u.jsx)(be.A,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,u.jsx)(i,{className:(0,a.A)({navbar__item:!r&&!o,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,ke.zK)(r),i=(0,we.QB)(t,r),l=o?.path===i?.path;return null===i||i.unlisted&&!l?null:(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>l||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,ke.zK)(r),i=(0,we.fW)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(oe,{exact:!0,...a,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...a}=e;const o=(0,we.Vd)(r)[0],i=t??o.label,l=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,u.jsx)(oe,{...a,label:i,to:l})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:a,dropdownItemsAfter:o,...i}=e;const{search:c,hash:d}=(0,l.zy)(),f=(0,ke.zK)(n),p=(0,ke.jh)(n),{savePreferredVersionName:h}=(0,xe.g1)(n),g=[...a,...p.map((function(e){const t=Se(e,f);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...o],m=(0,we.Vd)(n)[0],b=t&&g.length>1?(0,s.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,y=t&&g.length>1?void 0:Se(m,f).path;return g.length<=1?(0,u.jsx)(oe,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(pe,{...i,mobile:t,label:b,to:y,items:g,isActive:r?()=>!1:void 0})}};function _e(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=Ee[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(a,{...n})}function Ce(){const e=(0,N.M)(),t=(0,k.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(_e,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ae(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(s.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Te(){const e=0===(0,k.p)().navbar.items.length,t=z();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ae,{onClick:()=>t.hide()}),t.content]})}function Ne(){const e=(0,N.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(D,{header:(0,u.jsx)(Q,{}),primaryMenu:(0,u.jsx)(Ce,{}),secondaryMenu:(0,u.jsx)(Te,{})}):null}const Oe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Pe(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,a.A)("navbar-sidebar__backdrop",e.className)})}function je(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,k.p)(),i=(0,N.M)(),{navbarRef:l,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,O.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:l,"aria-label":(0,s.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.A)("navbar","navbar--fixed-top",n&&[Oe.navbarHideable,!d&&Oe.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Pe,{onClick:i.toggle}),(0,u.jsx)(Ne,{})]})}var Le=n(440);const Re={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function Ie(e){return(0,u.jsx)("button",{type:"button",...e,children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function ze(e){let{error:t}=e;const n=(0,Le.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,u.jsx)("p",{className:Re.errorBoundaryError,children:n})}class De extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Fe="right";function Me(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function Be(){const{toggle:e,shown:t}=(0,N.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,s.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(Me,{})})}const $e={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(De,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(_e,{...e})},t)))})}function He(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function Ve(){const e=(0,N.M)(),t=(0,k.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Fe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,u.jsx)(He,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(Be,{}),(0,u.jsx)(Y,{}),(0,u.jsx)(Ue,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ue,{items:r}),(0,u.jsx)(q,{className:$e.colorModeToggle}),!a&&(0,u.jsx)(ve,{children:(0,u.jsx)(be.A,{})})]})})}function We(){return(0,u.jsx)(je,{children:(0,u.jsx)(Ve,{})})}function qe(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,l=(0,X.Ay)(n),s=(0,X.Ay)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Z.A,{className:"footer__link-item",...r?{href:o?s:r}:{to:l},...i,children:[a,r&&!(0,J.A)(r)&&(0,u.jsx)(te.A,{})]})}function Ge(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(qe,{item:t})},t.href??t.to)}function Ye(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(Ge,{item:e},t)))})]})}function Ke(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(Ye,{column:e},t)))})}function Qe(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function Ze(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(qe,{item:t})}function Xe(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(Ze,{item:e}),t.length!==n+1&&(0,u.jsx)(Qe,{})]},n)))})})}function Je(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(Ke,{columns:t}):(0,u.jsx)(Xe,{links:t})}var et=n(1122);const tt={footerLogoLink:"footerLogoLink_BH7S"};function nt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(et.A,{className:(0,a.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function rt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Z.A,{href:t.href,className:tt.footerLogoLink,target:t.target,children:(0,u.jsx)(nt,{logo:t})}):(0,u.jsx)(nt,{logo:t})}function at(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function ot(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,u.jsx)("footer",{className:(0,a.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function it(){const{footer:e}=(0,k.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,u.jsx)(ot,{style:a,links:n&&n.length>0&&(0,u.jsx)(Je,{links:n}),logo:r&&(0,u.jsx)(rt,{logo:r}),copyright:t&&(0,u.jsx)(at,{copyright:t})})}const lt=r.memo(it),st=(0,P.fM)([F.a,w.o,O.Tv,xe.VQ,i.Jx,function(e){let{children:t}=e;return(0,u.jsx)(j.y_,{children:(0,u.jsx)(N.e,{children:(0,u.jsx)(R,{children:t})})})}]);function ct(e){let{children:t}=e;return(0,u.jsx)(st,{children:t})}var ut=n(1107);function dt(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(ut.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(s.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Ie,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(ze,{error:t})})]})})})}const ft={mainWrapper:"mainWrapper_z2l0"};function pt(e){const{children:t,noFooter:n,wrapperClassName:r,title:l,description:s}=e;return(0,b.J)(),(0,u.jsxs)(ct,{children:[(0,u.jsx)(i.be,{title:l,description:s}),(0,u.jsx)(v,{}),(0,u.jsx)(T,{}),(0,u.jsx)(We,{}),(0,u.jsx)("div",{id:d,className:(0,a.A)(m.G.wrapper.main,ft.mainWrapper,r),children:(0,u.jsx)(o.A,{fallback:e=>(0,u.jsx)(dt,{...e}),children:t})}),!n&&(0,u.jsx)(lt,{})]})}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(6540);var r=n(8774),a=n(6025),o=n(4586),i=n(6342),l=n(1122),s=n(4848);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,a.Ay)(t.src),dark:(0,a.Ay)(t.srcDark||t.src)},i=(0,s.jsx)(l.A,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,s.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,o.A)(),{navbar:{title:n,logo:l}}=(0,i.p)(),{imageClassName:u,titleClassName:d,...f}=e,p=(0,a.Ay)(l?.href||"/"),h=n?"":t,g=l?.alt??h;return(0,s.jsxs)(r.A,{to:p,...f,...l?.target&&{target:l.target},children:[l&&(0,s.jsx)(c,{logo:l,alt:g,imageClassName:u}),null!=n&&(0,s.jsx)("b",{className:d,children:n})]})}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(5260),a=n(4848);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,a.jsxs)(r.A,{children:[t&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,a.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,a.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},1122:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(6540),a=n(4164),o=n(2303),i=n(5293);const l={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var s=n(4848);function c(e){let{className:t,children:n}=e;const c=(0,o.A)(),{colorMode:u}=(0,i.G)();return(0,s.jsx)(s.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,a.A)(t,l.themedComponent,l[`themedComponent--${e}`])});return(0,s.jsx)(r.Fragment,{children:o},e)}))})}function u(e){const{sources:t,className:n,alt:r,...a}=e;return(0,s.jsx)(c,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,s.jsx)("img",{src:t[n],alt:r,className:o,...a})}})}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>b,u:()=>c});var r=n(6540),a=n(8193),o=n(205),i=n(3109),l=n(4848);const s="ease-in-out";function c(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function f(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??s}`,height:`${t}px`}}function l(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return f(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function h(e){if(!a.A.canUseDOM)return e?u:d}function g(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:s,disableSSRStyle:c}=e;const u=(0,r.useRef)(null);return p({collapsibleRef:u,collapsed:n,animation:o}),(0,l.jsx)(t,{ref:u,style:c?void 0:h(n),onTransitionEnd:e=>{"height"===e.propertyName&&(f(u.current,n),i?.(n))},className:s,children:a})}function m(e){let{collapsed:t,...n}=e;const[a,i]=(0,r.useState)(!t),[s,c]=(0,r.useState)(t);return(0,o.A)((()=>{t||i(!0)}),[t]),(0,o.A)((()=>{a&&c(t)}),[a,t]),a?(0,l.jsx)(g,{...n,collapsed:s}):null}function b(e){let{lazy:t,...n}=e;const r=t?m:g;return(0,l.jsx)(r,{...n})}},5041:(e,t,n)=>{"use strict";n.d(t,{M:()=>g,o:()=>h});var r=n(6540),a=n(2303),o=n(679),i=n(9532),l=n(6342),s=n(4848);const c=(0,o.Wf)("docusaurus.announcement.dismiss"),u=(0,o.Wf)("docusaurus.announcement.id"),d=()=>"true"===c.get(),f=e=>c.set(String(e)),p=r.createContext(null);function h(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.p)(),t=(0,a.A)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{f(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&f(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,s.jsx)(p.Provider,{value:n,children:t})}function g(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>m});var r=n(6540),a=n(8193),o=n(9532),i=n(679),l=n(6342),s=n(4848);const c=r.createContext(void 0),u="theme",d=(0,i.Wf)(u),f={light:"light",dark:"dark"},p=e=>e===f.dark?f.dark:f.light,h=e=>a.A.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),g=e=>{d.set(p(e))};function m(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.p)(),[a,o]=(0,r.useState)(h(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&g(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f.dark:f.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===f.dark},setLightTheme(){i(f.light)},setDarkTheme(){i(f.dark)}})),[a,i])}();return(0,s.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(c);if(null==e)throw new o.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},9876:(e,t,n)=>{"use strict";n.d(t,{e:()=>p,M:()=>h});var r=n(6540),a=n(5600),o=n(4581),i=n(6347),l=n(9532);function s(e){!function(e){const t=(0,i.W6)(),n=(0,l._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var c=n(6342),u=n(4848);const d=r.createContext(void 0);function f(){const e=function(){const e=(0,a.YL)(),{items:t}=(0,c.p)().navbar;return 0===t.length&&!e.component}(),t=(0,o.l)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:i})),[e,n,u,i])}function p(e){let{children:t}=e;const n=f();return(0,u.jsx)(d.Provider,{value:n,children:t})}function h(){const e=r.useContext(d);if(void 0===e)throw new l.dV("NavbarMobileSidebarProvider");return e}},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>c,YL:()=>s,y_:()=>l});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function l(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function s(){const e=(0,r.useContext)(i);if(!e)throw new a.dV("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const o=(0,r.useContext)(i);if(!o)throw new a.dV("NavbarSecondaryMenuContentProvider");const[,l]=o,s=(0,a.Be)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>a,J:()=>o});var r=n(6540);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>l});var r=n(6540),a=n(8193);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,l]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){l(function(e){if(!a.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?o.desktop:o.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},3109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},1682:(e,t,n)=>{"use strict";function r(e){return Array.from(new Set(e))}function a(e,t){const n={};let r=0;for(const a of e){const e=t(a,r);n[e]??=[],n[e].push(a),r+=1}return n}n.d(t,{$z:()=>a,sb:()=>r})},1213:(e,t,n)=>{"use strict";n.d(t,{e3:()=>f,be:()=>u,Jx:()=>p});var r=n(6540),a=n(4164),o=n(5260),i=n(6803),l=n(6025),s=n(4586);var c=n(4848);function u(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const u=function(e){const{siteConfig:t}=(0,s.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.hH)(),f=a?d(a,{absolute:!0}):void 0;return(0,c.jsxs)(o.A,{children:[t&&(0,c.jsx)("title",{children:u}),t&&(0,c.jsx)("meta",{property:"og:title",content:u}),n&&(0,c.jsx)("meta",{name:"description",content:n}),n&&(0,c.jsx)("meta",{property:"og:description",content:n}),r&&(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),f&&(0,c.jsx)("meta",{property:"og:image",content:f}),f&&(0,c.jsx)("meta",{name:"twitter:image",content:f}),i]})}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.A)(i,t);return(0,c.jsxs)(d.Provider,{value:l,children:[(0,c.jsx)(o.A,{children:(0,c.jsx)("html",{className:l})}),n]})}function p(e){let{children:t}=e;const n=(0,i.A)(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,c.jsx)(f,{className:(0,a.A)(r,o),children:t})}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>c,ZC:()=>l,_q:()=>i,dV:()=>s,fM:()=>u});var r=n(6540),a=n(205),o=n(4848);function i(e){const t=(0,r.useRef)(e);return(0,a.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function l(e){const t=(0,r.useRef)();return(0,a.A)((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>l,ys:()=>i});var r=n(6540),a=n(8328),o=n(4586);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.A,baseUrl:e})),[e])}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>c,gk:()=>p});var r=n(6540),a=n(8193),o=n(2303),i=(n(205),n(9532)),l=n(4848);const s=r.createContext(void 0);function c(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(s.Provider,{value:n,children:t})}function u(){const e=(0,r.useContext)(s);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const d=()=>a.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),a=(0,r.useRef)(d()),o=(0,i._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>c});n(6540);const r=JSON.parse('{"N":"localStorage","M":""}'),a=r.N;function o(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function i(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const a=i(t?.persistence);return null===a?s:{get:()=>{try{return a.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=a.getItem(n);a.setItem(n,e),o({key:n,oldValue:t,newValue:e,storage:a})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=a.getItem(n);a.removeItem(n),o({key:n,oldValue:e,newValue:null,storage:a})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===a&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},2131:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(4586),a=n(6347),o=n(440);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:l}}=(0,r.A)(),{pathname:s}=(0,a.zy)(),c=(0,o.Ks)(s,{trailingSlash:n,baseUrl:e}),u=l===i?e:e.replace(`/${l}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),a=n(6347),o=n(9532);function i(e){const t=(0,a.zy)(),n=(0,o.ZC)(t),i=(0,o._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(4586);function a(){return(0,r.A)().siteConfig.themeConfig}},2983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=a,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),l="/"===i||i===r?i:(s=i,c=n,c?a(s):o(s));var s,c;return e.replace(i,l)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=o;const r=n(2566);function a(e){return e.endsWith("/")?e:`${e}/`}function o(e){return(0,r.removeSuffix)(e,"/")}},253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const r=n(1635);t.LU="__blog-post-container";var a=n(2983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(a).default}});var o=n(2566);var i=n(253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},2566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>k,TM:()=>C,yJ:()=>p,sC:()=>T,AO:()=>f});var r=n(8168);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var l=n(1561);function s(e){return"/"===e.charAt(0)?e:"/"+e}function c(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.A)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,g(),k.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(k.entries[k.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=k.index+e;return t>=0&&t{"use strict";var r=n(4363),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var a=p(n);a&&a!==h&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),g=s(n),m=0;m{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,l],u=0;(s=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},119:(e,t,n)=>{"use strict";n.r(t)},1043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(c,i(e,u,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=f(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},5302:(e,t,n)=>{var r=n(4634);e.exports=p,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var h=e[i],g=n[2],m=n[3],b=n[4],y=n[5],v=n[6],k=n[7];l&&(r.push(l),l="");var w=null!=g&&null!=h&&h!==g,x="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||u,_=b||y;r.push({name:m||o++,prefix:g||"",delimiter:E,optional:S,repeat:x,partial:w,asterisk:!!k,pattern:_?c(_):k?".*":"[^"+s(E)+"]+?"})}}return i{!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i{Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json},9700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var c=l[s];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],f="string"==typeof c?c:c.content,p=t(r,u),h=f.indexOf(p);if(h>-1){++a;var g=f.substring(0,h),m=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(h+p.length),y=[];g&&y.push.apply(y,i([g])),y.push(m),b&&y.push.apply(y,i([b])),"string"==typeof c?l.splice.apply(l,[s,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return l}(n.tokens)}}}})}(Prism)},4604:()=>{Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss},1170:(e,t,n)=>{var r={"./prism-bash":7022,"./prism-json":2514,"./prism-scss":4604};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=1170},2694:(e,t,n)=>{"use strict";var r=n(6925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},2551:(e,t,n)=>{"use strict";var r=n(6540),a=n(9982);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n