diff --git a/webclient/.eslintrc.cjs b/webclient/.eslintrc.cjs index dfdc0c9d2..128333065 100644 --- a/webclient/.eslintrc.cjs +++ b/webclient/.eslintrc.cjs @@ -1,71 +1,71 @@ -/* eslint-env node */ -module.exports = { - root: true, - extends: [ - "plugin:vue/vue3-essential", - "plugin:vue/vue3-strongly-recommended", - "plugin:vue/vue3-recommended", - "eslint:recommended", - "@vue/eslint-config-typescript/recommended", - "@vue/eslint-config-prettier", - "@vue/eslint-config-prettier/skip-formatting", - ], - parserOptions: { - ecmaVersion: "latest", - }, - rules: { - "vue/no-v-html": "off", - "vue/block-lang": [ - "error", - { - script: { - lang: "ts", - }, - }, - ], - "vue/block-order": [ - "error", - { - order: ["script", "template", "style", "i18n"], - }, - ], - "vue/block-tag-newline": "error", - "vue/component-api-style": [ - "error", - ["script-setup", "composition"], // "script-setup", "composition", "composition-vue2", or "options" - ], - "vue/multi-word-component-names": "off", - "vue/component-name-in-template-casing": ["error", "PascalCase", { registeredComponentsOnly: false }], - "vue/custom-event-name-casing": ["error", "camelCase"], - "vue/define-macros-order": "error", - "vue/define-props-declaration": ["error", "type-based"], - "vue/html-button-has-type": [ - "error", - { - button: true, - submit: true, - reset: true, - }, - ], - "vue/no-boolean-default": ["error", "default-false"], - "vue/no-empty-component-block": "error", - "vue/html-comment-content-spacing": ["error", "always"], - "vue/no-ref-object-reactivity-loss": "error", - "vue/no-required-prop-with-default": "error", - "vue/no-restricted-call-after-await": "error", - //"vue/no-root-v-if": "error", todo: enable when there is a loading animation - "vue/no-setup-props-reactivity-loss": "error", - //"vue/no-static-inline-styles": "error", todo: enable after migration to tailwind - "vue/no-useless-mustaches": "error", - "vue/no-useless-v-bind": "error", - "vue/no-v-text": "error", - "vue/padding-line-between-blocks": "error", - "vue/prefer-prop-type-boolean-first": "error", - "vue/prefer-separate-static-class": "error", - "vue/require-macro-variable-name": "error", - "vue/require-typed-ref": "error", - "vue/static-class-names-order": "off", - "vue/v-for-delimiter-style": "error", - "vue/no-constant-condition": "error", - }, -}; +/* eslint-env node */ +module.exports = { + root: true, + extends: [ + "plugin:vue/vue3-essential", + "plugin:vue/vue3-strongly-recommended", + "plugin:vue/vue3-recommended", + "eslint:recommended", + "@vue/eslint-config-typescript/recommended", + "@vue/eslint-config-prettier", + "@vue/eslint-config-prettier/skip-formatting", + ], + parserOptions: { + ecmaVersion: "latest", + }, + rules: { + "vue/no-v-html": "off", + "vue/block-lang": [ + "error", + { + script: { + lang: "ts", + }, + }, + ], + "vue/block-order": [ + "error", + { + order: ["script", "template", "style", "i18n"], + }, + ], + "vue/block-tag-newline": "error", + "vue/component-api-style": [ + "error", + ["script-setup", "composition"], // "script-setup", "composition", "composition-vue2", or "options" + ], + "vue/multi-word-component-names": "off", + "vue/component-name-in-template-casing": ["error", "PascalCase", { registeredComponentsOnly: false }], + "vue/custom-event-name-casing": ["error", "camelCase"], + "vue/define-macros-order": "error", + "vue/define-props-declaration": ["error", "type-based"], + "vue/html-button-has-type": [ + "error", + { + button: true, + submit: true, + reset: true, + }, + ], + "vue/no-boolean-default": ["error", "default-false"], + "vue/no-empty-component-block": "error", + "vue/html-comment-content-spacing": ["error", "always"], + "vue/no-ref-object-reactivity-loss": "error", + "vue/no-required-prop-with-default": "error", + "vue/no-restricted-call-after-await": "error", + //"vue/no-root-v-if": "error", todo: enable when there is a loading animation + "vue/no-setup-props-reactivity-loss": "error", + //"vue/no-static-inline-styles": "error", todo: enable after migration to tailwind + "vue/no-useless-mustaches": "error", + "vue/no-useless-v-bind": "error", + "vue/no-v-text": "error", + "vue/padding-line-between-blocks": "error", + "vue/prefer-prop-type-boolean-first": "error", + "vue/prefer-separate-static-class": "error", + "vue/require-macro-variable-name": "error", + "vue/require-typed-ref": "error", + "vue/static-class-names-order": "off", + "vue/v-for-delimiter-style": "error", + "vue/no-constant-condition": "error", + }, +}; diff --git a/webclient/README.md b/webclient/README.md index b244c2240..f854a38e1 100644 --- a/webclient/README.md +++ b/webclient/README.md @@ -1,115 +1,115 @@ -# Webclient - -This folder contains the JavaScript based webclient for NavigaTUM. - -## Getting started - -### Prerequisites - -For getting started, there are some system dependencys which you will need. -Please follow the [system dependencys docs](/resources/documentation/Dependencys.md) before trying to run this part of our project. - -### Recommended IDE Setup - -[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). -Most modern IDEs (like PyCharm) should work as well and have a Plugin. - -## Dependencies - -### Prerequisites - -For getting started, there are some system dependencys which you will need. -Please follow the [system dependencys docs](/resources/documentation/Dependencys.md) before trying to run this part of our project. - -### Installing Dependency's - -```bash -pnpm install -``` - -## Run - -Ensure that _NavigaTUM-server_ is running in the background. -By default, the webclient will connect to the server on `https://nav.tum.de`. -If you want to connect to a local version instead, change the environemnt variable `NUXT_PUBLIC_{API,CDN,FEEDBACK,MAPS}_URL` to the appropriate value. - -To get a local server running, please: - -- either via following the [guide to local development](../server/README.md), or -- via [docker](https://docs.docker.com/) - _docker isolates the network, but we want these two containers to communicate to each other without being as brittle as IPs._ - _Naming the `navigatum-mieli-search` container `search` makes us able to connect to it via <`http://search:7700`> from the server_ - - ```bash - docker network create navigatum-net - docker run -it --rm -p 7700:7700 --name search --network navigatum-net ghcr.io/tum-dev/navigatum-mieli-search:main - docker run -it --rm -p 8080:8080 --network navigatum-net -e MIELI_SEARCH_ADDR=search ghcr.io/tum-dev/navigatum-server:main /bin/navigatum-main-api - ``` - -```sh -pnpm run dev -``` - -### Type-Check, Compile and Minify for Production - -```sh -pnpm run build -``` - -### Linting with [ESLint](https://eslint.org/) and formatting via prettier - -```sh -pnpm run lint -pnpm run format -``` - -### Update the API's type definitions - -From the folder of this README, run: - -```sh -pnpm run type-refresh -``` - -## Architecture - -The NavigaTUM webclient is made as a nuxt3 server side rendered application based on [Vue.js](https://vuejs.org/) and [Vue Router](https://router.vuejs.org/). -Our CSS framework is [Tailwind](https://tailwindcss.com/). - -### Directory structure (only the important parts) - -```plain -webclient -├── public/ # 🠔 Static assets such as icons, which cannot get inlined -├── api_types/ # 🠔 code generated via openapi.yaml for typechecking reasons -├── content/ # 🠔 Static pages written in markdown. Served at `/about/`. -├── assets/ # 🠔 Static assets such as icons -│ ├── main.scss # 🠔 Sass CSS code for all non-view parts -│ └── logos # 🠔 The Logos used by the app -├── components/ # 🠔 Vue components, which are used in views. -├── pages/ # 🠔 The pages are parts of App.vue, which are loaded based their file names. -├── nuxt.config.ts # 🠔 core configuration of nuxt -└── package.json # 🠔 Node package definition and dependencies -``` - -Note that new views are automatically included in the build, but they are not routed. -To add a new view, you need to add a new route in `router.ts`. - -## Testing - -> [!NOTE] -> cypress is currently temporarily disabled to help in the nuxt transition - -For this part of the project, the tests consist mainly of hot-path e2e tests and tests of critical components. -PRs improving the coverage are very likely to be accepted. -The reason behind these tests is that they fundamentally increase the future productivity by allowing faster review cycles. - -### Continuous Integration - -Every push and pull request triggers a build that runs linting issues (cypress is currently temporarily disabled to help in the nuxt transition). -This helps us catch any regressions or issues early in the development process. - -### Reporting Issues - -If you encounter any problems while running the Cypress tests or have suggestions for improving the testing framework, please open an issue/pull request on this repository. -We appreciate your feedback and contributions. +# Webclient + +This folder contains the JavaScript based webclient for NavigaTUM. + +## Getting started + +### Prerequisites + +For getting started, there are some system dependencys which you will need. +Please follow the [system dependencys docs](/resources/documentation/Dependencys.md) before trying to run this part of our project. + +### Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). +Most modern IDEs (like PyCharm) should work as well and have a Plugin. + +## Dependencies + +### Prerequisites + +For getting started, there are some system dependencys which you will need. +Please follow the [system dependencys docs](/resources/documentation/Dependencys.md) before trying to run this part of our project. + +### Installing Dependency's + +```bash +pnpm install +``` + +## Run + +Ensure that _NavigaTUM-server_ is running in the background. +By default, the webclient will connect to the server on `https://nav.tum.de`. +If you want to connect to a local version instead, change the environemnt variable `NUXT_PUBLIC_{API,CDN,FEEDBACK,MAPS}_URL` to the appropriate value. + +To get a local server running, please: + +- either via following the [guide to local development](../server/README.md), or +- via [docker](https://docs.docker.com/) + _docker isolates the network, but we want these two containers to communicate to each other without being as brittle as IPs._ + _Naming the `navigatum-mieli-search` container `search` makes us able to connect to it via <`http://search:7700`> from the server_ + + ```bash + docker network create navigatum-net + docker run -it --rm -p 7700:7700 --name search --network navigatum-net ghcr.io/tum-dev/navigatum-mieli-search:main + docker run -it --rm -p 8080:8080 --network navigatum-net -e MIELI_SEARCH_ADDR=search ghcr.io/tum-dev/navigatum-server:main /bin/navigatum-main-api + ``` + +```sh +pnpm run dev +``` + +### Type-Check, Compile and Minify for Production + +```sh +pnpm run build +``` + +### Linting with [ESLint](https://eslint.org/) and formatting via prettier + +```sh +pnpm run lint +pnpm run format +``` + +### Update the API's type definitions + +From the folder of this README, run: + +```sh +pnpm run type-refresh +``` + +## Architecture + +The NavigaTUM webclient is made as a nuxt3 server side rendered application based on [Vue.js](https://vuejs.org/) and [Vue Router](https://router.vuejs.org/). +Our CSS framework is [Tailwind](https://tailwindcss.com/). + +### Directory structure (only the important parts) + +```plain +webclient +├── public/ # 🠔 Static assets such as icons, which cannot get inlined +├── api_types/ # 🠔 code generated via openapi.yaml for typechecking reasons +├── content/ # 🠔 Static pages written in markdown. Served at `/about/`. +├── assets/ # 🠔 Static assets such as icons +│ ├── main.scss # 🠔 Sass CSS code for all non-view parts +│ └── logos # 🠔 The Logos used by the app +├── components/ # 🠔 Vue components, which are used in views. +├── pages/ # 🠔 The pages are parts of App.vue, which are loaded based their file names. +├── nuxt.config.ts # 🠔 core configuration of nuxt +└── package.json # 🠔 Node package definition and dependencies +``` + +Note that new views are automatically included in the build, but they are not routed. +To add a new view, you need to add a new route in `router.ts`. + +## Testing + +> [!NOTE] +> cypress is currently temporarily disabled to help in the nuxt transition + +For this part of the project, the tests consist mainly of hot-path e2e tests and tests of critical components. +PRs improving the coverage are very likely to be accepted. +The reason behind these tests is that they fundamentally increase the future productivity by allowing faster review cycles. + +### Continuous Integration + +Every push and pull request triggers a build that runs linting issues (cypress is currently temporarily disabled to help in the nuxt transition). +This helps us catch any regressions or issues early in the development process. + +### Reporting Issues + +If you encounter any problems while running the Cypress tests or have suggestions for improving the testing framework, please open an issue/pull request on this repository. +We appreciate your feedback and contributions. diff --git a/webclient/api_types/index.ts b/webclient/api_types/index.ts index 6fc440592..3af738f68 100644 --- a/webclient/api_types/index.ts +++ b/webclient/api_types/index.ts @@ -1,1415 +1,1415 @@ -/** - * This file was auto-generated by openapi-typescript. - * Do not make direct changes to the file. - */ - -export type paths = { - "/api/search": { - /** - * Search entries - * @description This endpoint is designed to support search-as-you-type results. - * - * Instead of simply returning a list, the search results are returned in a way to provide a richer experience by splitting them up into sections. You might not necessarily need to implement all types of sections, or all sections features (if you just want to show a list). The order of sections is a suggested order to display them, but you may change this as you like. - * - * Some fields support highlighting the query terms and it uses \x19 and \x17 to mark the beginning/end of a highlighted sequence. - * (See [Wikipedia](https://en.wikipedia.org/wiki/C0_and_C1_control_codes#Modified_C0_control_code_sets)). - * Some text-renderers will ignore them, but in case you do not want to use them, you might want to remove them from the responses via empty `pre_highlight` and `post_highlight` query parameters. - */ - get: operations["search"]; - }; - "/api/get/{id}": { - /** - * Get entry-details - * @description This returns the full data available for the entry (room/building). - * - * This is more data, that should be supplied once a user clicks on an entry. - * Preloading this is not an issue on our end, but keep in mind bandwith constraints on your side. - * The data can be up to 50kB (using gzip) or 200kB unzipped. - * The more about this data format is described in the NavigaTUM-data documentation - */ - get: operations["details"]; - }; - "/api/calendar/{id}": { - /** - * Retrieve Calendar Entries - * @description Retrieves calendar entries for a specific `id` within the requested time span. - * The time span is defined by the `start_after` and `end_before` query parameters. - * Ensure to provide valid date-time formats for these parameters. - * - * If successful, returns additional entries in the requested time span. - */ - get: operations["calendar"]; - }; - "/api/preview/{id}": { - /** - * Get a entry-preview - * @description This returns a 1200x630px preview for the location (room/building/..). - * - * This is usefully for implementing custom OpenGraph images for detail previews. - */ - get: operations["previews"]; - }; - "/api/feedback/get_token": { - /** - * Get a feedback-token - * @description ***Do not abuse this endpoint.*** - * - * This returns a JWT token usable for submitting feedback. - * You should request a token, ***if (and only if) a user is on a feedback page*** - * - * As a rudimentary way of rate-limiting feedback, this endpoint returns a token. - * To post feedback, you will need this token. - * - * Tokens gain validity after 5s, and are invalid after 12h of being issued. - * They are not refreshable, and are only valid for one usage. - * - * ***Important Note:*** - * Global Rate-Limiting allows bursts with up to 20 requests and replenishes 50 requests per day - */ - post: operations["get_token"]; - }; - "/api/feedback/feedback": { - /** - * Post feedback - * @description ***Do not abuse this endpoint.*** - * - * This posts the actual feedback to github and returns the github link. - * This API will create issues instead of pull-requests => all feedback is allowed, but `/api/feedback/propose_edit` is prefered, if it can be posted there. - * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. - * - * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid - */ - post: operations["post_feedback"]; - }; - "/api/feedback/propose_edit": { - /** - * Post Edit-Requests - * @description ***Do not abuse this endpoint.*** - * - * This posts the actual feedback to github and returns the github link. - * This API will create pull-requests instead of issues => only a subset of feedback is allowed. - * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. - * - * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid - */ - post: operations["propose_edit"]; - }; - "/cdn/{size}/{id}_{counter}.webp": { - /** - * Get title images - * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. - * You HAVE to get the proper attribution from that endpoint and use it. - */ - get: operations["img_cdn"]; - }; - "/cdn/maps/{source}/{id}.webp": { - /** - * Get title images - * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. - * You HAVE to get the proper attribution from that endpoint and use it. - */ - get: operations["maps_cdn"]; - }; - "/api/status": { - /** - * API healthcheck - * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. - */ - get: operations["api-health"]; - }; - "/api/feedback/status": { - /** - * feedback-API healthcheck - * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. - */ - get: operations["feedback-health"]; - }; - "/cdn/health": { - /** - * CDN healthcheck - * @description If this endpoint does not return 200, the CDN is experiencing a catastrophic outage. Should never happen. - */ - get: operations["cdn-health"]; - }; - "/health": { - /** - * Website healthcheck - * @description If this endpoint does not return 200, the Website is experiencing a catastrophic outage. Should never happen. - */ - get: operations["web-health"]; - }; -}; - -export type webhooks = Record; - -export type components = { - schemas: { - /** @description Data for the info-card table */ - readonly Props: { - /** @description The operator of the room */ - readonly operator?: { - /** - * @description The designation code of the operator - * @example TUS7000 - */ - readonly code?: string; - /** - * @description The full name of the operator (localized). Null for organisations that - * are no longer active (e.g. id=38698), but where the operator has not been - * updated in TUMonline. - * - * @example TUM School of Social Sciences and Technology - */ - readonly name?: string | null; - /** - * @description A link to the operator - * @example https://campus.tum.de/tumonline/webnav.navigate_to?corg=51901 - */ - readonly url?: string; - /** - * @description The id of the operator - * @example 51901 - */ - readonly id?: number; - }; - readonly computed: readonly components["schemas"]["ComputedProp"][]; - readonly links?: readonly components["schemas"]["LinkProp"][]; - /** - * @description A comment to show to an entry. - * It is used in the rare cases, where some aspect about the rooom/.. or its translation are misleading. - * An example of a room with a comment is MW1801. - */ - readonly comment?: string; - /** @description A link to the calendar of the room */ - readonly calendar_url?: string; - }; - readonly ComputedProp: { - /** @example Raumkennung */ - readonly name: string; - /** @example 5602.EG.001 */ - readonly text: string; - readonly extra?: { - /** @example Genauere Angaben */ - readonly header?: string; - /** @example für Prüfungen: 102 in eng, 71 in weit, 49 in corona */ - readonly body: string; - /** @example data based on a Survey of chimneysweeps */ - readonly footer?: string; - }; - }; - /** @description A link with a localized link text and url */ - readonly LinkProp: { - readonly text: string; - readonly url: string; - }; - /** @description The information you need to request Images from the /cdn/{size}/{id}_{counter}.webp endpoint */ - readonly ImageInfo: { - /** - * @description The name of the image file. consists of {building_id}_{image_id}.webp, where image_id is a counter starting at 0 - * @example mi_0.webp - */ - readonly name: string; - readonly author: components["schemas"]["PossibleURLRef"]; - readonly source: components["schemas"]["PossibleURLRef"]; - readonly license: components["schemas"]["PossibleURLRef"]; - readonly meta?: components["schemas"]["ImageMetadata"]; - }; - /** - * @description Aditional data about the images. Does not have to be displayed. - * All fields are optional. - */ - readonly ImageMetadata: { - /** @description optional date description */ - readonly date?: string; - /** @description optional location description */ - readonly location?: string; - /** @description optional coordinates in lat,lon */ - readonly geo?: string; - /** - * @description optional in contrast to source this points to the image itself. - * You should not use this to request the images, as they are not scaled. - */ - readonly image_url?: string; - /** @description optional caption */ - readonly caption?: string; - /** @description optional headline */ - readonly headline?: string; - /** @description optional the event this image was taken at */ - readonly event?: string; - /** @description optional the event this image is about */ - readonly faculty?: string; - /** @description optional the building this image is about */ - readonly building?: string; - /** @description optional the department this image is about */ - readonly department?: string; - }; - /** @description Additional information you should include, if you decide to display the image for legal and attribution reasons */ - readonly PossibleURLRef: { - /** @description The text to display */ - readonly text: string; - /** @description The URL to the referenced information. Always either null or a valid URL */ - readonly url?: string | null; - }; - readonly Coordinate: { - /** - * Format: double - * @description The latitude - * @example 48.26244490906312 - */ - readonly lat: number; - /** - * Format: double - * @description The latitude - * @example 48.26244490906312 - */ - readonly lon: number; - /** - * @description The source of the Coordinates - * @example roomfinder - * @enum {string} - */ - readonly source: "roomfinder" | "navigatum" | "inferred"; - /** - * @description How accurate the coordinate is. Only present, if it is limited to a degree (e.g. we only know the building) - * @example building - * @enum {string} - */ - readonly accuracy?: "building"; - }; - readonly Maps: { - /** - * @description The type of the Map that should be shown by default - * @enum {string} - */ - readonly default: "interactive" | "roomfinder"; - readonly roomfinder?: components["schemas"]["RoomfinderMap"]; - /** - * @description null would mean no overlay maps are displayed by default. - * For rooms you should add a warning that no floor map is available for this room - */ - readonly overlays?: { - /** - * @description The floor-id of the map, that should be shown as a default. - * null: - * - We suggest, you dont show a map by default. - * - This is only the case for buildings or other such entities and not for rooms, if we know where they are and a map exists - * - * @example 0 - */ - readonly default: number | null; - readonly available: readonly components["schemas"]["OverlayMapEntry"][]; - } | null; - }; - readonly RoomfinderMap: { - /** - * @description The id of the map, that should be shown as a default - * @example rf142 - */ - readonly default: string; - readonly available: readonly components["schemas"]["RoomfinderMapEntry"][]; - }; - readonly RoomfinderMapEntry: { - /** - * @description The human-readable name of the map - * @example FMI Übersicht - */ - readonly name: string; - /** - * @description The machine-readable name of the map - * @example rf142 - */ - readonly id: string; - /** - * @description Scale of the map. 2000 means 1:2000. - * @example 2000 - */ - readonly scale: string; - /** - * Format: int32 - * @description Map image x dimensions - * @example 461 - */ - readonly height: number; - /** - * Format: int32 - * @description Map image y dimensions - * @example 639 - */ - readonly width: number; - /** - * Format: int32 - * @description x Position on map - * @example 499 - */ - readonly x: number; - /** - * Format: int32 - * @description y Position on map image - * @example 189 - */ - readonly y: number; - /** - * @description Where the map was imported from - * @example Roomfinder - */ - readonly source: string; - /** - * @description Where the map is stored - * @example rf93.webp - */ - readonly file: string; - }; - readonly OverlayMapEntry: { - /** - * @description The machine-readable floor-id of the map. - * Should start with 0 for the ground level (defined by the main entrance) and increase or decrease. - * It is not guaranteed that numbers are consecutive or that `1` corresponds to level `01`, because buildings sometimes have more complicated layouts. They are however always in the correct (physical) order. - * - * @example 0 - */ - readonly id: number; - /** - * @description Floor of the Map. - * Should be used for display to the user in selectors. - * Matches the floor part of the TUMonline roomcode. - * - * @example EG - */ - readonly floor: string; - /** - * @description The human-readable name of the map - * @example MI Gebäude (EG) - */ - readonly name: string; - /** - * @description The filename of the map - * @example webp/rf95.webp - */ - readonly file: string; - /** @description Coordinates are four [lon, lat] pairs, for the top left, top right, bottom right, bottom left image corners. */ - readonly coordinates: readonly [ - readonly [number, number], - readonly [number, number], - readonly [number, number], - readonly [number, number], - ]; - }; - readonly Rooms: { - /** - * @description These indicate the type of item this represents - * @example rooms - * @enum {string} - */ - readonly facet: "rooms"; - /** - * Format: int64 - * @description The estimated (not exact) number of hits for that query - */ - readonly estimatedTotalHits: number; - readonly entries: readonly components["schemas"]["RoomEntry"][]; - /** - * Format: int64 - * @description A recommendation how many of the entries should be displayed by default. - * The number is usually from 0-20. - * More results might be displayed when clicking "expand". - * If this field is not present, then all entries are displayed. - * - * @example 20 - */ - readonly n_visible: number; - }; - readonly SitesBuildings: { - /** - * @description These indicate the type of item this represents - * @example sites_buildings - * @enum {string} - */ - readonly facet: "sites_buildings"; - /** - * Format: int64 - * @description The estimated (not exact) number of hits for that query - */ - readonly estimatedTotalHits: number; - readonly entries: readonly components["schemas"]["SitesBuildingsEntry"][]; - /** - * Format: int64 - * @description A recommendation how many of the entries should be displayed by default. - * The number is usually from 0-5. - * More results might be displayed when clicking "expand". - * If this field is not present, then all entries are displayed. - * - * @example 6 - */ - readonly n_visible: number; - }; - readonly RoomEntry: { - /** @description The id of the room */ - readonly id: string; - /** - * @description the type of the room - * @example room - * @enum {string} - */ - readonly type: "room" | "virtual_room" | "poi"; - /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ - readonly name: string; - /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ - readonly subtext: string; - /** @description Subtext to show below the search (by default in bold and after the non-bold subtext). Usually contains the arch-id of the room, which is another common room id format, and supports highlighting. */ - readonly subtext_bold: string; - /** @description This is an optional feature, that is only supported for some rooms. It might be displayed instead or before the name, to show that a different room id format has matched, that was probably used. See the image below for an example. It will be cropped to a maximum length to not take too much space in UIs. Supports highlighting. */ - readonly parsed_id?: string; - }; - readonly SitesBuildingsEntry: { - /** @description The id of the room */ - readonly id: string; - /** - * @description the type of the site/building - * @example campus - * @enum {string} - */ - readonly type: "campus" | "building" | "area" | "site" | "joined_building"; - /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ - readonly name: string; - /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ - readonly subtext: string; - }; - readonly TokenResponse: { - /** @description The JWT token, that can be used to generate feedback */ - readonly token: string; - /** - * Format: int64 - * @description Unix timestamp of when the token was created - */ - readonly created_at: number; - }; - readonly SearchResponse: { - readonly sections: readonly (components["schemas"]["SitesBuildings"] | components["schemas"]["Rooms"])[]; - /** - * Format: int32 - * @description Time the search took in the server side, not including network delay - * Maximum as timeout. other timeouts (browser, your client) may be smaller - * Expected average is 10..50 for uncached, regular requests - * - * @example 42 - */ - readonly time_ms: number; - }; - readonly DetailsResponse: components["schemas"]["BaseDetailsResponse"] & { - /** @description The id, that was requested */ - readonly id: string; - /** - * @description The type of the entry - * @enum {string} - */ - readonly type: "room" | "building" | "joined_building" | "area" | "site" | "campus" | "poi"; - readonly coords: components["schemas"]["Coordinate"]; - readonly maps: components["schemas"]["Maps"]; - readonly sections?: { - readonly buildings_overview?: components["schemas"]["BuildingsOverview"]; - readonly rooms_overview?: components["schemas"]["RoomsOverview"]; - readonly featured_overview?: components["schemas"]["FeaturedOverview"]; - }; - readonly poi?: { - readonly mvg: readonly [components["schemas"]["Station"], ...components["schemas"]["Station"][]]; - }; - }; - readonly BuildingsOverview: { - readonly entries: readonly (components["schemas"]["ChildEntry"] & { - /** - * @description What should be displayed below this Building - * @example Gebäudekomplex mit 512 Räumen - */ - readonly subtext: string; - /** - * @description The thumbnail for the building - * @example mi_0.webp - */ - readonly thumb?: string; - })[]; - /** - * Format: int64 - * @description A recommendation how many of the entries should be displayed by default. - * The number is usually from 0-5. - * More results might be displayed when clicking "expand". - * If this field is not present, then all entries are displayed. - * - * @example 5 - */ - readonly n_visible: number; - }; - readonly RoomsOverview: { - readonly usages?: readonly { - /** - * @description Category Name - * @example Büro - */ - readonly name: string; - /** - * @description How many children this category has - * @example 126 - */ - readonly count: number; - readonly children: readonly components["schemas"]["ChildEntry"][]; - }[]; - }; - readonly FeaturedOverview: { - readonly entries: readonly (components["schemas"]["ChildEntry"] & { - /** - * @description What should be displayed below this Building - * @example Gebäudekomplex mit 512 Räumen - */ - readonly subtext: string; - /** - * @description The thumbnail for the building - * @example mi_0.webp - */ - readonly image_url: string; - })[]; - }; - readonly ChildEntry: { - /** - * @description The id of the entry - * @example mi - */ - readonly id: string; - /** - * @description Human display name - * @example Mathematik / Informatik - */ - readonly name: string; - }; - /** - * @description This is a list of all sites, that are available in the system. - * It is sorted by the number of rooms in the site, descending. - * The first entry is the site with the most importance - */ - readonly SitesOverview: readonly (components["schemas"]["ChildEntry"] & { - /** - * Format: int64 - * @description A recommendation how many of the entries should be displayed by default. - * The number is usually from 0-5. - * More results might be displayed when clicking "expand". - * If this field is not present, then all entries are displayed. - * - * @example 6 - */ - readonly n_visible: number; - /** - * @description A select list of buildings, that are in this site. - * Derived from the areatree. - */ - readonly children: readonly components["schemas"]["ChildEntry"][]; - })[]; - readonly RootResponse: components["schemas"]["BaseDetailsResponse"] & { - /** - * @description The id, that was requested - * @enum {string} - */ - readonly id: "root"; - /** - * @description The type of the entry - * @enum {string} - */ - readonly type: "root"; - readonly sites_overview: components["schemas"]["SitesOverview"]; - }; - readonly BaseDetailsResponse: { - /** @description The type of the entry in a human-readable form */ - readonly type_common_name: string; - /** - * @description The name of the entry in a human-readable form - * @example 5602.EG.001 (MI HS 1, Friedrich L. Bauer Hörsaal) - */ - readonly name: string; - /** - * @description A list of alternative ids for this entry. - * - * Not to be confused with - * - `id` which is the unique identifier or - * - `visual-id` which is an alternative identifier for the entry (only displayed in the URL). - */ - readonly aliases?: readonly string[]; - readonly parents: readonly string[]; - readonly parent_names: readonly [string, ...string[]]; - readonly props: components["schemas"]["Props"]; - readonly imgs?: readonly components["schemas"]["ImageInfo"][]; - readonly ranking_factors: components["schemas"]["RankingFactors"]; - readonly sources: components["schemas"]["DataSources"]; - /** - * @description The url, this item should be displayed at. - * Present on both redirects and normal entries, to allow for the common /view/:id path - * - * @example /room/5602.EG.001 - */ - readonly redirect_url: string; - }; - readonly CalendarResponse: { - /** @description The entries of the requested */ - readonly events: readonly components["schemas"]["CalendarEntry"][]; - /** - * Format: date-time - * @description When the last sync with TUMonline happened. - * @example 2018-01-01T00:00:00 - */ - readonly last_sync: string; - /** - * @description Link to the same calendar, but in TUMonline - * @example https://campus.tum.de/tumonline/wbKalender.wbRessource?pResNr=12543 - */ - readonly calendar_url: string; - }; - readonly CalendarEntry: { - /** - * Format: int32 - * @description The id of the calendar entry used in TUMonline internally - * @example 42 - */ - readonly id: number; - /** - * @description The title of the Entry - * @example Quantenteleportation - */ - readonly title: string; - /** - * Format: date-time - * @description The start of the entry - * @example 2018-01-01T00:00:00 - */ - readonly start: string; - /** - * Format: date-time - * @description The end of the entry - * @example 2018-01-01T00:00:00 - */ - readonly end: string; - /** - * @description What this calendar entry means. Each of these should be displayed in a different color - * @enum {string} - */ - readonly entry_type: "lecture" | "exercise" | "exam" | "barred" | "other"; - /** - * @description For some Entrys, we do have more information (what kind of a `lecture` is it? What kind of an other `entry` is it?) - * @example Vorlesung mit Zentralübung - */ - readonly detailed_entry_type: string; - }; - /** @description Where we got our data from, should be displayed at the bottom of any page containing this data */ - readonly DataSources: { - /** - * @description Was this entry patched by us? (e.g. to fix a typo in the name/...) - * If so, we should not display the source, as it is not the original source. - */ - readonly patched?: boolean; - /** @description What is the basis of the data we have */ - readonly base: readonly { - /** - * @description The name of the provider - * @example NavigaTUM - */ - readonly name: string; - /** - * @description The url of the provider - * @example https://nav.tum.de - */ - readonly url?: string; - }[]; - }; - readonly RankingFactors: { - /** - * Format: int32 - * @description How much the combined ranking is important - */ - readonly rank_combined: number; - /** - * Format: int32 - * @description How much the type is important - */ - readonly rank_type: number; - /** - * Format: int32 - * @description How much the usage is important - */ - readonly rank_usage: number; - /** - * Format: int32 - * @description Automatic boost or suppression based on entry properties: - * - numbers of buildings for a `campus`/`area`/`site`, - * - numbers of seats for a `room`, - * - number of regular rooms for a `building`/`joined_building` - */ - readonly rank_boost?: number; - /** - * Format: int32 - * @description Custom boost or suppression factor defined by us - */ - readonly rank_custom?: number; - }; - readonly ProposeEditsRequest: components["schemas"]["TokenRequest"] & { - /** @description The edits to be made to the room. The keys are the ID of the props to be edited, the values are the proposed Edits. */ - readonly edits: { - [key: string]: { - readonly coordinate?: { - /** Format: double */ - readonly lat: number; - /** Format: double */ - readonly lon: number; - }; - readonly image?: { - readonly metadata: { - readonly author: string; - readonly license: components["schemas"]["LinkProp"]; - readonly source: components["schemas"]["LinkProp"]; - readonly offsets?: { - /** Format: int32 */ - readonly header?: number; - /** Format: int32 */ - readonly thumb?: number; - }; - readonly meta?: { - [key: string]: string; - }; - }; - /** - * Format: byte - * @description The image encoded as base64 - */ - readonly content: string; - }; - }; - }; - /** - * @description Additional context for the edit. - * Will be displayed in the discription field of the PR - * - * @example I have a picture of the room, please add it to the roomfinder - */ - readonly additional_context: string; - }; - readonly PostFeedbackRequest: components["schemas"]["TokenRequest"] & { - /** - * @description The category of the feedback. - * Enum attribute is softly enforced: Any value not listed below will be replaced by "other" - * @example bug - * @enum {string} - */ - readonly category: "bug" | "feature" | "search" | "entry" | "general" | "other"; - /** - * @description The subject/title of the feedback - * @example A catchy title - */ - readonly subject: string; - /** - * @description The body/description of the feedback - * @example A clear description what happened where and how we should improve it - */ - readonly body: string; - /** - * @description Whether the user has requested to delete the issue. - * If the user has requested to delete the issue, we will delete it from GitHub after processing it - * If the user has not requested to delete the issue, we will not delete it from GitHub and it will remain as a closed issue. - * - * @example true - */ - readonly deletion_requested: boolean; - }; - readonly TokenRequest: { - /** - * @description The JWT token, that can be used to generate feedback - * @example eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Njk2MzczODEsImlhdCI6MTY2OTU5NDE4MSwibmJmIjoxNjY5NTk0MTkxLCJraWQiOjE1ODU0MTUyODk5MzI0MjU0Mzg2fQ.sN0WwXzsGhjOVaqWPe-Fl5x-gwZvh28MMUM-74MoNj4 - */ - readonly token: string; - /** - * @description Whether the user has checked the privacy-checkbox. We are posting the feedback publicly on GitHub (not a EU-Company). You have to also include such a checkmark. - * @example true - */ - readonly privacy_checked: boolean; - }; - readonly Station: { - /** Format: double */ - readonly distance: number; - readonly station_id: string; - readonly name: string; - /** Format: double */ - readonly lat: number; - /** Format: double */ - readonly lon: number; - readonly sub_stations: readonly { - readonly station_id: string; - readonly name: string; - /** Format: double */ - readonly lat: number; - /** Format: double */ - readonly lon: number; - }[]; - }; - }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; -}; - -export type $defs = Record; - -export type external = Record; - -export type operations = { - /** - * Search entries - * @description This endpoint is designed to support search-as-you-type results. - * - * Instead of simply returning a list, the search results are returned in a way to provide a richer experience by splitting them up into sections. You might not necessarily need to implement all types of sections, or all sections features (if you just want to show a list). The order of sections is a suggested order to display them, but you may change this as you like. - * - * Some fields support highlighting the query terms and it uses \x19 and \x17 to mark the beginning/end of a highlighted sequence. - * (See [Wikipedia](https://en.wikipedia.org/wiki/C0_and_C1_control_codes#Modified_C0_control_code_sets)). - * Some text-renderers will ignore them, but in case you do not want to use them, you might want to remove them from the responses via empty `pre_highlight` and `post_highlight` query parameters. - */ - search: { - parameters: { - query: { - /** - * @description string you want to search for. - * Note, that the amounts returned can be controlled using the limit\* paramerters. - * - * The following query-filters are supported: - * - `in:`: Only return rooms in the given parent (e.g. `in:5304` or `in:garching`) - * alternative syntax: - * - `@` - * - `usage:`: Only return entries of the given usage (e.g. `usage:wc` or `usage:büro`) - * alternative syntax: - * - `nutzung:` - * - `=` - * - `type:`: Only return entries of the given type (e.g. `type:building` or `type:room`) - */ - q: string; - /** - * @description Maximum number of buildings/sites to return. - * Clamped to 0..1000. If this is an problem for you, please open an issue. - */ - limit_buildings?: number; - /** - * @description Maximum number of rooms to return. - * Clamped to 0..1000. If this is an problem for you, please open an issue. - */ - limit_rooms?: number; - /** - * @description Overall maximum number of results. Only visible results are counted (i.e. hidden buildings are not counted). - * Clamped to 1..1000. If this is an problem for you, please open an issue. - */ - limit_all?: number; - /** - * @description string to include in front of highlighted sequences. - * If this and `post_highlight` are empty, highlighting is disabled. - */ - pre_highlight?: string; - /** - * @description string to include after the highlighted sequences. - * If this and `pre_highlight` are empty, highlighting is disabled. - */ - post_highlight?: string; - }; - }; - responses: { - /** @description The search-result */ - 200: { - content: { - readonly "application/json": components["schemas"]["SearchResponse"]; - }; - }; - /** @description Invalid Request */ - 400: { - content: never; - }; - /** @description `search_query` is empty. Since searching for nothing is nonsensical, we dont support this. */ - 404: { - content: { - readonly "text/plain": "Not found"; - }; - }; - /** @description The uri you are trying to request is unreasonably long. Search querys dont have thousands of chars.. */ - 414: { - content: never; - }; - }; - }; - /** - * Get entry-details - * @description This returns the full data available for the entry (room/building). - * - * This is more data, that should be supplied once a user clicks on an entry. - * Preloading this is not an issue on our end, but keep in mind bandwith constraints on your side. - * The data can be up to 50kB (using gzip) or 200kB unzipped. - * The more about this data format is described in the NavigaTUM-data documentation - */ - details: { - parameters: { - query?: { - /** @description The language you want your details to be in. If either this or the query parameter is set to en, this will be delivered. */ - lang?: "de" | "en"; - }; - path: { - /** @description string you want to search for */ - id: string; - }; - }; - responses: { - /** @description More data about the requested building/room */ - 200: { - content: { - readonly "application/json": components["schemas"]["RootResponse"] | components["schemas"]["DetailsResponse"]; - }; - }; - /** @description Invalid input */ - 404: { - content: { - readonly "text/plain": "Not found"; - }; - }; - }; - }; - /** - * Retrieve Calendar Entries - * @description Retrieves calendar entries for a specific `id` within the requested time span. - * The time span is defined by the `start_after` and `end_before` query parameters. - * Ensure to provide valid date-time formats for these parameters. - * - * If successful, returns additional entries in the requested time span. - */ - calendar: { - parameters: { - query: { - /** @description The first allowed time the calendar would like to display */ - start_after: string; - /** @description The last allowed time the calendar would like to display */ - end_before: string; - }; - path: { - /** @description string you want to search for */ - id: string; - }; - }; - responses: { - /** @description More entries of the calendar in the requested time span */ - 200: { - content: { - readonly "application/json": components["schemas"]["CalendarResponse"]; - }; - }; - /** @description Invalid input */ - 404: { - content: { - readonly "text/plain": "Not found"; - }; - }; - /** @description Not Ready, please retry later */ - 503: { - content: { - readonly "text/plain": "Waiting for first sync with TUMonline"; - }; - }; - }; - }; - /** - * Get a entry-preview - * @description This returns a 1200x630px preview for the location (room/building/..). - * - * This is usefully for implementing custom OpenGraph images for detail previews. - */ - previews: { - parameters: { - query?: { - /** @description The language you want your preview to be in. If either this or the query parameter is set to en, this will be delivered. */ - lang?: "de" | "en"; - }; - path: { - /** @description string you want to search for */ - id: string; - }; - }; - responses: { - /** @description More data about the requested building/room */ - 200: { - content: { - readonly "image/png": unknown; - }; - }; - /** @description Invalid input */ - 404: { - content: { - readonly "text/plain": "Not found"; - }; - }; - }; - }; - /** - * Get a feedback-token - * @description ***Do not abuse this endpoint.*** - * - * This returns a JWT token usable for submitting feedback. - * You should request a token, ***if (and only if) a user is on a feedback page*** - * - * As a rudimentary way of rate-limiting feedback, this endpoint returns a token. - * To post feedback, you will need this token. - * - * Tokens gain validity after 5s, and are invalid after 12h of being issued. - * They are not refreshable, and are only valid for one usage. - * - * ***Important Note:*** - * Global Rate-Limiting allows bursts with up to 20 requests and replenishes 50 requests per day - */ - get_token: { - responses: { - /** @description Returns a usable token */ - 201: { - content: { - readonly "application/json": components["schemas"]["TokenResponse"]; - }; - }; - /** - * @description Too many requests. - * We are rate-limiting everyone's requests, please try again later. - */ - 429: { - content: never; - }; - /** - * @description Service unavailable. - * We have not configured a GitHub Access Token or a JWT Key. - * This could be because we are experiencing technical difficulties or intentional if we experience abuse of these endpoints. - * Please try again later. - */ - 503: { - content: never; - }; - }; - }; - /** - * Post feedback - * @description ***Do not abuse this endpoint.*** - * - * This posts the actual feedback to github and returns the github link. - * This API will create issues instead of pull-requests => all feedback is allowed, but `/api/feedback/propose_edit` is prefered, if it can be posted there. - * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. - * - * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid - */ - post_feedback: { - readonly requestBody?: { - readonly content: { - readonly "application/json": components["schemas"]["PostFeedbackRequest"]; - }; - }; - responses: { - /** - * @description The feedback has been successfully posted to GitHub. - * We return the link to the GitHub issue. - */ - 201: { - content: { - readonly "text/plain": string; - }; - }; - /** @description If not all fields in the body are present as defined above */ - 400: { - content: never; - }; - /** - * @description Forbidden. Causes are (delivered via the body): - * - * - `Invalid token`: You have not supplied a token generated via the `gen_token`-Endpoint. - * - `Token not old enough, please wait`: Tokens are only valid after 10s. - * - `Token expired`: Tokens are only valid for 12h. - * - `Token already used`: Tokens are non reusable/refreshable single-use items. - */ - 403: { - content: { - readonly "text/plain": - | "Invalid token" - | "Token not old enough, please wait" - | "Token expired" - | "Token already used"; - }; - }; - /** - * @description Unprocessable Entity - * Subject or body missing or too short. - */ - 422: { - content: never; - }; - /** - * @description Unavailable for legal reasons. - * Using this endpoint without accepting the privacy policy is not allowed. - * For us to post to GitHub, this has to be true - */ - 451: { - content: never; - }; - /** - * @description Internal Server Error. - * We have a problem communicating with GitHubs servers. Please try again later. - */ - 500: { - content: never; - }; - /** - * @description Service unavailable. - * We have not configured a GitHub Access Token. - * This could be because we are experiencing technical difficulties or intentional. Please try again later. - */ - 503: { - content: never; - }; - }; - }; - /** - * Post Edit-Requests - * @description ***Do not abuse this endpoint.*** - * - * This posts the actual feedback to github and returns the github link. - * This API will create pull-requests instead of issues => only a subset of feedback is allowed. - * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. - * - * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid - */ - propose_edit: { - readonly requestBody?: { - readonly content: { - readonly "application/json": components["schemas"]["ProposeEditsRequest"]; - }; - }; - responses: { - /** - * @description The feedback has been successfully posted to GitHub. - * We return the link to the GitHub issue. - */ - 201: { - content: { - readonly "text/plain": string; - }; - }; - /** @description If not all fields in the body are present as defined above */ - 400: { - content: never; - }; - /** - * @description Forbidden. Causes are (delivered via the body): - * - * - `Invalid token`: You have not supplied a token generated via the `gen_token`-Endpoint. - * - `Token not old enough, please wait`: Tokens are only valid after 10s. - * - `Token expired`: Tokens are only valid for 12h. - * - `Token already used`: Tokens are non reusable/refreshable single-use items. - */ - 403: { - content: { - readonly "text/plain": - | "Invalid token" - | "Token not old enough, please wait" - | "Token expired" - | "Token already used"; - }; - }; - /** - * @description Unprocessable Entity - * Subject or body missing or too short. - */ - 422: { - content: never; - }; - /** - * @description Unavailable for legal reasons. - * Using this endpoint without accepting the privacy policy is not allowed. - * For us to post to GitHub, this has to be true - */ - 451: { - content: never; - }; - /** - * @description Internal Server Error. - * We have a problem communicating with GitHubs servers. Please try again later. - */ - 500: { - content: never; - }; - /** - * @description Service unavailable. - * We have not configured a GitHub Access Token. - * This could be because we are experiencing technical difficulties or intentional. Please try again later. - */ - 503: { - content: never; - }; - }; - }; - /** - * Get title images - * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. - * You HAVE to get the proper attribution from that endpoint and use it. - */ - img_cdn: { - parameters: { - path: { - /** - * @description size of the resource you want - * - * | name | default | - * |--------|-----------------------------------------------------------------------| - * | lg | max 4k, aspect ratio untouched | - * | md | max 1920px, aspect ratio untouched | - * | sm | max 1024px, aspect ratio untouched | - * | thumb | 256x256, cropped to fit. Usually a center-crop, but sometimes offset. | - * | header | 512x210, cropped to fit. Usually a center-crop, but sometimes offset. | - */ - size: "lg" | "md" | "sm" | "thumb" | "header"; - /** @description id of the recource you want an image for */ - id: string; - /** - * @description counter of the image you want. - * @example 0 - */ - counter: number; - }; - }; - responses: { - /** @description The image you requested */ - 200: { - content: { - readonly "image/webp": unknown; - }; - }; - /** - * @description Bad Request. - * The request was malformed. - * Please check your request and try again. - */ - 400: { - content: never; - }; - /** @description Requested Resource Not Found */ - 404: { - content: { - readonly "text/plain": "Not found"; - }; - }; - /** @description The uri you are trying to request is unreasonably long. neither ids, nor any other parameter has more than 30 chars.. */ - 414: { - content: never; - }; - }; - }; - /** - * Get title images - * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. - * You HAVE to get the proper attribution from that endpoint and use it. - */ - maps_cdn: { - parameters: { - path: { - /** @description source of the resource you want */ - source: "overlay" | "roomfinder"; - /** @description id of the map you want */ - id: string; - }; - }; - responses: { - /** @description The map you requested */ - 200: { - content: { - readonly "image/webp": unknown; - }; - }; - /** - * @description Bad Request. - * The request was malformed. - * Please check your request and try again. - */ - 400: { - content: never; - }; - /** @description Requested Resource Not Found */ - 404: { - content: { - readonly "text/plain": "Not found"; - }; - }; - /** @description The uri you are trying to request is unreasonably long. neither ids, nor any other parameter has more than 30 chars.. */ - 414: { - content: never; - }; - }; - }; - /** - * API healthcheck - * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. - */ - "api-health": { - responses: { - /** @description Ok */ - 200: { - content: { - readonly "text/plain": string; - }; - }; - /** @description Service Unavailable */ - 503: { - content: never; - }; - }; - }; - /** - * feedback-API healthcheck - * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. - */ - "feedback-health": { - responses: { - /** @description Ok */ - 200: { - content: { - readonly "text/plain": string; - }; - }; - /** @description Service Unavailable */ - 503: { - content: never; - }; - }; - }; - /** - * CDN healthcheck - * @description If this endpoint does not return 200, the CDN is experiencing a catastrophic outage. Should never happen. - */ - "cdn-health": { - responses: { - /** @description Ok */ - 200: { - content: { - readonly "text/plain": "healthy"; - }; - }; - /** @description Service Unavailable */ - 503: { - content: never; - }; - }; - }; - /** - * Website healthcheck - * @description If this endpoint does not return 200, the Website is experiencing a catastrophic outage. Should never happen. - */ - "web-health": { - responses: { - /** @description Ok */ - 200: { - content: { - readonly "text/plain": "healthy"; - }; - }; - /** @description Service Unavailable */ - 503: { - content: never; - }; - }; - }; -}; +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export type paths = { + "/api/search": { + /** + * Search entries + * @description This endpoint is designed to support search-as-you-type results. + * + * Instead of simply returning a list, the search results are returned in a way to provide a richer experience by splitting them up into sections. You might not necessarily need to implement all types of sections, or all sections features (if you just want to show a list). The order of sections is a suggested order to display them, but you may change this as you like. + * + * Some fields support highlighting the query terms and it uses \x19 and \x17 to mark the beginning/end of a highlighted sequence. + * (See [Wikipedia](https://en.wikipedia.org/wiki/C0_and_C1_control_codes#Modified_C0_control_code_sets)). + * Some text-renderers will ignore them, but in case you do not want to use them, you might want to remove them from the responses via empty `pre_highlight` and `post_highlight` query parameters. + */ + get: operations["search"]; + }; + "/api/get/{id}": { + /** + * Get entry-details + * @description This returns the full data available for the entry (room/building). + * + * This is more data, that should be supplied once a user clicks on an entry. + * Preloading this is not an issue on our end, but keep in mind bandwith constraints on your side. + * The data can be up to 50kB (using gzip) or 200kB unzipped. + * The more about this data format is described in the NavigaTUM-data documentation + */ + get: operations["details"]; + }; + "/api/calendar/{id}": { + /** + * Retrieve Calendar Entries + * @description Retrieves calendar entries for a specific `id` within the requested time span. + * The time span is defined by the `start_after` and `end_before` query parameters. + * Ensure to provide valid date-time formats for these parameters. + * + * If successful, returns additional entries in the requested time span. + */ + get: operations["calendar"]; + }; + "/api/preview/{id}": { + /** + * Get a entry-preview + * @description This returns a 1200x630px preview for the location (room/building/..). + * + * This is usefully for implementing custom OpenGraph images for detail previews. + */ + get: operations["previews"]; + }; + "/api/feedback/get_token": { + /** + * Get a feedback-token + * @description ***Do not abuse this endpoint.*** + * + * This returns a JWT token usable for submitting feedback. + * You should request a token, ***if (and only if) a user is on a feedback page*** + * + * As a rudimentary way of rate-limiting feedback, this endpoint returns a token. + * To post feedback, you will need this token. + * + * Tokens gain validity after 5s, and are invalid after 12h of being issued. + * They are not refreshable, and are only valid for one usage. + * + * ***Important Note:*** + * Global Rate-Limiting allows bursts with up to 20 requests and replenishes 50 requests per day + */ + post: operations["get_token"]; + }; + "/api/feedback/feedback": { + /** + * Post feedback + * @description ***Do not abuse this endpoint.*** + * + * This posts the actual feedback to github and returns the github link. + * This API will create issues instead of pull-requests => all feedback is allowed, but `/api/feedback/propose_edit` is prefered, if it can be posted there. + * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. + * + * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid + */ + post: operations["post_feedback"]; + }; + "/api/feedback/propose_edit": { + /** + * Post Edit-Requests + * @description ***Do not abuse this endpoint.*** + * + * This posts the actual feedback to github and returns the github link. + * This API will create pull-requests instead of issues => only a subset of feedback is allowed. + * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. + * + * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid + */ + post: operations["propose_edit"]; + }; + "/cdn/{size}/{id}_{counter}.webp": { + /** + * Get title images + * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. + * You HAVE to get the proper attribution from that endpoint and use it. + */ + get: operations["img_cdn"]; + }; + "/cdn/maps/{source}/{id}.webp": { + /** + * Get title images + * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. + * You HAVE to get the proper attribution from that endpoint and use it. + */ + get: operations["maps_cdn"]; + }; + "/api/status": { + /** + * API healthcheck + * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. + */ + get: operations["api-health"]; + }; + "/api/feedback/status": { + /** + * feedback-API healthcheck + * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. + */ + get: operations["feedback-health"]; + }; + "/cdn/health": { + /** + * CDN healthcheck + * @description If this endpoint does not return 200, the CDN is experiencing a catastrophic outage. Should never happen. + */ + get: operations["cdn-health"]; + }; + "/health": { + /** + * Website healthcheck + * @description If this endpoint does not return 200, the Website is experiencing a catastrophic outage. Should never happen. + */ + get: operations["web-health"]; + }; +}; + +export type webhooks = Record; + +export type components = { + schemas: { + /** @description Data for the info-card table */ + readonly Props: { + /** @description The operator of the room */ + readonly operator?: { + /** + * @description The designation code of the operator + * @example TUS7000 + */ + readonly code?: string; + /** + * @description The full name of the operator (localized). Null for organisations that + * are no longer active (e.g. id=38698), but where the operator has not been + * updated in TUMonline. + * + * @example TUM School of Social Sciences and Technology + */ + readonly name?: string | null; + /** + * @description A link to the operator + * @example https://campus.tum.de/tumonline/webnav.navigate_to?corg=51901 + */ + readonly url?: string; + /** + * @description The id of the operator + * @example 51901 + */ + readonly id?: number; + }; + readonly computed: readonly components["schemas"]["ComputedProp"][]; + readonly links?: readonly components["schemas"]["LinkProp"][]; + /** + * @description A comment to show to an entry. + * It is used in the rare cases, where some aspect about the rooom/.. or its translation are misleading. + * An example of a room with a comment is MW1801. + */ + readonly comment?: string; + /** @description A link to the calendar of the room */ + readonly calendar_url?: string; + }; + readonly ComputedProp: { + /** @example Raumkennung */ + readonly name: string; + /** @example 5602.EG.001 */ + readonly text: string; + readonly extra?: { + /** @example Genauere Angaben */ + readonly header?: string; + /** @example für Prüfungen: 102 in eng, 71 in weit, 49 in corona */ + readonly body: string; + /** @example data based on a Survey of chimneysweeps */ + readonly footer?: string; + }; + }; + /** @description A link with a localized link text and url */ + readonly LinkProp: { + readonly text: string; + readonly url: string; + }; + /** @description The information you need to request Images from the /cdn/{size}/{id}_{counter}.webp endpoint */ + readonly ImageInfo: { + /** + * @description The name of the image file. consists of {building_id}_{image_id}.webp, where image_id is a counter starting at 0 + * @example mi_0.webp + */ + readonly name: string; + readonly author: components["schemas"]["PossibleURLRef"]; + readonly source: components["schemas"]["PossibleURLRef"]; + readonly license: components["schemas"]["PossibleURLRef"]; + readonly meta?: components["schemas"]["ImageMetadata"]; + }; + /** + * @description Aditional data about the images. Does not have to be displayed. + * All fields are optional. + */ + readonly ImageMetadata: { + /** @description optional date description */ + readonly date?: string; + /** @description optional location description */ + readonly location?: string; + /** @description optional coordinates in lat,lon */ + readonly geo?: string; + /** + * @description optional in contrast to source this points to the image itself. + * You should not use this to request the images, as they are not scaled. + */ + readonly image_url?: string; + /** @description optional caption */ + readonly caption?: string; + /** @description optional headline */ + readonly headline?: string; + /** @description optional the event this image was taken at */ + readonly event?: string; + /** @description optional the event this image is about */ + readonly faculty?: string; + /** @description optional the building this image is about */ + readonly building?: string; + /** @description optional the department this image is about */ + readonly department?: string; + }; + /** @description Additional information you should include, if you decide to display the image for legal and attribution reasons */ + readonly PossibleURLRef: { + /** @description The text to display */ + readonly text: string; + /** @description The URL to the referenced information. Always either null or a valid URL */ + readonly url?: string | null; + }; + readonly Coordinate: { + /** + * Format: double + * @description The latitude + * @example 48.26244490906312 + */ + readonly lat: number; + /** + * Format: double + * @description The latitude + * @example 48.26244490906312 + */ + readonly lon: number; + /** + * @description The source of the Coordinates + * @example roomfinder + * @enum {string} + */ + readonly source: "roomfinder" | "navigatum" | "inferred"; + /** + * @description How accurate the coordinate is. Only present, if it is limited to a degree (e.g. we only know the building) + * @example building + * @enum {string} + */ + readonly accuracy?: "building"; + }; + readonly Maps: { + /** + * @description The type of the Map that should be shown by default + * @enum {string} + */ + readonly default: "interactive" | "roomfinder"; + readonly roomfinder?: components["schemas"]["RoomfinderMap"]; + /** + * @description null would mean no overlay maps are displayed by default. + * For rooms you should add a warning that no floor map is available for this room + */ + readonly overlays?: { + /** + * @description The floor-id of the map, that should be shown as a default. + * null: + * - We suggest, you dont show a map by default. + * - This is only the case for buildings or other such entities and not for rooms, if we know where they are and a map exists + * + * @example 0 + */ + readonly default: number | null; + readonly available: readonly components["schemas"]["OverlayMapEntry"][]; + } | null; + }; + readonly RoomfinderMap: { + /** + * @description The id of the map, that should be shown as a default + * @example rf142 + */ + readonly default: string; + readonly available: readonly components["schemas"]["RoomfinderMapEntry"][]; + }; + readonly RoomfinderMapEntry: { + /** + * @description The human-readable name of the map + * @example FMI Übersicht + */ + readonly name: string; + /** + * @description The machine-readable name of the map + * @example rf142 + */ + readonly id: string; + /** + * @description Scale of the map. 2000 means 1:2000. + * @example 2000 + */ + readonly scale: string; + /** + * Format: int32 + * @description Map image x dimensions + * @example 461 + */ + readonly height: number; + /** + * Format: int32 + * @description Map image y dimensions + * @example 639 + */ + readonly width: number; + /** + * Format: int32 + * @description x Position on map + * @example 499 + */ + readonly x: number; + /** + * Format: int32 + * @description y Position on map image + * @example 189 + */ + readonly y: number; + /** + * @description Where the map was imported from + * @example Roomfinder + */ + readonly source: string; + /** + * @description Where the map is stored + * @example rf93.webp + */ + readonly file: string; + }; + readonly OverlayMapEntry: { + /** + * @description The machine-readable floor-id of the map. + * Should start with 0 for the ground level (defined by the main entrance) and increase or decrease. + * It is not guaranteed that numbers are consecutive or that `1` corresponds to level `01`, because buildings sometimes have more complicated layouts. They are however always in the correct (physical) order. + * + * @example 0 + */ + readonly id: number; + /** + * @description Floor of the Map. + * Should be used for display to the user in selectors. + * Matches the floor part of the TUMonline roomcode. + * + * @example EG + */ + readonly floor: string; + /** + * @description The human-readable name of the map + * @example MI Gebäude (EG) + */ + readonly name: string; + /** + * @description The filename of the map + * @example webp/rf95.webp + */ + readonly file: string; + /** @description Coordinates are four [lon, lat] pairs, for the top left, top right, bottom right, bottom left image corners. */ + readonly coordinates: readonly [ + readonly [number, number], + readonly [number, number], + readonly [number, number], + readonly [number, number], + ]; + }; + readonly Rooms: { + /** + * @description These indicate the type of item this represents + * @example rooms + * @enum {string} + */ + readonly facet: "rooms"; + /** + * Format: int64 + * @description The estimated (not exact) number of hits for that query + */ + readonly estimatedTotalHits: number; + readonly entries: readonly components["schemas"]["RoomEntry"][]; + /** + * Format: int64 + * @description A recommendation how many of the entries should be displayed by default. + * The number is usually from 0-20. + * More results might be displayed when clicking "expand". + * If this field is not present, then all entries are displayed. + * + * @example 20 + */ + readonly n_visible: number; + }; + readonly SitesBuildings: { + /** + * @description These indicate the type of item this represents + * @example sites_buildings + * @enum {string} + */ + readonly facet: "sites_buildings"; + /** + * Format: int64 + * @description The estimated (not exact) number of hits for that query + */ + readonly estimatedTotalHits: number; + readonly entries: readonly components["schemas"]["SitesBuildingsEntry"][]; + /** + * Format: int64 + * @description A recommendation how many of the entries should be displayed by default. + * The number is usually from 0-5. + * More results might be displayed when clicking "expand". + * If this field is not present, then all entries are displayed. + * + * @example 6 + */ + readonly n_visible: number; + }; + readonly RoomEntry: { + /** @description The id of the room */ + readonly id: string; + /** + * @description the type of the room + * @example room + * @enum {string} + */ + readonly type: "room" | "virtual_room" | "poi"; + /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ + readonly name: string; + /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ + readonly subtext: string; + /** @description Subtext to show below the search (by default in bold and after the non-bold subtext). Usually contains the arch-id of the room, which is another common room id format, and supports highlighting. */ + readonly subtext_bold: string; + /** @description This is an optional feature, that is only supported for some rooms. It might be displayed instead or before the name, to show that a different room id format has matched, that was probably used. See the image below for an example. It will be cropped to a maximum length to not take too much space in UIs. Supports highlighting. */ + readonly parsed_id?: string; + }; + readonly SitesBuildingsEntry: { + /** @description The id of the room */ + readonly id: string; + /** + * @description the type of the site/building + * @example campus + * @enum {string} + */ + readonly type: "campus" | "building" | "area" | "site" | "joined_building"; + /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ + readonly name: string; + /** @description Subtext to show below the search result. Usually contains the context of where this rooms is located in. Currently not highlighted. */ + readonly subtext: string; + }; + readonly TokenResponse: { + /** @description The JWT token, that can be used to generate feedback */ + readonly token: string; + /** + * Format: int64 + * @description Unix timestamp of when the token was created + */ + readonly created_at: number; + }; + readonly SearchResponse: { + readonly sections: readonly (components["schemas"]["SitesBuildings"] | components["schemas"]["Rooms"])[]; + /** + * Format: int32 + * @description Time the search took in the server side, not including network delay + * Maximum as timeout. other timeouts (browser, your client) may be smaller + * Expected average is 10..50 for uncached, regular requests + * + * @example 42 + */ + readonly time_ms: number; + }; + readonly DetailsResponse: components["schemas"]["BaseDetailsResponse"] & { + /** @description The id, that was requested */ + readonly id: string; + /** + * @description The type of the entry + * @enum {string} + */ + readonly type: "room" | "building" | "joined_building" | "area" | "site" | "campus" | "poi"; + readonly coords: components["schemas"]["Coordinate"]; + readonly maps: components["schemas"]["Maps"]; + readonly sections?: { + readonly buildings_overview?: components["schemas"]["BuildingsOverview"]; + readonly rooms_overview?: components["schemas"]["RoomsOverview"]; + readonly featured_overview?: components["schemas"]["FeaturedOverview"]; + }; + readonly poi?: { + readonly mvg: readonly [components["schemas"]["Station"], ...components["schemas"]["Station"][]]; + }; + }; + readonly BuildingsOverview: { + readonly entries: readonly (components["schemas"]["ChildEntry"] & { + /** + * @description What should be displayed below this Building + * @example Gebäudekomplex mit 512 Räumen + */ + readonly subtext: string; + /** + * @description The thumbnail for the building + * @example mi_0.webp + */ + readonly thumb?: string; + })[]; + /** + * Format: int64 + * @description A recommendation how many of the entries should be displayed by default. + * The number is usually from 0-5. + * More results might be displayed when clicking "expand". + * If this field is not present, then all entries are displayed. + * + * @example 5 + */ + readonly n_visible: number; + }; + readonly RoomsOverview: { + readonly usages?: readonly { + /** + * @description Category Name + * @example Büro + */ + readonly name: string; + /** + * @description How many children this category has + * @example 126 + */ + readonly count: number; + readonly children: readonly components["schemas"]["ChildEntry"][]; + }[]; + }; + readonly FeaturedOverview: { + readonly entries: readonly (components["schemas"]["ChildEntry"] & { + /** + * @description What should be displayed below this Building + * @example Gebäudekomplex mit 512 Räumen + */ + readonly subtext: string; + /** + * @description The thumbnail for the building + * @example mi_0.webp + */ + readonly image_url: string; + })[]; + }; + readonly ChildEntry: { + /** + * @description The id of the entry + * @example mi + */ + readonly id: string; + /** + * @description Human display name + * @example Mathematik / Informatik + */ + readonly name: string; + }; + /** + * @description This is a list of all sites, that are available in the system. + * It is sorted by the number of rooms in the site, descending. + * The first entry is the site with the most importance + */ + readonly SitesOverview: readonly (components["schemas"]["ChildEntry"] & { + /** + * Format: int64 + * @description A recommendation how many of the entries should be displayed by default. + * The number is usually from 0-5. + * More results might be displayed when clicking "expand". + * If this field is not present, then all entries are displayed. + * + * @example 6 + */ + readonly n_visible: number; + /** + * @description A select list of buildings, that are in this site. + * Derived from the areatree. + */ + readonly children: readonly components["schemas"]["ChildEntry"][]; + })[]; + readonly RootResponse: components["schemas"]["BaseDetailsResponse"] & { + /** + * @description The id, that was requested + * @enum {string} + */ + readonly id: "root"; + /** + * @description The type of the entry + * @enum {string} + */ + readonly type: "root"; + readonly sites_overview: components["schemas"]["SitesOverview"]; + }; + readonly BaseDetailsResponse: { + /** @description The type of the entry in a human-readable form */ + readonly type_common_name: string; + /** + * @description The name of the entry in a human-readable form + * @example 5602.EG.001 (MI HS 1, Friedrich L. Bauer Hörsaal) + */ + readonly name: string; + /** + * @description A list of alternative ids for this entry. + * + * Not to be confused with + * - `id` which is the unique identifier or + * - `visual-id` which is an alternative identifier for the entry (only displayed in the URL). + */ + readonly aliases?: readonly string[]; + readonly parents: readonly string[]; + readonly parent_names: readonly [string, ...string[]]; + readonly props: components["schemas"]["Props"]; + readonly imgs?: readonly components["schemas"]["ImageInfo"][]; + readonly ranking_factors: components["schemas"]["RankingFactors"]; + readonly sources: components["schemas"]["DataSources"]; + /** + * @description The url, this item should be displayed at. + * Present on both redirects and normal entries, to allow for the common /view/:id path + * + * @example /room/5602.EG.001 + */ + readonly redirect_url: string; + }; + readonly CalendarResponse: { + /** @description The entries of the requested */ + readonly events: readonly components["schemas"]["CalendarEntry"][]; + /** + * Format: date-time + * @description When the last sync with TUMonline happened. + * @example 2018-01-01T00:00:00 + */ + readonly last_sync: string; + /** + * @description Link to the same calendar, but in TUMonline + * @example https://campus.tum.de/tumonline/wbKalender.wbRessource?pResNr=12543 + */ + readonly calendar_url: string; + }; + readonly CalendarEntry: { + /** + * Format: int32 + * @description The id of the calendar entry used in TUMonline internally + * @example 42 + */ + readonly id: number; + /** + * @description The title of the Entry + * @example Quantenteleportation + */ + readonly title: string; + /** + * Format: date-time + * @description The start of the entry + * @example 2018-01-01T00:00:00 + */ + readonly start: string; + /** + * Format: date-time + * @description The end of the entry + * @example 2018-01-01T00:00:00 + */ + readonly end: string; + /** + * @description What this calendar entry means. Each of these should be displayed in a different color + * @enum {string} + */ + readonly entry_type: "lecture" | "exercise" | "exam" | "barred" | "other"; + /** + * @description For some Entrys, we do have more information (what kind of a `lecture` is it? What kind of an other `entry` is it?) + * @example Vorlesung mit Zentralübung + */ + readonly detailed_entry_type: string; + }; + /** @description Where we got our data from, should be displayed at the bottom of any page containing this data */ + readonly DataSources: { + /** + * @description Was this entry patched by us? (e.g. to fix a typo in the name/...) + * If so, we should not display the source, as it is not the original source. + */ + readonly patched?: boolean; + /** @description What is the basis of the data we have */ + readonly base: readonly { + /** + * @description The name of the provider + * @example NavigaTUM + */ + readonly name: string; + /** + * @description The url of the provider + * @example https://nav.tum.de + */ + readonly url?: string; + }[]; + }; + readonly RankingFactors: { + /** + * Format: int32 + * @description How much the combined ranking is important + */ + readonly rank_combined: number; + /** + * Format: int32 + * @description How much the type is important + */ + readonly rank_type: number; + /** + * Format: int32 + * @description How much the usage is important + */ + readonly rank_usage: number; + /** + * Format: int32 + * @description Automatic boost or suppression based on entry properties: + * - numbers of buildings for a `campus`/`area`/`site`, + * - numbers of seats for a `room`, + * - number of regular rooms for a `building`/`joined_building` + */ + readonly rank_boost?: number; + /** + * Format: int32 + * @description Custom boost or suppression factor defined by us + */ + readonly rank_custom?: number; + }; + readonly ProposeEditsRequest: components["schemas"]["TokenRequest"] & { + /** @description The edits to be made to the room. The keys are the ID of the props to be edited, the values are the proposed Edits. */ + readonly edits: { + [key: string]: { + readonly coordinate?: { + /** Format: double */ + readonly lat: number; + /** Format: double */ + readonly lon: number; + }; + readonly image?: { + readonly metadata: { + readonly author: string; + readonly license: components["schemas"]["LinkProp"]; + readonly source: components["schemas"]["LinkProp"]; + readonly offsets?: { + /** Format: int32 */ + readonly header?: number; + /** Format: int32 */ + readonly thumb?: number; + }; + readonly meta?: { + [key: string]: string; + }; + }; + /** + * Format: byte + * @description The image encoded as base64 + */ + readonly content: string; + }; + }; + }; + /** + * @description Additional context for the edit. + * Will be displayed in the discription field of the PR + * + * @example I have a picture of the room, please add it to the roomfinder + */ + readonly additional_context: string; + }; + readonly PostFeedbackRequest: components["schemas"]["TokenRequest"] & { + /** + * @description The category of the feedback. + * Enum attribute is softly enforced: Any value not listed below will be replaced by "other" + * @example bug + * @enum {string} + */ + readonly category: "bug" | "feature" | "search" | "entry" | "general" | "other"; + /** + * @description The subject/title of the feedback + * @example A catchy title + */ + readonly subject: string; + /** + * @description The body/description of the feedback + * @example A clear description what happened where and how we should improve it + */ + readonly body: string; + /** + * @description Whether the user has requested to delete the issue. + * If the user has requested to delete the issue, we will delete it from GitHub after processing it + * If the user has not requested to delete the issue, we will not delete it from GitHub and it will remain as a closed issue. + * + * @example true + */ + readonly deletion_requested: boolean; + }; + readonly TokenRequest: { + /** + * @description The JWT token, that can be used to generate feedback + * @example eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Njk2MzczODEsImlhdCI6MTY2OTU5NDE4MSwibmJmIjoxNjY5NTk0MTkxLCJraWQiOjE1ODU0MTUyODk5MzI0MjU0Mzg2fQ.sN0WwXzsGhjOVaqWPe-Fl5x-gwZvh28MMUM-74MoNj4 + */ + readonly token: string; + /** + * @description Whether the user has checked the privacy-checkbox. We are posting the feedback publicly on GitHub (not a EU-Company). You have to also include such a checkmark. + * @example true + */ + readonly privacy_checked: boolean; + }; + readonly Station: { + /** Format: double */ + readonly distance: number; + readonly station_id: string; + readonly name: string; + /** Format: double */ + readonly lat: number; + /** Format: double */ + readonly lon: number; + readonly sub_stations: readonly { + readonly station_id: string; + readonly name: string; + /** Format: double */ + readonly lat: number; + /** Format: double */ + readonly lon: number; + }[]; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +}; + +export type $defs = Record; + +export type external = Record; + +export type operations = { + /** + * Search entries + * @description This endpoint is designed to support search-as-you-type results. + * + * Instead of simply returning a list, the search results are returned in a way to provide a richer experience by splitting them up into sections. You might not necessarily need to implement all types of sections, or all sections features (if you just want to show a list). The order of sections is a suggested order to display them, but you may change this as you like. + * + * Some fields support highlighting the query terms and it uses \x19 and \x17 to mark the beginning/end of a highlighted sequence. + * (See [Wikipedia](https://en.wikipedia.org/wiki/C0_and_C1_control_codes#Modified_C0_control_code_sets)). + * Some text-renderers will ignore them, but in case you do not want to use them, you might want to remove them from the responses via empty `pre_highlight` and `post_highlight` query parameters. + */ + search: { + parameters: { + query: { + /** + * @description string you want to search for. + * Note, that the amounts returned can be controlled using the limit\* paramerters. + * + * The following query-filters are supported: + * - `in:`: Only return rooms in the given parent (e.g. `in:5304` or `in:garching`) + * alternative syntax: + * - `@` + * - `usage:`: Only return entries of the given usage (e.g. `usage:wc` or `usage:büro`) + * alternative syntax: + * - `nutzung:` + * - `=` + * - `type:`: Only return entries of the given type (e.g. `type:building` or `type:room`) + */ + q: string; + /** + * @description Maximum number of buildings/sites to return. + * Clamped to 0..1000. If this is an problem for you, please open an issue. + */ + limit_buildings?: number; + /** + * @description Maximum number of rooms to return. + * Clamped to 0..1000. If this is an problem for you, please open an issue. + */ + limit_rooms?: number; + /** + * @description Overall maximum number of results. Only visible results are counted (i.e. hidden buildings are not counted). + * Clamped to 1..1000. If this is an problem for you, please open an issue. + */ + limit_all?: number; + /** + * @description string to include in front of highlighted sequences. + * If this and `post_highlight` are empty, highlighting is disabled. + */ + pre_highlight?: string; + /** + * @description string to include after the highlighted sequences. + * If this and `pre_highlight` are empty, highlighting is disabled. + */ + post_highlight?: string; + }; + }; + responses: { + /** @description The search-result */ + 200: { + content: { + readonly "application/json": components["schemas"]["SearchResponse"]; + }; + }; + /** @description Invalid Request */ + 400: { + content: never; + }; + /** @description `search_query` is empty. Since searching for nothing is nonsensical, we dont support this. */ + 404: { + content: { + readonly "text/plain": "Not found"; + }; + }; + /** @description The uri you are trying to request is unreasonably long. Search querys dont have thousands of chars.. */ + 414: { + content: never; + }; + }; + }; + /** + * Get entry-details + * @description This returns the full data available for the entry (room/building). + * + * This is more data, that should be supplied once a user clicks on an entry. + * Preloading this is not an issue on our end, but keep in mind bandwith constraints on your side. + * The data can be up to 50kB (using gzip) or 200kB unzipped. + * The more about this data format is described in the NavigaTUM-data documentation + */ + details: { + parameters: { + query?: { + /** @description The language you want your details to be in. If either this or the query parameter is set to en, this will be delivered. */ + lang?: "de" | "en"; + }; + path: { + /** @description string you want to search for */ + id: string; + }; + }; + responses: { + /** @description More data about the requested building/room */ + 200: { + content: { + readonly "application/json": components["schemas"]["RootResponse"] | components["schemas"]["DetailsResponse"]; + }; + }; + /** @description Invalid input */ + 404: { + content: { + readonly "text/plain": "Not found"; + }; + }; + }; + }; + /** + * Retrieve Calendar Entries + * @description Retrieves calendar entries for a specific `id` within the requested time span. + * The time span is defined by the `start_after` and `end_before` query parameters. + * Ensure to provide valid date-time formats for these parameters. + * + * If successful, returns additional entries in the requested time span. + */ + calendar: { + parameters: { + query: { + /** @description The first allowed time the calendar would like to display */ + start_after: string; + /** @description The last allowed time the calendar would like to display */ + end_before: string; + }; + path: { + /** @description string you want to search for */ + id: string; + }; + }; + responses: { + /** @description More entries of the calendar in the requested time span */ + 200: { + content: { + readonly "application/json": components["schemas"]["CalendarResponse"]; + }; + }; + /** @description Invalid input */ + 404: { + content: { + readonly "text/plain": "Not found"; + }; + }; + /** @description Not Ready, please retry later */ + 503: { + content: { + readonly "text/plain": "Waiting for first sync with TUMonline"; + }; + }; + }; + }; + /** + * Get a entry-preview + * @description This returns a 1200x630px preview for the location (room/building/..). + * + * This is usefully for implementing custom OpenGraph images for detail previews. + */ + previews: { + parameters: { + query?: { + /** @description The language you want your preview to be in. If either this or the query parameter is set to en, this will be delivered. */ + lang?: "de" | "en"; + }; + path: { + /** @description string you want to search for */ + id: string; + }; + }; + responses: { + /** @description More data about the requested building/room */ + 200: { + content: { + readonly "image/png": unknown; + }; + }; + /** @description Invalid input */ + 404: { + content: { + readonly "text/plain": "Not found"; + }; + }; + }; + }; + /** + * Get a feedback-token + * @description ***Do not abuse this endpoint.*** + * + * This returns a JWT token usable for submitting feedback. + * You should request a token, ***if (and only if) a user is on a feedback page*** + * + * As a rudimentary way of rate-limiting feedback, this endpoint returns a token. + * To post feedback, you will need this token. + * + * Tokens gain validity after 5s, and are invalid after 12h of being issued. + * They are not refreshable, and are only valid for one usage. + * + * ***Important Note:*** + * Global Rate-Limiting allows bursts with up to 20 requests and replenishes 50 requests per day + */ + get_token: { + responses: { + /** @description Returns a usable token */ + 201: { + content: { + readonly "application/json": components["schemas"]["TokenResponse"]; + }; + }; + /** + * @description Too many requests. + * We are rate-limiting everyone's requests, please try again later. + */ + 429: { + content: never; + }; + /** + * @description Service unavailable. + * We have not configured a GitHub Access Token or a JWT Key. + * This could be because we are experiencing technical difficulties or intentional if we experience abuse of these endpoints. + * Please try again later. + */ + 503: { + content: never; + }; + }; + }; + /** + * Post feedback + * @description ***Do not abuse this endpoint.*** + * + * This posts the actual feedback to github and returns the github link. + * This API will create issues instead of pull-requests => all feedback is allowed, but `/api/feedback/propose_edit` is prefered, if it can be posted there. + * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. + * + * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid + */ + post_feedback: { + readonly requestBody?: { + readonly content: { + readonly "application/json": components["schemas"]["PostFeedbackRequest"]; + }; + }; + responses: { + /** + * @description The feedback has been successfully posted to GitHub. + * We return the link to the GitHub issue. + */ + 201: { + content: { + readonly "text/plain": string; + }; + }; + /** @description If not all fields in the body are present as defined above */ + 400: { + content: never; + }; + /** + * @description Forbidden. Causes are (delivered via the body): + * + * - `Invalid token`: You have not supplied a token generated via the `gen_token`-Endpoint. + * - `Token not old enough, please wait`: Tokens are only valid after 10s. + * - `Token expired`: Tokens are only valid for 12h. + * - `Token already used`: Tokens are non reusable/refreshable single-use items. + */ + 403: { + content: { + readonly "text/plain": + | "Invalid token" + | "Token not old enough, please wait" + | "Token expired" + | "Token already used"; + }; + }; + /** + * @description Unprocessable Entity + * Subject or body missing or too short. + */ + 422: { + content: never; + }; + /** + * @description Unavailable for legal reasons. + * Using this endpoint without accepting the privacy policy is not allowed. + * For us to post to GitHub, this has to be true + */ + 451: { + content: never; + }; + /** + * @description Internal Server Error. + * We have a problem communicating with GitHubs servers. Please try again later. + */ + 500: { + content: never; + }; + /** + * @description Service unavailable. + * We have not configured a GitHub Access Token. + * This could be because we are experiencing technical difficulties or intentional. Please try again later. + */ + 503: { + content: never; + }; + }; + }; + /** + * Post Edit-Requests + * @description ***Do not abuse this endpoint.*** + * + * This posts the actual feedback to github and returns the github link. + * This API will create pull-requests instead of issues => only a subset of feedback is allowed. + * For this Endpoint to work, you need to generate a token via the `/api/feedback/get_token` endpoint. + * + * ***Important Note:*** Tokens are only used if we return a 201 Created response. Otherwise, they are still valid + */ + propose_edit: { + readonly requestBody?: { + readonly content: { + readonly "application/json": components["schemas"]["ProposeEditsRequest"]; + }; + }; + responses: { + /** + * @description The feedback has been successfully posted to GitHub. + * We return the link to the GitHub issue. + */ + 201: { + content: { + readonly "text/plain": string; + }; + }; + /** @description If not all fields in the body are present as defined above */ + 400: { + content: never; + }; + /** + * @description Forbidden. Causes are (delivered via the body): + * + * - `Invalid token`: You have not supplied a token generated via the `gen_token`-Endpoint. + * - `Token not old enough, please wait`: Tokens are only valid after 10s. + * - `Token expired`: Tokens are only valid for 12h. + * - `Token already used`: Tokens are non reusable/refreshable single-use items. + */ + 403: { + content: { + readonly "text/plain": + | "Invalid token" + | "Token not old enough, please wait" + | "Token expired" + | "Token already used"; + }; + }; + /** + * @description Unprocessable Entity + * Subject or body missing or too short. + */ + 422: { + content: never; + }; + /** + * @description Unavailable for legal reasons. + * Using this endpoint without accepting the privacy policy is not allowed. + * For us to post to GitHub, this has to be true + */ + 451: { + content: never; + }; + /** + * @description Internal Server Error. + * We have a problem communicating with GitHubs servers. Please try again later. + */ + 500: { + content: never; + }; + /** + * @description Service unavailable. + * We have not configured a GitHub Access Token. + * This could be because we are experiencing technical difficulties or intentional. Please try again later. + */ + 503: { + content: never; + }; + }; + }; + /** + * Get title images + * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. + * You HAVE to get the proper attribution from that endpoint and use it. + */ + img_cdn: { + parameters: { + path: { + /** + * @description size of the resource you want + * + * | name | default | + * |--------|-----------------------------------------------------------------------| + * | lg | max 4k, aspect ratio untouched | + * | md | max 1920px, aspect ratio untouched | + * | sm | max 1024px, aspect ratio untouched | + * | thumb | 256x256, cropped to fit. Usually a center-crop, but sometimes offset. | + * | header | 512x210, cropped to fit. Usually a center-crop, but sometimes offset. | + */ + size: "lg" | "md" | "sm" | "thumb" | "header"; + /** @description id of the recource you want an image for */ + id: string; + /** + * @description counter of the image you want. + * @example 0 + */ + counter: number; + }; + }; + responses: { + /** @description The image you requested */ + 200: { + content: { + readonly "image/webp": unknown; + }; + }; + /** + * @description Bad Request. + * The request was malformed. + * Please check your request and try again. + */ + 400: { + content: never; + }; + /** @description Requested Resource Not Found */ + 404: { + content: { + readonly "text/plain": "Not found"; + }; + }; + /** @description The uri you are trying to request is unreasonably long. neither ids, nor any other parameter has more than 30 chars.. */ + 414: { + content: never; + }; + }; + }; + /** + * Get title images + * @description This endpoint is designed to fetch the images, that are described by the `/api/get/{id}`-endpoint. + * You HAVE to get the proper attribution from that endpoint and use it. + */ + maps_cdn: { + parameters: { + path: { + /** @description source of the resource you want */ + source: "overlay" | "roomfinder"; + /** @description id of the map you want */ + id: string; + }; + }; + responses: { + /** @description The map you requested */ + 200: { + content: { + readonly "image/webp": unknown; + }; + }; + /** + * @description Bad Request. + * The request was malformed. + * Please check your request and try again. + */ + 400: { + content: never; + }; + /** @description Requested Resource Not Found */ + 404: { + content: { + readonly "text/plain": "Not found"; + }; + }; + /** @description The uri you are trying to request is unreasonably long. neither ids, nor any other parameter has more than 30 chars.. */ + 414: { + content: never; + }; + }; + }; + /** + * API healthcheck + * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. + */ + "api-health": { + responses: { + /** @description Ok */ + 200: { + content: { + readonly "text/plain": string; + }; + }; + /** @description Service Unavailable */ + 503: { + content: never; + }; + }; + }; + /** + * feedback-API healthcheck + * @description If this endpoint does not return 200, the API is experiencing a catastrophic outage. Should never happen. + */ + "feedback-health": { + responses: { + /** @description Ok */ + 200: { + content: { + readonly "text/plain": string; + }; + }; + /** @description Service Unavailable */ + 503: { + content: never; + }; + }; + }; + /** + * CDN healthcheck + * @description If this endpoint does not return 200, the CDN is experiencing a catastrophic outage. Should never happen. + */ + "cdn-health": { + responses: { + /** @description Ok */ + 200: { + content: { + readonly "text/plain": "healthy"; + }; + }; + /** @description Service Unavailable */ + 503: { + content: never; + }; + }; + }; + /** + * Website healthcheck + * @description If this endpoint does not return 200, the Website is experiencing a catastrophic outage. Should never happen. + */ + "web-health": { + responses: { + /** @description Ok */ + 200: { + content: { + readonly "text/plain": "healthy"; + }; + }; + /** @description Service Unavailable */ + 503: { + content: never; + }; + }; + }; +}; diff --git a/webclient/assets/main.scss b/webclient/assets/main.scss index ce3a8ecc0..2f35c7de6 100644 --- a/webclient/assets/main.scss +++ b/webclient/assets/main.scss @@ -1,17 +1,17 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -/* v-cloak is set until vue loaded */ -[v-cloak] { - display: none; -} - -.focusable { - @apply focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus-visible:outline-0; -} - -/* see https://www.youtube.com/watch?v=cH8VbLM1958 why this is here */ -* { - min-width: 0; -} +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* v-cloak is set until vue loaded */ +[v-cloak] { + display: none; +} + +.focusable { + @apply focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 focus-visible:outline-0; +} + +/* see https://www.youtube.com/watch?v=cH8VbLM1958 why this is here */ +* { + min-width: 0; +} diff --git a/webclient/components/AppFooter.vue b/webclient/components/AppFooter.vue index 992443288..c2fd879bd 100644 --- a/webclient/components/AppFooter.vue +++ b/webclient/components/AppFooter.vue @@ -1,119 +1,119 @@ - - - - - -de: - about: - link: /about/ueber-uns - text: Über uns - api: - link: /api - text: API - feedback: - open: Feedback Form öffnen - text: Feedback senden - imprint: - link: /about/impressum - text: Impressum - language: Sprache - official_roomfinder: Offizieller Roomfinder - privacy: - link: /about/datenschutz - text: Datenschutz - sourcecode: - text: Source Code - theme: Theme - tum_logo_alt: The Logo of the Technical University Munich -en: - about: - link: /en/about/about-us - text: About us - api: - link: /en/api - text: API - feedback: - open: Open the feedback-form - text: Feedback - imprint: - link: /en/about/imprint - text: Imprint - language: Language - official_roomfinder: Official roomfinder - privacy: - link: /en/about/privacy - text: Privacy - sourcecode: - text: Source Code - theme: Theme - tum_logo_alt: Das Logo der Technischen Universität München - + + + + + +de: + about: + link: /about/ueber-uns + text: Über uns + api: + link: /api + text: API + feedback: + open: Feedback Form öffnen + text: Feedback senden + imprint: + link: /about/impressum + text: Impressum + language: Sprache + official_roomfinder: Offizieller Roomfinder + privacy: + link: /about/datenschutz + text: Datenschutz + sourcecode: + text: Source Code + theme: Theme + tum_logo_alt: The Logo of the Technical University Munich +en: + about: + link: /en/about/about-us + text: About us + api: + link: /en/api + text: API + feedback: + open: Open the feedback-form + text: Feedback + imprint: + link: /en/about/imprint + text: Imprint + language: Language + official_roomfinder: Official roomfinder + privacy: + link: /en/about/privacy + text: Privacy + sourcecode: + text: Source Code + theme: Theme + tum_logo_alt: Das Logo der Technischen Universität München + diff --git a/webclient/components/AppNavHeader.vue b/webclient/components/AppNavHeader.vue index c87cf4951..ce13c19f7 100644 --- a/webclient/components/AppNavHeader.vue +++ b/webclient/components/AppNavHeader.vue @@ -1,17 +1,17 @@ - + diff --git a/webclient/components/AppSearchBar.vue b/webclient/components/AppSearchBar.vue index c67927657..298cc156a 100644 --- a/webclient/components/AppSearchBar.vue +++ b/webclient/components/AppSearchBar.vue @@ -1,260 +1,260 @@ - - - - - - - - -de: - category: Feedback-Kategorie - delete: Das zugehörige GitHub Issue löschen, sobald es gelöst wurde. - helptext: - bug: Welchen Fehler hast du gefunden? Wo hast du ihn gefunden? Bitte gib eine genaue Beschreibung an. - entry: Feedback zu einem Eintrag. Wir können Räume/Gebäude/Standorte hinzufügen und alle Daten, die du siehst (Namen, Koordinaten, Adressen, ...) anpassen. Was können wir verbessern? - feature: Features, die du gerne auf dieser Website haben würdest - general: Generelles Feedback über diese Website - other: "Feedback ist auf ein Problem gestoßen: Kategorie ungültig" - search: Feedback zur Suche. Was war dein Suchbegriff? Was hättest du als Ergebnis erwartet? - message: Nachricht - subject: Betreff - success: - response_at: Antwort auf dein Feedback findest du auf - thank_you: Vielen Dank für dein Feedback! Wir werden es schnellstmöglich bearbeiten. - this_issue: diesem GitHub Issue - type: - bug: Fehler - entry: Eintrag - feature: Features - general: Allgemein - search: Suche -en: - category: Feedback category - delete: Delete this GitHub issue when resolved. - helptext: - bug: Which bug did you find? Where did you find it? Please provide a detailed description. - entry: Feedback about an entry. We can add rooms/buildings/locations and adjust all data you see (names, coordinates, addresses, ...). What can we improve? - feature: Features you would like to see on this website - general: General Feedback about this website - other: "Feedback encountered issue: Category invalid" - search: Feedback about the search. What was your search query? What did you expect to see? - message: Message - subject: Subject - success: - response_at: You can see our response at - thank_you: Thank you for giving your feedback. We will work on this as soon as possible. - this_issue: this GitHub issue - type: - bug: Bug - entry: Entry - feature: Features - general: General - search: Search - + + + + + +de: + category: Feedback-Kategorie + delete: Das zugehörige GitHub Issue löschen, sobald es gelöst wurde. + helptext: + bug: Welchen Fehler hast du gefunden? Wo hast du ihn gefunden? Bitte gib eine genaue Beschreibung an. + entry: Feedback zu einem Eintrag. Wir können Räume/Gebäude/Standorte hinzufügen und alle Daten, die du siehst (Namen, Koordinaten, Adressen, ...) anpassen. Was können wir verbessern? + feature: Features, die du gerne auf dieser Website haben würdest + general: Generelles Feedback über diese Website + other: "Feedback ist auf ein Problem gestoßen: Kategorie ungültig" + search: Feedback zur Suche. Was war dein Suchbegriff? Was hättest du als Ergebnis erwartet? + message: Nachricht + subject: Betreff + success: + response_at: Antwort auf dein Feedback findest du auf + thank_you: Vielen Dank für dein Feedback! Wir werden es schnellstmöglich bearbeiten. + this_issue: diesem GitHub Issue + type: + bug: Fehler + entry: Eintrag + feature: Features + general: Allgemein + search: Suche +en: + category: Feedback category + delete: Delete this GitHub issue when resolved. + helptext: + bug: Which bug did you find? Where did you find it? Please provide a detailed description. + entry: Feedback about an entry. We can add rooms/buildings/locations and adjust all data you see (names, coordinates, addresses, ...). What can we improve? + feature: Features you would like to see on this website + general: General Feedback about this website + other: "Feedback encountered issue: Category invalid" + search: Feedback about the search. What was your search query? What did you expect to see? + message: Message + subject: Subject + success: + response_at: You can see our response at + thank_you: Thank you for giving your feedback. We will work on this as soon as possible. + this_issue: this GitHub issue + type: + bug: Bug + entry: Entry + feature: Features + general: General + search: Search + diff --git a/webclient/components/Modal.vue b/webclient/components/Modal.vue index 1dced96b9..1a9a55649 100644 --- a/webclient/components/Modal.vue +++ b/webclient/components/Modal.vue @@ -1,97 +1,97 @@ - - - - - -de: - close: Modal schließen -en: - close: close modal - + + + + + +de: + close: Modal schließen +en: + close: close modal + diff --git a/webclient/components/PreferencesPopup.vue b/webclient/components/PreferencesPopup.vue index 8bfa2b6b0..b1cdb3098 100644 --- a/webclient/components/PreferencesPopup.vue +++ b/webclient/components/PreferencesPopup.vue @@ -1,73 +1,73 @@ - - - - - -de: - preferences: Präferenzen - language: Sprache -en: - preferences: Preferences - language: Language - + + + + + +de: + preferences: Präferenzen + language: Sprache +en: + preferences: Preferences + language: Language + diff --git a/webclient/components/RoomfinderImageLocation.vue b/webclient/components/RoomfinderImageLocation.vue index 3082c7773..1de36a222 100644 --- a/webclient/components/RoomfinderImageLocation.vue +++ b/webclient/components/RoomfinderImageLocation.vue @@ -1,119 +1,119 @@ - - - - - -de: - img_alt: Bild des Lageplans - img_source: Bildquelle -en: - img_alt: Image showing the Site Plan - img_source: Image source - + + + + + +de: + img_alt: Bild des Lageplans + img_source: Bildquelle +en: + img_alt: Image showing the Site Plan + img_source: Image source + diff --git a/webclient/components/SearchResultItem.vue b/webclient/components/SearchResultItem.vue index 27bb4c872..ca4beaf53 100644 --- a/webclient/components/SearchResultItem.vue +++ b/webclient/components/SearchResultItem.vue @@ -1,63 +1,63 @@ - - - + + + diff --git a/webclient/components/SearchSectionList.vue b/webclient/components/SearchSectionList.vue index 6eaa89d1c..82986cd8f 100644 --- a/webclient/components/SearchSectionList.vue +++ b/webclient/components/SearchSectionList.vue @@ -1,60 +1,60 @@ - - - - - -de: - sections: - sites_buildings: Gebäude / Standorte - rooms: Räume - view_more: mehr anzeigen - approx_results: ca. {count} Ergebnisse, bitte grenze die Suche weiter ein - results: 1 Ergebnis | {count} Ergebnisse -en: - sections: - sites_buildings: Buildings / Sites - rooms: Rooms - view_more: view more - approx_results: approx. {count} results, please narrow the search further - results: 1 result | {count} results - + + + + + +de: + sections: + sites_buildings: Gebäude / Standorte + rooms: Räume + view_more: mehr anzeigen + approx_results: ca. {count} Ergebnisse, bitte grenze die Suche weiter ein + results: 1 Ergebnis | {count} Ergebnisse +en: + sections: + sites_buildings: Buildings / Sites + rooms: Rooms + view_more: view more + approx_results: approx. {count} results, please narrow the search further + results: 1 result | {count} results + diff --git a/webclient/components/SelectionOption.vue b/webclient/components/SelectionOption.vue index 8141e97ef..8684873db 100644 --- a/webclient/components/SelectionOption.vue +++ b/webclient/components/SelectionOption.vue @@ -1,22 +1,22 @@ - - - + + + diff --git a/webclient/components/SelectionSwitch.vue b/webclient/components/SelectionSwitch.vue index 59839ae61..2dd096c13 100644 --- a/webclient/components/SelectionSwitch.vue +++ b/webclient/components/SelectionSwitch.vue @@ -1,42 +1,42 @@ - - - + + + diff --git a/webclient/components/ShareButton.vue b/webclient/components/ShareButton.vue index 8ac99977f..0de5f6126 100644 --- a/webclient/components/ShareButton.vue +++ b/webclient/components/ShareButton.vue @@ -1,79 +1,79 @@ - - - - - -de: - copied: Kopiert - copy_link: Link kopieren - open_in: Öffnen in - other_app: Andere App ... - external_link: Externe Links - share: Teilen - share_link: Teilen mit ... -en: - copied: Copied - copy_link: Copy link - open_in: Open in - other_app: Other app ... - external_link: External links - share: Share - share_link: Share with ... - + + + + + +de: + copied: Kopiert + copy_link: Link kopieren + open_in: Öffnen in + other_app: Andere App ... + external_link: Externe Links + share: Teilen + share_link: Teilen mit ... +en: + copied: Copied + copy_link: Copy link + open_in: Open in + other_app: Other app ... + external_link: External links + share: Share + share_link: Share with ... + diff --git a/webclient/components/Spinner.vue b/webclient/components/Spinner.vue index c81f04613..b7795bb82 100644 --- a/webclient/components/Spinner.vue +++ b/webclient/components/Spinner.vue @@ -1,22 +1,22 @@ - - - + + + diff --git a/webclient/components/SwaggerUI.vue b/webclient/components/SwaggerUI.vue index bfd9b14d0..22d2f9892 100644 --- a/webclient/components/SwaggerUI.vue +++ b/webclient/components/SwaggerUI.vue @@ -1,34 +1,34 @@ - - - - - + + + + + diff --git a/webclient/components/TinyModal.vue b/webclient/components/TinyModal.vue index 1e9ddc380..19e93f00c 100644 --- a/webclient/components/TinyModal.vue +++ b/webclient/components/TinyModal.vue @@ -1,51 +1,51 @@ - - - - - -de: - show_more_information: Mehr Informationen anzeigen -en: - show_more_information: Show more information - + + + + + +de: + show_more_information: Mehr Informationen anzeigen +en: + show_more_information: Show more information + diff --git a/webclient/components/Toast.vue b/webclient/components/Toast.vue index 3f17b2ad0..d1a98a593 100644 --- a/webclient/components/Toast.vue +++ b/webclient/components/Toast.vue @@ -1,26 +1,26 @@ - - - + + + diff --git a/webclient/components/TokenBasedModal.vue b/webclient/components/TokenBasedModal.vue index 2ac12d728..02064cce9 100644 --- a/webclient/components/TokenBasedModal.vue +++ b/webclient/components/TokenBasedModal.vue @@ -1,279 +1,279 @@ - - - - - -de: - title: Feedback senden - cancel: Abbrechen - error: - token_unexpected_status: "Unerwarteter Status Code beim Abrufen eines Feedback Tokens: " - token_req_failed: Unerwarteter Fehler beim Laden des Feedback-Formulars. Das Senden von Feedback ist gerade vermutlich nicht möglich. Bitte schreibe stattdessen eine Mail. - too_many_requests: Feedback senden ist aktuell nicht möglich aufgrund von rate-limiting. Bitte versuche es später nochmal oder schreibe eine Mail. - send_invalid_token: Formular-Token ungültig (vermutlich abgelaufen). Bitte kopiere den Text und öffne das Formular nochmal. - please_accept_privacy_statement: Du musst die Datenschutzerklärung akzeptiert haben, damit wir dein Feedback via GitHub verarbeiten können. - feedback_not_configured: Das Senden von Feedback ist auf dem Server aktuell nicht konfiguriert. - send_no_token: Ein unerwarteter Fehler ist aufgetreten (Kein Token). Bitte kopiere den Text und öffne das Formular nochmal. - send_req_failed: Unerwarteter Fehler beim Senden des Feedback-Formulars. Das Senden von Feedback ist gerade vermutlich nicht möglich. Bitte schreibe stattdessen eine Mail. - form: - too_short_body: "Fehler: Nachricht fehlt oder ist zu kurz" - too_short_subject: "Fehler: Betreff fehlt oder ist zu kurz" - status: - send_unexpected_status: Unerwarteter Status Code - server_error: Server Fehler - public: - agreement: - pre: Meine Feedback Daten (Betreff und Nachricht) dürfen anonym, aber öffentlich zugänglich auf der - post: gespeichert werden. - disclaimer: - pre: Mit der Nutzung dieses Feedbackformulars stimmst du explizit den - post: sowie einer möglichen Übertragung der Daten außerhalb der Europäischen Union zu. - github_project_issues: GitHub Projektseite - github_site_policy: Nutzungsbedingungen und Datenschutzbestimmungen von GitHub - imprint: Impressum gelisteten Kontaktmöglichkeiten - objection_instruction: Falls du dies ablehnst, schreibe uns bitte über navigatum (at-symbol) tum.de, oder eine der anderen in unserem - processing_based_on_gdpr: Die Verarbeitung basiert auf Grundlage des Art. 6 Abs.1 lit. a DSGVO. - question_contact: - pre: Bei Fragen kannst du dich gerne an uns (navigatum (at-symbol) tum.de) oder an unseren Datenschutzbeauftragten - post: wenden. - right_of_appeal: Es besteht zudem ein Beschwerderecht beim Bayerischen Landesbeauftragten für den Datenschutz. - right_to_information: Unter den gesetzlichen Voraussetzungen und einem vorhandenen Personenbezug der Daten besteht ein Recht auf Auskunft, sowie auf Berichtigung oder Löschung oder auf Einschränkung der Verarbeitung oder eines Widerspruchsrechts gegen die Verarbeitung sowie des Rechts auf Datenübertragbarkeit. - sending: Wird gesendet - try_again_later: Bitte versuche es später noch einmal - send: Senden - thank_you: Vielen Dank! -en: - title: Send Feedback - cancel: Cancel - error: - token_unexpected_status: "Unexpected status code when retrieving a feedback token: " - send_invalid_token: Invalid form token (probably expired). Please copy the text and re-open the form. - please_accept_privacy_statement: You have to accept the privacy statement for us to process the feedback via GitHub. - feedback_not_configured: Sending feedback is currently not configured on the server. - send_no_token: An unexpected error occured (no token). Please copy the text and re-open the form. - send_req_failed: Unexpected error when sending the feedback form. Sending feedback is currently probably not possible. Please send a mail instead. - token_req_failed: Unexpected error when loading the feedback form. Sending feedback is currently probably not possible. Please send a mail instead. - too_many_requests: Sending feedback is currently not possible due to rate-limiting. Please try again in a while or send a mail. - form: - too_short_body: "Error: Message missing or too short" - too_short_subject: "Error: Subject missing or too short" - status: - server_error: Server Error - send_unexpected_status: Unexpected status code - public: - agreement: - pre: My feedback data (subject and message) may be stored anonymously but publicly accessible on the - post: . - disclaimer: - pre: By using this feedback form, you explicitly agree to the - post: as well as a possible transfer of the data outside the European Union. - github_project_issues: GitHub project page - github_site_policy: terms of use and privacy policy of GitHub - imprint: contact options listed in our imprint - objection_instruction: If you object to this, please write to us via navigatum (at-symbol) tum.de, or one of the other - processing_based_on_gdpr: The processing is based on Art. 6 para. 1 lit. a DSGVO. - question_contact: - pre: If you have any questions, please feel free to contact us (navigatum (at-symbol) tum.de) or our data protection officer - post: . - right_of_appeal: There is also a right of appeal to the Bavarian State Commissioner for Data Protection. - right_to_information: Under the legal conditions and an existing personal reference of the data, there is a right to information, as well as to correction or deletion or to restriction of processing or a right to object to processing as well as the right to data portability. - sending: Sending - try_again_later: not possible - send: Send - thank_you: Thank you! - + + + + + +de: + title: Feedback senden + cancel: Abbrechen + error: + token_unexpected_status: "Unerwarteter Status Code beim Abrufen eines Feedback Tokens: " + token_req_failed: Unerwarteter Fehler beim Laden des Feedback-Formulars. Das Senden von Feedback ist gerade vermutlich nicht möglich. Bitte schreibe stattdessen eine Mail. + too_many_requests: Feedback senden ist aktuell nicht möglich aufgrund von rate-limiting. Bitte versuche es später nochmal oder schreibe eine Mail. + send_invalid_token: Formular-Token ungültig (vermutlich abgelaufen). Bitte kopiere den Text und öffne das Formular nochmal. + please_accept_privacy_statement: Du musst die Datenschutzerklärung akzeptiert haben, damit wir dein Feedback via GitHub verarbeiten können. + feedback_not_configured: Das Senden von Feedback ist auf dem Server aktuell nicht konfiguriert. + send_no_token: Ein unerwarteter Fehler ist aufgetreten (Kein Token). Bitte kopiere den Text und öffne das Formular nochmal. + send_req_failed: Unerwarteter Fehler beim Senden des Feedback-Formulars. Das Senden von Feedback ist gerade vermutlich nicht möglich. Bitte schreibe stattdessen eine Mail. + form: + too_short_body: "Fehler: Nachricht fehlt oder ist zu kurz" + too_short_subject: "Fehler: Betreff fehlt oder ist zu kurz" + status: + send_unexpected_status: Unerwarteter Status Code + server_error: Server Fehler + public: + agreement: + pre: Meine Feedback Daten (Betreff und Nachricht) dürfen anonym, aber öffentlich zugänglich auf der + post: gespeichert werden. + disclaimer: + pre: Mit der Nutzung dieses Feedbackformulars stimmst du explizit den + post: sowie einer möglichen Übertragung der Daten außerhalb der Europäischen Union zu. + github_project_issues: GitHub Projektseite + github_site_policy: Nutzungsbedingungen und Datenschutzbestimmungen von GitHub + imprint: Impressum gelisteten Kontaktmöglichkeiten + objection_instruction: Falls du dies ablehnst, schreibe uns bitte über navigatum (at-symbol) tum.de, oder eine der anderen in unserem + processing_based_on_gdpr: Die Verarbeitung basiert auf Grundlage des Art. 6 Abs.1 lit. a DSGVO. + question_contact: + pre: Bei Fragen kannst du dich gerne an uns (navigatum (at-symbol) tum.de) oder an unseren Datenschutzbeauftragten + post: wenden. + right_of_appeal: Es besteht zudem ein Beschwerderecht beim Bayerischen Landesbeauftragten für den Datenschutz. + right_to_information: Unter den gesetzlichen Voraussetzungen und einem vorhandenen Personenbezug der Daten besteht ein Recht auf Auskunft, sowie auf Berichtigung oder Löschung oder auf Einschränkung der Verarbeitung oder eines Widerspruchsrechts gegen die Verarbeitung sowie des Rechts auf Datenübertragbarkeit. + sending: Wird gesendet + try_again_later: Bitte versuche es später noch einmal + send: Senden + thank_you: Vielen Dank! +en: + title: Send Feedback + cancel: Cancel + error: + token_unexpected_status: "Unexpected status code when retrieving a feedback token: " + send_invalid_token: Invalid form token (probably expired). Please copy the text and re-open the form. + please_accept_privacy_statement: You have to accept the privacy statement for us to process the feedback via GitHub. + feedback_not_configured: Sending feedback is currently not configured on the server. + send_no_token: An unexpected error occured (no token). Please copy the text and re-open the form. + send_req_failed: Unexpected error when sending the feedback form. Sending feedback is currently probably not possible. Please send a mail instead. + token_req_failed: Unexpected error when loading the feedback form. Sending feedback is currently probably not possible. Please send a mail instead. + too_many_requests: Sending feedback is currently not possible due to rate-limiting. Please try again in a while or send a mail. + form: + too_short_body: "Error: Message missing or too short" + too_short_subject: "Error: Subject missing or too short" + status: + server_error: Server Error + send_unexpected_status: Unexpected status code + public: + agreement: + pre: My feedback data (subject and message) may be stored anonymously but publicly accessible on the + post: . + disclaimer: + pre: By using this feedback form, you explicitly agree to the + post: as well as a possible transfer of the data outside the European Union. + github_project_issues: GitHub project page + github_site_policy: terms of use and privacy policy of GitHub + imprint: contact options listed in our imprint + objection_instruction: If you object to this, please write to us via navigatum (at-symbol) tum.de, or one of the other + processing_based_on_gdpr: The processing is based on Art. 6 para. 1 lit. a DSGVO. + question_contact: + pre: If you have any questions, please feel free to contact us (navigatum (at-symbol) tum.de) or our data protection officer + post: . + right_of_appeal: There is also a right of appeal to the Bavarian State Commissioner for Data Protection. + right_to_information: Under the legal conditions and an existing personal reference of the data, there is a right to information, as well as to correction or deletion or to restriction of processing or a right to object to processing as well as the right to data portability. + sending: Sending + try_again_later: not possible + send: Send + thank_you: Thank you! + diff --git a/webclient/composables/FloorControl.ts b/webclient/composables/FloorControl.ts index 15e17e82e..cd92344c6 100644 --- a/webclient/composables/FloorControl.ts +++ b/webclient/composables/FloorControl.ts @@ -1,170 +1,170 @@ -import type { IControl, Map } from "maplibre-gl"; -import { Evented } from "maplibre-gl"; -import type { components } from "~/api_types"; - -type OverlayMapEntry = components["schemas"]["OverlayMapEntry"]; -type OverlayMap = { - readonly default: number | null; - readonly available: readonly OverlayMapEntry[]; -}; - -// In reality, this extends maplibregl.Control, but this is apparently not working -export class FloorControl extends Evented implements IControl { - private readonly container: HTMLDivElement; - private readonly floor_list: HTMLDivElement; - private resize_observer: ResizeObserver | undefined; - private map: Map | undefined; - - constructor() { - super(); - - this.container = document.createElement("div"); - this.container.classList.add("maplibregl-ctrl-group"); - this.container.classList.add("maplibregl-ctrl"); - this.container.classList.add("floor-ctrl"); - - // vertical open/collapse button - const verticalOpenClose = document.createElement("button"); - verticalOpenClose.classList.add("vertical-oc"); - verticalOpenClose.innerHTML = ``; - verticalOpenClose.addEventListener("click", () => this.container.classList.toggle("closed")); - // horizontal (primarily on mobile) - const horizontalOpenClose = document.createElement("button"); - horizontalOpenClose.classList.add("horizontal-oc"); - horizontalOpenClose.innerHTML = ``; - horizontalOpenClose.addEventListener("click", () => { - this.container.classList.toggle("closed"); - }); - - this.floor_list = document.createElement("div"); - this.floor_list.id = "floor-list"; - - this.container.appendChild(horizontalOpenClose); - this.container.appendChild(this.floor_list); - this.container.appendChild(verticalOpenClose); - } - - onAdd(map: Map): HTMLDivElement { - this.map = map; - - // To change on `fullscreen` click on mobile, we need to - // observe window size changed - if (ResizeObserver) { - this.resize_observer = new ResizeObserver(() => { - this._recalculateLayout(this.floor_list.children.length); - }); - const interactiveMap = document.getElementById("interactive-map"); - if (interactiveMap) this.resize_observer.observe(interactiveMap); - } - return this.container; - } - - onRemove(): void { - this.container.remove(); - this.map = undefined; - } - - public resetFloors(): void { - this.container.classList.remove("visible"); - this.fire("floor-changed", { file: null, coords: undefined }); - } - - public updateFloors(overlays: OverlayMap): void { - // `floors` is null or a list of floors with data, - // `visibleId` is the id of the visible floor. - this.floor_list.innerHTML = ""; - - const clickHandlerBuilder = (allFloors: readonly OverlayMapEntry[] | null, i: number) => { - // Because JS - return () => { - if (allFloors) { - // floorlist is reversed, so we need to reverse the index - const indexInFloorList = allFloors.length - i - 1; - this._setActiveFloor(indexInFloorList, allFloors[i].floor); - this.fire("floor-changed", { - file: allFloors[i].file, - coords: allFloors[i].coordinates, - }); - } else { - this._setActiveFloor(i, "∅"); - this.fire("floor-changed", { file: null, coords: undefined }); - } - - if (!this.container.classList.contains("reduced")) this.container.classList.add("closed"); - }; - }; - let btn; - let visibleI = null; - [...overlays.available].reverse().forEach((floor: OverlayMapEntry, reversed_index: number) => { - const index = overlays.available.length - reversed_index - 1; - btn = document.createElement("button"); - btn.innerText = floor.floor; - btn.addEventListener("click", clickHandlerBuilder(overlays.available, index)); - this.floor_list.appendChild(btn); - - if (floor.id === overlays.default) visibleI = index; - }); - - if (visibleI === null) { - this._setActiveFloor(this.floor_list.children.length, "∅"); - this.fire("floor-changed", { file: null, coords: undefined }); - } else { - this._setActiveFloor(visibleI, overlays.available[visibleI].floor); - this.fire("floor-changed", { - file: overlays.available[visibleI].file, - coords: overlays.available[visibleI].coordinates, - }); - } - - // The last button hides all overlays - btn = document.createElement("button"); - btn.innerText = "∅"; - btn.addEventListener("click", clickHandlerBuilder(null, this.floor_list.children.length)); - this.floor_list.appendChild(btn); - - this._recalculateLayout(this.floor_list.children.length); - - this.container.classList.add("visible"); - } - - // Recalculate the layout for displaying n floor buttons - private _recalculateLayout(n: number): void { - // Calculate required and available size to choose between - // vertical (default) or horizontal layout - const mapHeight = document.getElementById("interactive-map")?.clientHeight || 0; - const topCtrlHeight = document.querySelector(".maplibregl-ctrl-top-left")?.clientHeight || 0; - const bottomCtrlHeight = document.querySelector(".maplibregl-ctrl-bottom-left")?.clientHeight || 0; - const floorCtrlHeight = document.querySelector(".floor-ctrl")?.clientHeight || 0; - - // The buttons have a height of 29px - const availableHeight = mapHeight - topCtrlHeight - bottomCtrlHeight + floorCtrlHeight; - const requiredHeight = 29 * n; - - // 3 or fewer buttons can always be displayed in reduced layout. - // Also, if the control takes only a small amount of space, it is always open. - if (n <= 3 || requiredHeight < availableHeight * 0.2) { - this.container.classList.remove("closed"); // reduced can never be closed - this.container.classList.remove("horizontal"); - this.container.classList.add("reduced"); - } else { - this.container.classList.remove("reduced"); - this.container.classList.add("closed"); - - // 25px = 10px reserved for top/bottom margin + 5px between control groups - // 29px = additional height from the open/collapse button - if (availableHeight - (requiredHeight + 29) > 25) this.container.classList.remove("horizontal"); - else this.container.classList.add("horizontal"); - } - } - - private _setActiveFloor(floorListI: number, name: string): void { - for (let i = 0; i < this.floor_list.children.length; i++) { - if (i === floorListI) this.floor_list.children[i].classList.add("active"); - else this.floor_list.children[i].classList.remove("active"); - } - const vertical = document.getElementById("vertical-oc-text") as HTMLSpanElement; - vertical.innerText = name; - const horizontal = document.getElementById("horizontal-oc-text") as HTMLSpanElement; - horizontal.innerText = name; - } -} +import type { IControl, Map } from "maplibre-gl"; +import { Evented } from "maplibre-gl"; +import type { components } from "~/api_types"; + +type OverlayMapEntry = components["schemas"]["OverlayMapEntry"]; +type OverlayMap = { + readonly default: number | null; + readonly available: readonly OverlayMapEntry[]; +}; + +// In reality, this extends maplibregl.Control, but this is apparently not working +export class FloorControl extends Evented implements IControl { + private readonly container: HTMLDivElement; + private readonly floor_list: HTMLDivElement; + private resize_observer: ResizeObserver | undefined; + private map: Map | undefined; + + constructor() { + super(); + + this.container = document.createElement("div"); + this.container.classList.add("maplibregl-ctrl-group"); + this.container.classList.add("maplibregl-ctrl"); + this.container.classList.add("floor-ctrl"); + + // vertical open/collapse button + const verticalOpenClose = document.createElement("button"); + verticalOpenClose.classList.add("vertical-oc"); + verticalOpenClose.innerHTML = ``; + verticalOpenClose.addEventListener("click", () => this.container.classList.toggle("closed")); + // horizontal (primarily on mobile) + const horizontalOpenClose = document.createElement("button"); + horizontalOpenClose.classList.add("horizontal-oc"); + horizontalOpenClose.innerHTML = ``; + horizontalOpenClose.addEventListener("click", () => { + this.container.classList.toggle("closed"); + }); + + this.floor_list = document.createElement("div"); + this.floor_list.id = "floor-list"; + + this.container.appendChild(horizontalOpenClose); + this.container.appendChild(this.floor_list); + this.container.appendChild(verticalOpenClose); + } + + onAdd(map: Map): HTMLDivElement { + this.map = map; + + // To change on `fullscreen` click on mobile, we need to + // observe window size changed + if (ResizeObserver) { + this.resize_observer = new ResizeObserver(() => { + this._recalculateLayout(this.floor_list.children.length); + }); + const interactiveMap = document.getElementById("interactive-map"); + if (interactiveMap) this.resize_observer.observe(interactiveMap); + } + return this.container; + } + + onRemove(): void { + this.container.remove(); + this.map = undefined; + } + + public resetFloors(): void { + this.container.classList.remove("visible"); + this.fire("floor-changed", { file: null, coords: undefined }); + } + + public updateFloors(overlays: OverlayMap): void { + // `floors` is null or a list of floors with data, + // `visibleId` is the id of the visible floor. + this.floor_list.innerHTML = ""; + + const clickHandlerBuilder = (allFloors: readonly OverlayMapEntry[] | null, i: number) => { + // Because JS + return () => { + if (allFloors) { + // floorlist is reversed, so we need to reverse the index + const indexInFloorList = allFloors.length - i - 1; + this._setActiveFloor(indexInFloorList, allFloors[i].floor); + this.fire("floor-changed", { + file: allFloors[i].file, + coords: allFloors[i].coordinates, + }); + } else { + this._setActiveFloor(i, "∅"); + this.fire("floor-changed", { file: null, coords: undefined }); + } + + if (!this.container.classList.contains("reduced")) this.container.classList.add("closed"); + }; + }; + let btn; + let visibleI = null; + [...overlays.available].reverse().forEach((floor: OverlayMapEntry, reversed_index: number) => { + const index = overlays.available.length - reversed_index - 1; + btn = document.createElement("button"); + btn.innerText = floor.floor; + btn.addEventListener("click", clickHandlerBuilder(overlays.available, index)); + this.floor_list.appendChild(btn); + + if (floor.id === overlays.default) visibleI = index; + }); + + if (visibleI === null) { + this._setActiveFloor(this.floor_list.children.length, "∅"); + this.fire("floor-changed", { file: null, coords: undefined }); + } else { + this._setActiveFloor(visibleI, overlays.available[visibleI].floor); + this.fire("floor-changed", { + file: overlays.available[visibleI].file, + coords: overlays.available[visibleI].coordinates, + }); + } + + // The last button hides all overlays + btn = document.createElement("button"); + btn.innerText = "∅"; + btn.addEventListener("click", clickHandlerBuilder(null, this.floor_list.children.length)); + this.floor_list.appendChild(btn); + + this._recalculateLayout(this.floor_list.children.length); + + this.container.classList.add("visible"); + } + + // Recalculate the layout for displaying n floor buttons + private _recalculateLayout(n: number): void { + // Calculate required and available size to choose between + // vertical (default) or horizontal layout + const mapHeight = document.getElementById("interactive-map")?.clientHeight || 0; + const topCtrlHeight = document.querySelector(".maplibregl-ctrl-top-left")?.clientHeight || 0; + const bottomCtrlHeight = document.querySelector(".maplibregl-ctrl-bottom-left")?.clientHeight || 0; + const floorCtrlHeight = document.querySelector(".floor-ctrl")?.clientHeight || 0; + + // The buttons have a height of 29px + const availableHeight = mapHeight - topCtrlHeight - bottomCtrlHeight + floorCtrlHeight; + const requiredHeight = 29 * n; + + // 3 or fewer buttons can always be displayed in reduced layout. + // Also, if the control takes only a small amount of space, it is always open. + if (n <= 3 || requiredHeight < availableHeight * 0.2) { + this.container.classList.remove("closed"); // reduced can never be closed + this.container.classList.remove("horizontal"); + this.container.classList.add("reduced"); + } else { + this.container.classList.remove("reduced"); + this.container.classList.add("closed"); + + // 25px = 10px reserved for top/bottom margin + 5px between control groups + // 29px = additional height from the open/collapse button + if (availableHeight - (requiredHeight + 29) > 25) this.container.classList.remove("horizontal"); + else this.container.classList.add("horizontal"); + } + } + + private _setActiveFloor(floorListI: number, name: string): void { + for (let i = 0; i < this.floor_list.children.length; i++) { + if (i === floorListI) this.floor_list.children[i].classList.add("active"); + else this.floor_list.children[i].classList.remove("active"); + } + const vertical = document.getElementById("vertical-oc-text") as HTMLSpanElement; + vertical.innerText = name; + const horizontal = document.getElementById("horizontal-oc-text") as HTMLSpanElement; + horizontal.innerText = name; + } +} diff --git a/webclient/composables/autocomplete.ts b/webclient/composables/autocomplete.ts index 1a2d44ec6..baa76107e 100644 --- a/webclient/composables/autocomplete.ts +++ b/webclient/composables/autocomplete.ts @@ -1,87 +1,87 @@ -import type { components } from "~/api_types"; - -type SearchResponse = components["schemas"]["SearchResponse"]; -type RoomEntry = components["schemas"]["RoomEntry"]; -type SitesBuildingsEntry = components["schemas"]["SitesBuildingsEntry"]; - -function _allowHighlighting(text: string): string { - /// This function does still parse content only from our internal API (which should not try to pawn us in the - // first place), but for extra redundancy we sanitise this anyway. - // It is not done by Vue, as we use `v-html`-Tag to include it in the frontend. - const opt = new Option(text).innerHTML; - return opt.replaceAll("\x19", "").replaceAll("\x17", ""); -} - -export type SectionFacet = RoomFacet | SiteBuildingFacet; -type RoomFacet = { - facet: "rooms"; - name: string; - entries: EntryFacet[]; - estimatedTotalHits: number; -}; -type SiteBuildingFacet = { - facet: "sites_buildings"; - name: string; - entries: EntryFacet[]; - estimatedTotalHits: number; - expanded: boolean; - n_visible: number; -}; -type EntryFacet = { - id: string; - name: string; - type: string; - subtext: string; - subtext_bold: string | null; - parsed_id: string | null; -}; - -export function extractFacets(data: SearchResponse, roomName: string, buildingName: string) { - const sections: SectionFacet[] = []; - - data.sections.forEach((section) => { - const entries: EntryFacet[] = []; - - switch (section.facet) { - case "rooms": - section.entries.forEach((entry: RoomEntry) => { - entries.push({ - id: entry.id, - name: _allowHighlighting(entry.name), // we explicitly dont let vue sanitise this text - type: entry.type, - subtext: entry.subtext, - subtext_bold: _allowHighlighting(entry.subtext_bold), // we explicitly dont let vue sanitise this text - parsed_id: _allowHighlighting(entry.parsed_id || ""), // we explicitly dont let vue sanitise this text - }); - }); - sections.push({ - facet: "rooms", - name: roomName, - entries: entries, - estimatedTotalHits: section.estimatedTotalHits, - }); - break; - case "sites_buildings": - section.entries.forEach((entry: SitesBuildingsEntry) => { - entries.push({ - id: entry.id, - name: _allowHighlighting(entry.name), // we explicitly dont let vue sanitise this text - type: entry.type, - subtext: entry.subtext, - subtext_bold: null, - parsed_id: null, - }); - }); - sections.push({ - facet: "sites_buildings", - name: buildingName, - expanded: false, - entries: entries, - estimatedTotalHits: section.estimatedTotalHits, - n_visible: section.n_visible || entries.length, - }); - } - }); - - return sections; -} +import type { components } from "~/api_types"; + +type SearchResponse = components["schemas"]["SearchResponse"]; +type RoomEntry = components["schemas"]["RoomEntry"]; +type SitesBuildingsEntry = components["schemas"]["SitesBuildingsEntry"]; + +function _allowHighlighting(text: string): string { + /// This function does still parse content only from our internal API (which should not try to pawn us in the + // first place), but for extra redundancy we sanitise this anyway. + // It is not done by Vue, as we use `v-html`-Tag to include it in the frontend. + const opt = new Option(text).innerHTML; + return opt.replaceAll("\x19", "").replaceAll("\x17", ""); +} + +export type SectionFacet = RoomFacet | SiteBuildingFacet; +type RoomFacet = { + facet: "rooms"; + name: string; + entries: EntryFacet[]; + estimatedTotalHits: number; +}; +type SiteBuildingFacet = { + facet: "sites_buildings"; + name: string; + entries: EntryFacet[]; + estimatedTotalHits: number; + expanded: boolean; + n_visible: number; +}; +type EntryFacet = { + id: string; + name: string; + type: string; + subtext: string; + subtext_bold: string | null; + parsed_id: string | null; +}; + +export function extractFacets(data: SearchResponse, roomName: string, buildingName: string) { + const sections: SectionFacet[] = []; + + data.sections.forEach((section) => { + const entries: EntryFacet[] = []; + + switch (section.facet) { + case "rooms": + section.entries.forEach((entry: RoomEntry) => { + entries.push({ + id: entry.id, + name: _allowHighlighting(entry.name), // we explicitly dont let vue sanitise this text + type: entry.type, + subtext: entry.subtext, + subtext_bold: _allowHighlighting(entry.subtext_bold), // we explicitly dont let vue sanitise this text + parsed_id: _allowHighlighting(entry.parsed_id || ""), // we explicitly dont let vue sanitise this text + }); + }); + sections.push({ + facet: "rooms", + name: roomName, + entries: entries, + estimatedTotalHits: section.estimatedTotalHits, + }); + break; + case "sites_buildings": + section.entries.forEach((entry: SitesBuildingsEntry) => { + entries.push({ + id: entry.id, + name: _allowHighlighting(entry.name), // we explicitly dont let vue sanitise this text + type: entry.type, + subtext: entry.subtext, + subtext_bold: null, + parsed_id: null, + }); + }); + sections.push({ + facet: "sites_buildings", + name: buildingName, + expanded: false, + entries: entries, + estimatedTotalHits: section.estimatedTotalHits, + n_visible: section.n_visible || entries.length, + }); + } + }); + + return sections; +} diff --git a/webclient/composables/common.ts b/webclient/composables/common.ts index d61be8d77..8e2b2c911 100644 --- a/webclient/composables/common.ts +++ b/webclient/composables/common.ts @@ -1,8 +1,8 @@ -export function setTitle(name: string): void { - document.title = `${name} – NavigaTUM`; - document.querySelector('meta[property="og:title"]')?.setAttribute("content", name); -} -export function setDescription(description: string): void { - document.querySelector('meta[name="description"]')?.setAttribute("content", description); - document.querySelector('meta[property="og:description"]')?.setAttribute("content", description); -} +export function setTitle(name: string): void { + document.title = `${name} – NavigaTUM`; + document.querySelector('meta[property="og:title"]')?.setAttribute("content", name); +} +export function setDescription(description: string): void { + document.querySelector('meta[name="description"]')?.setAttribute("content", description); + document.querySelector('meta[property="og:description"]')?.setAttribute("content", description); +} diff --git a/webclient/composables/feedback.ts b/webclient/composables/feedback.ts index 6ee48d3b3..1878dac46 100644 --- a/webclient/composables/feedback.ts +++ b/webclient/composables/feedback.ts @@ -1,12 +1,12 @@ -import type { components } from "~/api_types"; - -type PostFeedbackRequest = components["schemas"]["PostFeedbackRequest"]; -type FeedbackState = { - open: boolean; - data: Omit; -}; -export const useFeedback = () => - useState("feedback", () => ({ - open: false, - data: { category: "general", subject: "", body: "", deletion_requested: false }, - })); +import type { components } from "~/api_types"; + +type PostFeedbackRequest = components["schemas"]["PostFeedbackRequest"]; +type FeedbackState = { + open: boolean; + data: Omit; +}; +export const useFeedback = () => + useState("feedback", () => ({ + open: false, + data: { category: "general", subject: "", body: "", deletion_requested: false }, + })); diff --git a/webclient/composables/feedbackToken.ts b/webclient/composables/feedbackToken.ts index 1b4c6dddb..5b48ef350 100644 --- a/webclient/composables/feedbackToken.ts +++ b/webclient/composables/feedbackToken.ts @@ -1,70 +1,70 @@ -import { reactive } from "vue"; -import type { components } from "~/api_types"; -import { useLocalStorage } from "@vueuse/core"; - -type TokenResponse = components["schemas"]["TokenResponse"]; - -enum TokenStatus { - SUCCESSFULLY_CREATED = 201, - TOO_MANY_REQUESTS = 429, - NOT_CONFIGURED = 503, -} - -export function useFeedbackToken(t: ReturnType["t"]): { - error: { message: string; blockSend: boolean }; - token: { value: TokenResponse | null }; -} { - const token = useLocalStorage("feedback-token", null, { - serializer: { - read: (v) => (v ? JSON.parse(v) : null), - write: (v) => JSON.stringify(v), - }, - }); - const error = reactive({ - message: "", - blockSend: false, - }); - - // legacy migration function TODO: remove only after 31.09.2023, to give our users time to migrate to the new token format - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - if (token.value?.expiry) { - token.value = null; - } - - // Token are renewed much before being invalid on the server. - const MS_PER_HOUR = 3600000; - const TOKEN_VALIDITY_FRONTEND_HOURS = 6; - const runtimeConfig = useRuntimeConfig(); - if (token.value === null || Date.now() - token.value.created_at > TOKEN_VALIDITY_FRONTEND_HOURS * MS_PER_HOUR) { - fetch(`${runtimeConfig.public.feedbackURL}/api/feedback/get_token`, { method: "POST" }) - .then((r) => { - if (r.status === TokenStatus.SUCCESSFULLY_CREATED) { - r.json() - .then((j: TokenResponse) => { - token.value = j; - }) - .catch((r) => { - error.message = t("error.token_req_failed"); - console.error(r); - }); - } else if (r.status === TokenStatus.TOO_MANY_REQUESTS) { - error.message = t("error.too_many_requests"); - error.blockSend = true; - } else if (r.status === TokenStatus.NOT_CONFIGURED) { - error.message = t("error.feedback_not_configured"); - error.blockSend = true; - } else { - error.message = `${t("error.token_unexpected_status")}${r.status}`; - error.blockSend = true; - } - if (r.status !== TokenStatus.SUCCESSFULLY_CREATED) - document.getElementById("token-modal-error")?.scrollIntoView({ behavior: "smooth" }); - }) - .catch((r) => { - error.message = t("error.token_req_failed"); - console.error(r); - }); - } - return { error, token }; -} +import { reactive } from "vue"; +import type { components } from "~/api_types"; +import { useLocalStorage } from "@vueuse/core"; + +type TokenResponse = components["schemas"]["TokenResponse"]; + +enum TokenStatus { + SUCCESSFULLY_CREATED = 201, + TOO_MANY_REQUESTS = 429, + NOT_CONFIGURED = 503, +} + +export function useFeedbackToken(t: ReturnType["t"]): { + error: { message: string; blockSend: boolean }; + token: { value: TokenResponse | null }; +} { + const token = useLocalStorage("feedback-token", null, { + serializer: { + read: (v) => (v ? JSON.parse(v) : null), + write: (v) => JSON.stringify(v), + }, + }); + const error = reactive({ + message: "", + blockSend: false, + }); + + // legacy migration function TODO: remove only after 31.09.2023, to give our users time to migrate to the new token format + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + if (token.value?.expiry) { + token.value = null; + } + + // Token are renewed much before being invalid on the server. + const MS_PER_HOUR = 3600000; + const TOKEN_VALIDITY_FRONTEND_HOURS = 6; + const runtimeConfig = useRuntimeConfig(); + if (token.value === null || Date.now() - token.value.created_at > TOKEN_VALIDITY_FRONTEND_HOURS * MS_PER_HOUR) { + fetch(`${runtimeConfig.public.feedbackURL}/api/feedback/get_token`, { method: "POST" }) + .then((r) => { + if (r.status === TokenStatus.SUCCESSFULLY_CREATED) { + r.json() + .then((j: TokenResponse) => { + token.value = j; + }) + .catch((r) => { + error.message = t("error.token_req_failed"); + console.error(r); + }); + } else if (r.status === TokenStatus.TOO_MANY_REQUESTS) { + error.message = t("error.too_many_requests"); + error.blockSend = true; + } else if (r.status === TokenStatus.NOT_CONFIGURED) { + error.message = t("error.feedback_not_configured"); + error.blockSend = true; + } else { + error.message = `${t("error.token_unexpected_status")}${r.status}`; + error.blockSend = true; + } + if (r.status !== TokenStatus.SUCCESSFULLY_CREATED) + document.getElementById("token-modal-error")?.scrollIntoView({ behavior: "smooth" }); + }) + .catch((r) => { + error.message = t("error.token_req_failed"); + console.error(r); + }); + } + return { error, token }; +} diff --git a/webclient/composables/outdatedBrowser.ts b/webclient/composables/outdatedBrowser.ts index 40a11a7a3..d88633271 100644 --- a/webclient/composables/outdatedBrowser.ts +++ b/webclient/composables/outdatedBrowser.ts @@ -1,76 +1,76 @@ -type BrowserName = "Opera" | "Edge" | "Chrome" | "Safari" | "Firefox"; -type BrowserInfo = { - name: BrowserName; - version: number; -}; - -function extractBrowserInfo(): BrowserInfo { - const ua = navigator.userAgent; - let tem; - let M = ua.match(/(opera|chrome|safari|firefox(?=\/))\/?\s*(\d+)/i) || []; - - if (M[1] === "Chrome") { - tem = ua.match(/\b(OPR|Edge)\/(\d+)/); - if (tem != null) { - return { name: tem[1].replace("OPR", "Opera") as BrowserName, version: +tem[2] }; - } - } - - M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, "-?"]; - - if ((tem = ua.match(/version\/(\d+)/i)) != null) { - M.splice(1, 1, tem[1]); - } - - return { name: M[0] as BrowserName, version: +M[1] }; -} - -function isSupportedBrowser(browserName: BrowserName, browserVersion: number) { - switch (browserName) { - case "Chrome": - return 98 <= browserVersion; - case "Firefox": - return 94 <= browserVersion; - case "Edge": - return 98 <= browserVersion; - case "Opera": - return 84 <= browserVersion; - case "Safari": - return 15.3 <= browserVersion; - default: - return false; - } -} - -function shouldWarnForOutdatedBrowser(): boolean { - const browser = extractBrowserInfo(); - if (isSupportedBrowser(browser.name, browser.version)) return false; - console.table(browser); - const optLastTime = localStorage.getItem("lastOutdatedBrowserWarningTime"); - if (optLastTime === null) return true; - const lastTime = new Date(optLastTime); - - const currentTime: Date = new Date(); - const msSinceLastWarning = currentTime.getTime() - lastTime.getTime(); - const daysSinceLastWarning = msSinceLastWarning / (1000 * 60 * 60 * 24); - return daysSinceLastWarning > 1; -} - -if (shouldWarnForOutdatedBrowser()) { - alert( - `Please consider upgrading your browser to one of the following recommended options: - -- Google Chrome -- Mozilla Firefox -- Microsoft Edge - -We regret to inform you that your current web browser is outdated and unsupported for the optimal performance of this website. -To ensure a secure and efficient browsing experience, we recommend updating your browser to the latest version or switching to a more modern and supported browser. -Outdated browsers may not be able to render the website correctly thus leading to reduced functionality or lead to potential security vulnerabilities. - -If you need assistance with updating your browser, please refer to your browser's official website or your IT department for guidance. -Thank you for your understanding, and we look forward to providing you with an enhanced browsing experience once your browser is up-to-date.`, - ); - localStorage.setItem("lastOutdatedBrowserWarningTime", new Date().getTime().toString()); -} -export {}; +type BrowserName = "Opera" | "Edge" | "Chrome" | "Safari" | "Firefox"; +type BrowserInfo = { + name: BrowserName; + version: number; +}; + +function extractBrowserInfo(): BrowserInfo { + const ua = navigator.userAgent; + let tem; + let M = ua.match(/(opera|chrome|safari|firefox(?=\/))\/?\s*(\d+)/i) || []; + + if (M[1] === "Chrome") { + tem = ua.match(/\b(OPR|Edge)\/(\d+)/); + if (tem != null) { + return { name: tem[1].replace("OPR", "Opera") as BrowserName, version: +tem[2] }; + } + } + + M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, "-?"]; + + if ((tem = ua.match(/version\/(\d+)/i)) != null) { + M.splice(1, 1, tem[1]); + } + + return { name: M[0] as BrowserName, version: +M[1] }; +} + +function isSupportedBrowser(browserName: BrowserName, browserVersion: number) { + switch (browserName) { + case "Chrome": + return 98 <= browserVersion; + case "Firefox": + return 94 <= browserVersion; + case "Edge": + return 98 <= browserVersion; + case "Opera": + return 84 <= browserVersion; + case "Safari": + return 15.3 <= browserVersion; + default: + return false; + } +} + +function shouldWarnForOutdatedBrowser(): boolean { + const browser = extractBrowserInfo(); + if (isSupportedBrowser(browser.name, browser.version)) return false; + console.table(browser); + const optLastTime = localStorage.getItem("lastOutdatedBrowserWarningTime"); + if (optLastTime === null) return true; + const lastTime = new Date(optLastTime); + + const currentTime: Date = new Date(); + const msSinceLastWarning = currentTime.getTime() - lastTime.getTime(); + const daysSinceLastWarning = msSinceLastWarning / (1000 * 60 * 60 * 24); + return daysSinceLastWarning > 1; +} + +if (shouldWarnForOutdatedBrowser()) { + alert( + `Please consider upgrading your browser to one of the following recommended options: + +- Google Chrome +- Mozilla Firefox +- Microsoft Edge + +We regret to inform you that your current web browser is outdated and unsupported for the optimal performance of this website. +To ensure a secure and efficient browsing experience, we recommend updating your browser to the latest version or switching to a more modern and supported browser. +Outdated browsers may not be able to render the website correctly thus leading to reduced functionality or lead to potential security vulnerabilities. + +If you need assistance with updating your browser, please refer to your browser's official website or your IT department for guidance. +Thank you for your understanding, and we look forward to providing you with an enhanced browsing experience once your browser is up-to-date.`, + ); + localStorage.setItem("lastOutdatedBrowserWarningTime", new Date().getTime().toString()); +} +export {}; diff --git a/webclient/composables/webglSupport.ts b/webclient/composables/webglSupport.ts index f2cab5257..b12d93662 100644 --- a/webclient/composables/webglSupport.ts +++ b/webclient/composables/webglSupport.ts @@ -1,10 +1,10 @@ -function supportsWebgl(): boolean { - try { - const canvas = document.createElement("canvas"); - return !!window.WebGLRenderingContext && !!(canvas.getContext("webgl") || canvas.getContext("experimental-webgl")); - } catch (e) { - return false; - } -} - -export const webglSupport: boolean = supportsWebgl(); +function supportsWebgl(): boolean { + try { + const canvas = document.createElement("canvas"); + return !!window.WebGLRenderingContext && !!(canvas.getContext("webgl") || canvas.getContext("experimental-webgl")); + } catch (e) { + return false; + } +} + +export const webglSupport: boolean = supportsWebgl(); diff --git a/webclient/content/about/datenschutz.md b/webclient/content/about/datenschutz.md index 8184bb5ba..9e924ff58 100644 --- a/webclient/content/about/datenschutz.md +++ b/webclient/content/about/datenschutz.md @@ -1,226 +1,226 @@ -# Datenschutzerklärung - -## A. Allgemeine Informationen - -### Name und Kontaktdaten des Verantwortlichen - -Verantwortlicher im Sinne der Datenschutzgesetze, insbesondere der EU-Datenschutzgrundverordnung (DSGVO), ist: - -Frank Elsinga in Vertretung für ["OpenSource @ TUM e.V."](https://tum.dev). - -```plain -Postal address: Boltzmannstr. 3, 85748 Garching b. München, Germany. -Telephone: 089/289-17052 -E-Mail: navigatum (at-symbol) tum.de -``` - -### Kontaktdaten des Datenschutzbeauftragten - -```plain -Der/Die Datenschutzbeauftragte der Technischen Universität München -Postanschrift: Arcisstr. 21, 80333 München -Telefon: 089/289-17052 -E-Mail: beauftragter(at)datenschutz.tum.de -``` - -### Zwecke und Rechtsgrundlagen für die Verarbeitung - -#### Feedback - -Die Nutzung des Feedbackformulars erfolgt auf einer rein freiwilligen Basis. -Die Verarbeitung basiert auf Grundlage des Art. 6 Abs.1 lit. a DSGVO. -Für die Nutzung des Feedbackformulars muss den [Tearms of Service und den Datenschutzbestimmungen von GitHub](https://docs.github.com/en/github/site-policy) zugestimmt werden. -Auf die mögliche Übertragung der Daten außerhalb der Europäischen Union wird hingewiesen. -Für nicht öffentliche Kommunikation wird auf die Kontaktmöglichkeit über das [Impressum](/about/impressum) hingewiesen. - -### Empfänger von personenbezogenen Daten - -Der technische Betrieb unserer Datenverarbeitungssysteme erfolgt durch: - -```plain -Leibniz-Rechenzentrum (LRZ) der Bayerischen Akademie der Wissenschaften -Boltzmannstraße 1 -D-85748 Garching bei München -Telefon: (089) 35831 8000 -Fax: (089) 35831 9700 -E-Mail: lrzpost(at)lrz.de -www.lrz.de -``` - -Gegebenenfalls werden Ihre Daten an die zuständigen Aufsichts- und Rechnungsprüfungsbehörden zur Wahrnehmung der jeweiligen Kontrollrechte übermittelt. - -Zur Abwehr von Gefahren für die Sicherheit in der Informationstechnik können bei elektronischer Übermittlung Daten an das Landesamt für Sicherheit in der Informationstechnik weitergeleitet werden und dort auf Grundlage der Art. 12 ff. des Bayerischen E-Government-Gesetzes verarbeitet werden. - -### Dauer der Speicherung der personenbezogenen Daten - -#### Feedback - -Die Daten von einem Nutzer freiwillig bereitgestellten Daten werden technisch nicht gelöscht, außer er wünscht dies. - -Zudem kann ein Nutzer seinen Kommentar jederzeit durch uns löschen lassen. -Schreiben Sie dafür bitte eine E-Mail an uns (navigatum (at-symbol) tum.de) und übermitteln den Link zu Ihrem Kommentar. -Darüber hinaus können Sie sich auch an den unten aufgeführten Datenschutzbeauftragten bzw. die für den Datenschutz zuständige Person werden. - -## Ihre Rechte - -Soweit wir von Ihnen personenbezogene Daten verarbeiten, stehen Ihnen als Betroffener nachfolgende Rechte zu: - -- Sie haben das Recht auf Auskunft über die zu Ihrer Person gespeicherten Daten (Art. 15 DSGVO). -- Sollten unrichtige personenbezogene Daten verarbeitet werden, steht Ihnen ein Recht auf Berichtigung zu (Art. 16 DSGVO). -- Liegen die gesetzlichen Voraussetzungen vor, so können Sie die Löschung oder Einschränkung der Verarbeitung verlangen (Art. 17 und 18 DSGVO). -- Wenn Sie in die Verarbeitung eingewilligt haben oder ein Vertrag zur Datenverarbeitung besteht und die Datenverarbeitung mithilfe automatisierter Verfahren durchgeführt wird, steht Ihnen gegebenenfalls ein Recht auf Datenübertragbarkeit zu (Art. 20 DSGVO). -- Falls Sie in die Verarbeitung eingewilligt haben und die Verarbeitung auf dieser Einwilligung beruht, können Sie die Einwilligung jederzeit für die Zukunft widerrufen. - Die Rechtmäßigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Datenverarbeitung wird durch diesen nicht berührt. - -Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die Verarbeitung Ihrer Daten Widerspruch einzulegen, wenn die Verarbeitung ausschließlich auf Grundlage des Art. 6 Abs. 1 Buchst. e oder f DSGVO erfolgt (Art. 21 Abs. 1 Satz 1 DSGVO). - -### Beschwerderecht bei der Aufsichtsbehörde - -Weiterhin besteht ein Beschwerderecht beim Bayerischen Landesbeauftragten für den Datenschutz. -Diesen können Sie unter folgenden Kontaktdaten erreichen: - -```plain -Postanschrift: Postfach 22 12 19, 80502 München -Adresse: Wagmüllerstraße 18, 80538 München -Telefon: 089 212672-0 -Telefax: 089 212672-50 -E-Mail: poststelle(at)datenschutz-bayern.de -https://www.datenschutz-bayern.de/ -``` - -## Änderung unserer Datenschutzbestimmungen - -Wir behalten uns vor, diese Datenschutzerklärung anzupassen, damit sie stets den aktuellen rechtlichen Anforderungen entspricht oder um Änderungen unserer Leistungen in der Datenschutzerklärung umzusetzen, z.B. bei der Einführung neuer Services. -Für Ihren erneuten Besuch gilt dann die neue Datenschutzerklärung. - -## Fragen an den Datenschutzbeauftragten - -Wenn Sie Fragen zum Datenschutz haben, schreiben Sie uns bitte eine E-Mail oder wenden Sie sich direkt an die für den Datenschutz verantwortliche Person in unserer Organisation. -Diese Person finden Sie unter den im Impressum genannten Kontaktmöglichkeiten. - -## B. Informationen zum Internetauftritt - -### Weitere Informationen - -Für nähere Informationen zur Verarbeitung Ihrer Daten und zu Ihren Rechten können Sie uns unter den oben (zu Beginn von A.) genannten Kontaktdaten erreichen. - -## Informationen zum Internetauftritt - -### Technische Umsetzung - -Unser Webserver wird durch das Leibniz-Rechenzentrum der Bayerischen Akademie der Wissenschaften (LRZ) betrieben. -Die von Ihnen im Rahmen des Besuchs unseres Webauftritts übermittelten personenbezogenen Daten werden daher in unserem Auftrag durch das LRZ verarbeitet: - -```plain -Leibniz-Rechenzentrum (LRZ) der Bayerischen Akademie der Wissenschaften -Boltzmannstraße 1 -D-85748 Garching bei München -Telefon: (089) 35831 8000 -Fax: (089) 35831 9700 -E-Mail: lrzpost(at)lrz.de -www.lrz.de -``` - -### Protokollierung - -Wenn Sie diese oder andere Internetseiten aufrufen, übermitteln Sie über Ihren Internetbrowser Daten an unseren Webserver. -Die folgenden Daten werden während einer laufenden Verbindung zur Kommunikation zwischen Ihrem Internetbrowser und unserem Webserver temporär in einer Logdatei aufgezeichnet: - -- Datum und Uhrzeit der Anfrage -- Zeitbetrag, den die Anfrage gedauert hat -- Name der angeforderten Datei -- Seite, von der aus die Datei angefordert wurde -- Zugriffsstatus (Datei übertragen, Datei nicht gefunden, etc.) -- Verwendete Webbrowser und verwendetes Betriebssystem -- Übertragene Datenmenge. - -**Insbesondere werden keine IP-Adressen protokolliert.** - -Die Verarbeitung der Daten in dieser Logdatei geschieht wie folgt: - -- Die Logeinträge werden kontinuierlich automatisch ausgewertet, um Angriffe auf die Webserver erkennen und entsprechend reagieren zu können. -- In Einzelfällen, d.h. bei gemeldeten Störungen, Fehlern und Sicherheitsvorfällen, erfolgt eine manuelle Analyse. - -Da keine eindeutig auf Personen zurückführbaren Informationen geloggt werden, ist so kein Rückschluss auf einzelne Personen möglich ist. - -Logeinträge werden nach maximal 2 Wochen automatisiert gelöscht. - -### Externe Dienstleister - -Wir haben keine laufenden Verträge mit externen Dienstleistern. - -### Aktive Komponenten - -Auf dieser Website werden aktive Komponenten wie JavaScript, Java-Applets oder Active-X-Controls verwendet. -Diese Funktion kann durch die Einstellung Ihres Internetbrowsers von Ihnen abgeschaltet werden. - -## SSL-Verschlüsselung - -Um die Sicherheit Ihrer Daten bei der Übertragung zu schützen, verwenden wir dem aktuellen Stand der Technik entsprechende Verschlüsselungsverfahren (z. B. SSL) über HTTPS. - -## Suchanfragen - -Suchanfragen werden über die reguläre Protokollierung (siehe oben) hinaus nicht gespeichert. -Zur Reduktion der Antwortzeiten des Servers können Anfragen jedoch im Arbeitsspeicher des Server gecacht (zwischengespeichert) werden. -Die Cachingdauer beträgt höchstens eine Woche. - -## Anonyme Statistiken - -Zur Erkennung von Problemen und zur weiteren Verbesserung des Angebots werden bei der Benutzung der Dienste anonyme Statistiken erhoben. -Diese erlauben keine Rückführung auf die Personen, die die Dienste nutzen. - -### Cookies - -Wie viele andere Webseiten verwenden wir auch sogenannte "Cookies". -Bei Cookies handelt es sich um kleine Textdateien, die auf Ihrem Endgerät (Laptop, Tablet, Smartphone o.ä.) gespeichert werden, wenn Sie unsere Webseite besuchen. - -Sie können Sie einzelne Cookies oder den gesamten Cookie-Bestand löschen. -Darüber hinaus erhalten Sie Informationen und Anleitungen, wie diese Cookies gelöscht oder deren Speicherung vorab blockiert werden können. -Je nach Anbieter Ihres Browsers finden Sie die notwendigen Informationen unter den nachfolgenden Links: - -- Mozilla Firefox: -- Internet Explorer: -- Google Chrome: -- Opera: -- Safari: - -#### Technisch notwendige Cookies - -##### Art und Zweck der Verarbeitung - -Wir setzen Cookies ein, um unsere Website nutzerfreundlicher zu gestalten. -Einige Elemente unserer Internetseite erfordern es, dass vom Benutzer gewählte Einstellungen auch nach einem Seitenwechsel vorhanden sind. -Der Zweck der Verwendung technisch notwendiger Cookies ist, die Nutzung von Websites für die Nutzer zu vereinfachen. -Einige Funktionen unserer Internetseite können ohne den Einsatz von Cookies nicht angeboten werden. - -Für folgende Anwendungen benötigen wir Cookies: - -- Übernahme von Spracheinstellungen -- Übernahme von Themeeinstellungen - -Diese Webseite verwendet diese Cookies ausschließlich zum Zwecke der Speicherung der Sprachen- und Theme-Einstellung. -Ein entsprechendes, nicht-personenbezogenes, Cookie wird erst gesetzt, wenn die Standardeinstellung geändert wird. - -##### Speicherdauer - -Die Cookies werden serverseitig nicht protokolliert oder gespeichert. -Daher ist kein Tracking über Cookies möglich. -Im Browser beträgt die Speicherdauer ein Jahr. - -## C. Informationen zu einzelnen Verarbeitungen - -### Feedback - -Bei der Kontaktaufnahme mit uns per Feedbackformular werden die Angaben des Nutzers zur Bearbeitung der Kontaktanfrage und deren Abwicklung gem. Art. 6 Abs. 1 lit. b) DSGVO verarbeitet. -Eine Rückführung auf die Person ist dabei nur insoweit möglich, wie personenbezogene Daten im versendeten Text enthalten sind. -Neben dem vom Nutzer bereitgestellten Daten wird außerdem der Raum, über den Feedback abgegeben wurde, das Datum und die Uhrzeit der Feedbackserstellung gesendet. -Es wird zudem gespeichert, ob der Nutzer die Löschung der übertragenen Daten nach Beendigung der Feedbackbearbeitung wünscht. - -**Empfänger:** -Das übertragene Feedback wird, im Rahmen unserem Commitment zur Transparenz, öffentlich zugänglich auf [Github](https://github.com/TUM-Dev/navigatum/issues) gespeichert. -Sie sind also technisch nicht auf einen Personenkreis beschränkt. -Dem Nutzer wird ein Issue-link präsentiert, um die Bearbeitung des Feedbacks nachvollziehen zu können. -Falls der Nutzer die sofortige Löschung gewünscht hat, kann diese Funktion nicht mehr technisch bereitgestellt werden. - -**Bereitstellung vorgeschrieben oder erforderlich:** -Die Bereitstellung dieser nicht personenbezogenen Daten erfolgt freiwillig. +# Datenschutzerklärung + +## A. Allgemeine Informationen + +### Name und Kontaktdaten des Verantwortlichen + +Verantwortlicher im Sinne der Datenschutzgesetze, insbesondere der EU-Datenschutzgrundverordnung (DSGVO), ist: + +Frank Elsinga in Vertretung für ["OpenSource @ TUM e.V."](https://tum.dev). + +```plain +Postal address: Boltzmannstr. 3, 85748 Garching b. München, Germany. +Telephone: 089/289-17052 +E-Mail: navigatum (at-symbol) tum.de +``` + +### Kontaktdaten des Datenschutzbeauftragten + +```plain +Der/Die Datenschutzbeauftragte der Technischen Universität München +Postanschrift: Arcisstr. 21, 80333 München +Telefon: 089/289-17052 +E-Mail: beauftragter(at)datenschutz.tum.de +``` + +### Zwecke und Rechtsgrundlagen für die Verarbeitung + +#### Feedback + +Die Nutzung des Feedbackformulars erfolgt auf einer rein freiwilligen Basis. +Die Verarbeitung basiert auf Grundlage des Art. 6 Abs.1 lit. a DSGVO. +Für die Nutzung des Feedbackformulars muss den [Tearms of Service und den Datenschutzbestimmungen von GitHub](https://docs.github.com/en/github/site-policy) zugestimmt werden. +Auf die mögliche Übertragung der Daten außerhalb der Europäischen Union wird hingewiesen. +Für nicht öffentliche Kommunikation wird auf die Kontaktmöglichkeit über das [Impressum](/about/impressum) hingewiesen. + +### Empfänger von personenbezogenen Daten + +Der technische Betrieb unserer Datenverarbeitungssysteme erfolgt durch: + +```plain +Leibniz-Rechenzentrum (LRZ) der Bayerischen Akademie der Wissenschaften +Boltzmannstraße 1 +D-85748 Garching bei München +Telefon: (089) 35831 8000 +Fax: (089) 35831 9700 +E-Mail: lrzpost(at)lrz.de +www.lrz.de +``` + +Gegebenenfalls werden Ihre Daten an die zuständigen Aufsichts- und Rechnungsprüfungsbehörden zur Wahrnehmung der jeweiligen Kontrollrechte übermittelt. + +Zur Abwehr von Gefahren für die Sicherheit in der Informationstechnik können bei elektronischer Übermittlung Daten an das Landesamt für Sicherheit in der Informationstechnik weitergeleitet werden und dort auf Grundlage der Art. 12 ff. des Bayerischen E-Government-Gesetzes verarbeitet werden. + +### Dauer der Speicherung der personenbezogenen Daten + +#### Feedback + +Die Daten von einem Nutzer freiwillig bereitgestellten Daten werden technisch nicht gelöscht, außer er wünscht dies. + +Zudem kann ein Nutzer seinen Kommentar jederzeit durch uns löschen lassen. +Schreiben Sie dafür bitte eine E-Mail an uns (navigatum (at-symbol) tum.de) und übermitteln den Link zu Ihrem Kommentar. +Darüber hinaus können Sie sich auch an den unten aufgeführten Datenschutzbeauftragten bzw. die für den Datenschutz zuständige Person werden. + +## Ihre Rechte + +Soweit wir von Ihnen personenbezogene Daten verarbeiten, stehen Ihnen als Betroffener nachfolgende Rechte zu: + +- Sie haben das Recht auf Auskunft über die zu Ihrer Person gespeicherten Daten (Art. 15 DSGVO). +- Sollten unrichtige personenbezogene Daten verarbeitet werden, steht Ihnen ein Recht auf Berichtigung zu (Art. 16 DSGVO). +- Liegen die gesetzlichen Voraussetzungen vor, so können Sie die Löschung oder Einschränkung der Verarbeitung verlangen (Art. 17 und 18 DSGVO). +- Wenn Sie in die Verarbeitung eingewilligt haben oder ein Vertrag zur Datenverarbeitung besteht und die Datenverarbeitung mithilfe automatisierter Verfahren durchgeführt wird, steht Ihnen gegebenenfalls ein Recht auf Datenübertragbarkeit zu (Art. 20 DSGVO). +- Falls Sie in die Verarbeitung eingewilligt haben und die Verarbeitung auf dieser Einwilligung beruht, können Sie die Einwilligung jederzeit für die Zukunft widerrufen. + Die Rechtmäßigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Datenverarbeitung wird durch diesen nicht berührt. + +Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die Verarbeitung Ihrer Daten Widerspruch einzulegen, wenn die Verarbeitung ausschließlich auf Grundlage des Art. 6 Abs. 1 Buchst. e oder f DSGVO erfolgt (Art. 21 Abs. 1 Satz 1 DSGVO). + +### Beschwerderecht bei der Aufsichtsbehörde + +Weiterhin besteht ein Beschwerderecht beim Bayerischen Landesbeauftragten für den Datenschutz. +Diesen können Sie unter folgenden Kontaktdaten erreichen: + +```plain +Postanschrift: Postfach 22 12 19, 80502 München +Adresse: Wagmüllerstraße 18, 80538 München +Telefon: 089 212672-0 +Telefax: 089 212672-50 +E-Mail: poststelle(at)datenschutz-bayern.de +https://www.datenschutz-bayern.de/ +``` + +## Änderung unserer Datenschutzbestimmungen + +Wir behalten uns vor, diese Datenschutzerklärung anzupassen, damit sie stets den aktuellen rechtlichen Anforderungen entspricht oder um Änderungen unserer Leistungen in der Datenschutzerklärung umzusetzen, z.B. bei der Einführung neuer Services. +Für Ihren erneuten Besuch gilt dann die neue Datenschutzerklärung. + +## Fragen an den Datenschutzbeauftragten + +Wenn Sie Fragen zum Datenschutz haben, schreiben Sie uns bitte eine E-Mail oder wenden Sie sich direkt an die für den Datenschutz verantwortliche Person in unserer Organisation. +Diese Person finden Sie unter den im Impressum genannten Kontaktmöglichkeiten. + +## B. Informationen zum Internetauftritt + +### Weitere Informationen + +Für nähere Informationen zur Verarbeitung Ihrer Daten und zu Ihren Rechten können Sie uns unter den oben (zu Beginn von A.) genannten Kontaktdaten erreichen. + +## Informationen zum Internetauftritt + +### Technische Umsetzung + +Unser Webserver wird durch das Leibniz-Rechenzentrum der Bayerischen Akademie der Wissenschaften (LRZ) betrieben. +Die von Ihnen im Rahmen des Besuchs unseres Webauftritts übermittelten personenbezogenen Daten werden daher in unserem Auftrag durch das LRZ verarbeitet: + +```plain +Leibniz-Rechenzentrum (LRZ) der Bayerischen Akademie der Wissenschaften +Boltzmannstraße 1 +D-85748 Garching bei München +Telefon: (089) 35831 8000 +Fax: (089) 35831 9700 +E-Mail: lrzpost(at)lrz.de +www.lrz.de +``` + +### Protokollierung + +Wenn Sie diese oder andere Internetseiten aufrufen, übermitteln Sie über Ihren Internetbrowser Daten an unseren Webserver. +Die folgenden Daten werden während einer laufenden Verbindung zur Kommunikation zwischen Ihrem Internetbrowser und unserem Webserver temporär in einer Logdatei aufgezeichnet: + +- Datum und Uhrzeit der Anfrage +- Zeitbetrag, den die Anfrage gedauert hat +- Name der angeforderten Datei +- Seite, von der aus die Datei angefordert wurde +- Zugriffsstatus (Datei übertragen, Datei nicht gefunden, etc.) +- Verwendete Webbrowser und verwendetes Betriebssystem +- Übertragene Datenmenge. + +**Insbesondere werden keine IP-Adressen protokolliert.** + +Die Verarbeitung der Daten in dieser Logdatei geschieht wie folgt: + +- Die Logeinträge werden kontinuierlich automatisch ausgewertet, um Angriffe auf die Webserver erkennen und entsprechend reagieren zu können. +- In Einzelfällen, d.h. bei gemeldeten Störungen, Fehlern und Sicherheitsvorfällen, erfolgt eine manuelle Analyse. + +Da keine eindeutig auf Personen zurückführbaren Informationen geloggt werden, ist so kein Rückschluss auf einzelne Personen möglich ist. + +Logeinträge werden nach maximal 2 Wochen automatisiert gelöscht. + +### Externe Dienstleister + +Wir haben keine laufenden Verträge mit externen Dienstleistern. + +### Aktive Komponenten + +Auf dieser Website werden aktive Komponenten wie JavaScript, Java-Applets oder Active-X-Controls verwendet. +Diese Funktion kann durch die Einstellung Ihres Internetbrowsers von Ihnen abgeschaltet werden. + +## SSL-Verschlüsselung + +Um die Sicherheit Ihrer Daten bei der Übertragung zu schützen, verwenden wir dem aktuellen Stand der Technik entsprechende Verschlüsselungsverfahren (z. B. SSL) über HTTPS. + +## Suchanfragen + +Suchanfragen werden über die reguläre Protokollierung (siehe oben) hinaus nicht gespeichert. +Zur Reduktion der Antwortzeiten des Servers können Anfragen jedoch im Arbeitsspeicher des Server gecacht (zwischengespeichert) werden. +Die Cachingdauer beträgt höchstens eine Woche. + +## Anonyme Statistiken + +Zur Erkennung von Problemen und zur weiteren Verbesserung des Angebots werden bei der Benutzung der Dienste anonyme Statistiken erhoben. +Diese erlauben keine Rückführung auf die Personen, die die Dienste nutzen. + +### Cookies + +Wie viele andere Webseiten verwenden wir auch sogenannte "Cookies". +Bei Cookies handelt es sich um kleine Textdateien, die auf Ihrem Endgerät (Laptop, Tablet, Smartphone o.ä.) gespeichert werden, wenn Sie unsere Webseite besuchen. + +Sie können Sie einzelne Cookies oder den gesamten Cookie-Bestand löschen. +Darüber hinaus erhalten Sie Informationen und Anleitungen, wie diese Cookies gelöscht oder deren Speicherung vorab blockiert werden können. +Je nach Anbieter Ihres Browsers finden Sie die notwendigen Informationen unter den nachfolgenden Links: + +- Mozilla Firefox: +- Internet Explorer: +- Google Chrome: +- Opera: +- Safari: + +#### Technisch notwendige Cookies + +##### Art und Zweck der Verarbeitung + +Wir setzen Cookies ein, um unsere Website nutzerfreundlicher zu gestalten. +Einige Elemente unserer Internetseite erfordern es, dass vom Benutzer gewählte Einstellungen auch nach einem Seitenwechsel vorhanden sind. +Der Zweck der Verwendung technisch notwendiger Cookies ist, die Nutzung von Websites für die Nutzer zu vereinfachen. +Einige Funktionen unserer Internetseite können ohne den Einsatz von Cookies nicht angeboten werden. + +Für folgende Anwendungen benötigen wir Cookies: + +- Übernahme von Spracheinstellungen +- Übernahme von Themeeinstellungen + +Diese Webseite verwendet diese Cookies ausschließlich zum Zwecke der Speicherung der Sprachen- und Theme-Einstellung. +Ein entsprechendes, nicht-personenbezogenes, Cookie wird erst gesetzt, wenn die Standardeinstellung geändert wird. + +##### Speicherdauer + +Die Cookies werden serverseitig nicht protokolliert oder gespeichert. +Daher ist kein Tracking über Cookies möglich. +Im Browser beträgt die Speicherdauer ein Jahr. + +## C. Informationen zu einzelnen Verarbeitungen + +### Feedback + +Bei der Kontaktaufnahme mit uns per Feedbackformular werden die Angaben des Nutzers zur Bearbeitung der Kontaktanfrage und deren Abwicklung gem. Art. 6 Abs. 1 lit. b) DSGVO verarbeitet. +Eine Rückführung auf die Person ist dabei nur insoweit möglich, wie personenbezogene Daten im versendeten Text enthalten sind. +Neben dem vom Nutzer bereitgestellten Daten wird außerdem der Raum, über den Feedback abgegeben wurde, das Datum und die Uhrzeit der Feedbackserstellung gesendet. +Es wird zudem gespeichert, ob der Nutzer die Löschung der übertragenen Daten nach Beendigung der Feedbackbearbeitung wünscht. + +**Empfänger:** +Das übertragene Feedback wird, im Rahmen unserem Commitment zur Transparenz, öffentlich zugänglich auf [Github](https://github.com/TUM-Dev/navigatum/issues) gespeichert. +Sie sind also technisch nicht auf einen Personenkreis beschränkt. +Dem Nutzer wird ein Issue-link präsentiert, um die Bearbeitung des Feedbacks nachvollziehen zu können. +Falls der Nutzer die sofortige Löschung gewünscht hat, kann diese Funktion nicht mehr technisch bereitgestellt werden. + +**Bereitstellung vorgeschrieben oder erforderlich:** +Die Bereitstellung dieser nicht personenbezogenen Daten erfolgt freiwillig. diff --git a/webclient/content/about/impressum.md b/webclient/content/about/impressum.md index 6b38d1697..7c963571d 100644 --- a/webclient/content/about/impressum.md +++ b/webclient/content/about/impressum.md @@ -1,70 +1,70 @@ -# Impressum - -## Herausgeber - -```plain -Technische Universität München -Postanschrift: Arcisstraße 21, 80333 München -Telefon: +49-(0)89-289-17123 -E-Mail: poststelle (at-symbol) tum.de -``` - -## Vertretungsberechtigt - -Die Technische Universität München wird gesetzlich vertreten durch den Präsidenten Prof. Dr. Thomas F. Hofmann. - -## Umsatzsteueridentifikationsnummer - -`DE811193231` (gemäß § 27a Umsatzsteuergesetz) - -## Verantwortlich für den Inhalt - -```plain -Frank Elsinga -Postanschrift: Josef-Fischhaber-Straße 46, 82319 Starnberg -Telefon: +49-(0)176 – 56–727-579 -E-Mail: navigatum (at-symbol) tum.de -``` - -
- ---- - -
- -## Nutzungsbedingungen - -Texte, Bilder, Grafiken sowie die Gestaltung dieser Internetseiten können dem Urheberrecht unterliegen. -Nicht urheberrechtlich geschützt sind nach § 5 des Urheberrechtsgesetz (UrhG) - -- Gesetze, Verordnungen, amtliche Erlasse und Bekanntmachungen sowie Entscheidungen und amtlich verfasste Leitsätze zu Entscheidungen und -- andere amtliche Werke, die im amtlichen Interesse zur allgemeinen Kenntnisnahme veröffentlicht worden sind, mit der Einschränkung, dass die Bestimmungen über Änderungsverbot und Quellenangabe in § 62 Abs. 1 bis 3 und § 63 Abs. 1 und 2 UrhG entsprechend anzuwenden sind. - -Als Privatperson dürfen Sie urheberrechtlich geschütztes Material zum privaten und sonstigen eigenen Gebrauch im Rahmen des § 53 UrhG verwenden. -Eine Vervielfältigung oder Verwendung urheberrechtlich geschützten Materials dieser Seiten oder Teilen davon in anderen elektronischen oder gedruckten Publikationen und deren Veröffentlichung ist nur mit unserer Einwilligung gestattet. -Diese Einwilligung erteilen auf Anfrage die für den Inhalt Verantwortlichen. -Der Nachdruck und die Auswertung von Pressemitteilungen und Reden sind mit Quellenangabe allgemein gestattet. - -Weiterhin können Texte, Bilder, Grafiken und sonstige Dateien ganz oder teilweise dem Urheberrecht Dritter unterliegen. -Auch über das Bestehen möglicher Rechte Dritter geben Ihnen die für den Inhalt Verantwortlichen nähere Auskünfte. - -## Haftunsausschuss - -Alle auf dieser Internetseite bereitgestellten Informationen haben wir nach bestem Wissen und Gewissen erarbeitet und geprüft. -Eine Gewähr für die jederzeitige Aktualität, Richtigkeit, Vollständigkeit und Verfügbarkeit der bereit gestellten Informationen können wir allerdings nicht übernehmen. -Ein Vertragsverhältnis mit den Nutzern des Internetangebots kommt nicht zustande. - -Wir haften nicht für Schäden, die durch die Nutzung dieses Internetangebots entstehen. -Dieser Haftungsausschluss gilt nicht, soweit die Vorschriften des § 839 BGB (Haftung bei Amtspflichtverletzung) einschlägig sind. -Für etwaige Schäden, die beim Aufrufen oder Herunterladen von Daten durch Schadsoftware oder der Installation oder Nutzung von Software verursacht werden, übernehmen wir keine Haftung. - -Falls im Einzelfall erforderlich: Der Haftungsausschluss gilt nicht für Informationen, die in den Anwendungsbereich der Europäischen Dienstleistungsrichtlinie (Richtlinie 2006/123/EG – DLRL) fallen. -Für diese Informationen wird die Richtigkeit und Aktualität gewährleistet. - -## Links - -Von unseren eigenen Inhalten sind Querverweise ("Links") auf die Webseiten anderer Anbieter zu unterscheiden. -Durch diese Links ermöglichen wir lediglich den Zugang zur Nutzung fremder Inhalte nach § 8 Telemediengesetz. -Bei der erstmaligen Verknüpfung mit diesen Internetangeboten haben wir diese fremden Inhalte daraufhin überprüft, ob durch sie eine mögliche zivilrechtliche oder strafrechtliche Verantwortlichkeit ausgelöst wird. -Wir können diese fremden Inhalte aber nicht ständig auf Veränderungen überprüfen und daher auch keine Verantwortung dafür übernehmen. -Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung von Informationen Dritter entstehen, haftet allein der jeweilige Anbieter der Seite. +# Impressum + +## Herausgeber + +```plain +Technische Universität München +Postanschrift: Arcisstraße 21, 80333 München +Telefon: +49-(0)89-289-17123 +E-Mail: poststelle (at-symbol) tum.de +``` + +## Vertretungsberechtigt + +Die Technische Universität München wird gesetzlich vertreten durch den Präsidenten Prof. Dr. Thomas F. Hofmann. + +## Umsatzsteueridentifikationsnummer + +`DE811193231` (gemäß § 27a Umsatzsteuergesetz) + +## Verantwortlich für den Inhalt + +```plain +Frank Elsinga +Postanschrift: Josef-Fischhaber-Straße 46, 82319 Starnberg +Telefon: +49-(0)176 – 56–727-579 +E-Mail: navigatum (at-symbol) tum.de +``` + +
+ +--- + +
+ +## Nutzungsbedingungen + +Texte, Bilder, Grafiken sowie die Gestaltung dieser Internetseiten können dem Urheberrecht unterliegen. +Nicht urheberrechtlich geschützt sind nach § 5 des Urheberrechtsgesetz (UrhG) + +- Gesetze, Verordnungen, amtliche Erlasse und Bekanntmachungen sowie Entscheidungen und amtlich verfasste Leitsätze zu Entscheidungen und +- andere amtliche Werke, die im amtlichen Interesse zur allgemeinen Kenntnisnahme veröffentlicht worden sind, mit der Einschränkung, dass die Bestimmungen über Änderungsverbot und Quellenangabe in § 62 Abs. 1 bis 3 und § 63 Abs. 1 und 2 UrhG entsprechend anzuwenden sind. + +Als Privatperson dürfen Sie urheberrechtlich geschütztes Material zum privaten und sonstigen eigenen Gebrauch im Rahmen des § 53 UrhG verwenden. +Eine Vervielfältigung oder Verwendung urheberrechtlich geschützten Materials dieser Seiten oder Teilen davon in anderen elektronischen oder gedruckten Publikationen und deren Veröffentlichung ist nur mit unserer Einwilligung gestattet. +Diese Einwilligung erteilen auf Anfrage die für den Inhalt Verantwortlichen. +Der Nachdruck und die Auswertung von Pressemitteilungen und Reden sind mit Quellenangabe allgemein gestattet. + +Weiterhin können Texte, Bilder, Grafiken und sonstige Dateien ganz oder teilweise dem Urheberrecht Dritter unterliegen. +Auch über das Bestehen möglicher Rechte Dritter geben Ihnen die für den Inhalt Verantwortlichen nähere Auskünfte. + +## Haftunsausschuss + +Alle auf dieser Internetseite bereitgestellten Informationen haben wir nach bestem Wissen und Gewissen erarbeitet und geprüft. +Eine Gewähr für die jederzeitige Aktualität, Richtigkeit, Vollständigkeit und Verfügbarkeit der bereit gestellten Informationen können wir allerdings nicht übernehmen. +Ein Vertragsverhältnis mit den Nutzern des Internetangebots kommt nicht zustande. + +Wir haften nicht für Schäden, die durch die Nutzung dieses Internetangebots entstehen. +Dieser Haftungsausschluss gilt nicht, soweit die Vorschriften des § 839 BGB (Haftung bei Amtspflichtverletzung) einschlägig sind. +Für etwaige Schäden, die beim Aufrufen oder Herunterladen von Daten durch Schadsoftware oder der Installation oder Nutzung von Software verursacht werden, übernehmen wir keine Haftung. + +Falls im Einzelfall erforderlich: Der Haftungsausschluss gilt nicht für Informationen, die in den Anwendungsbereich der Europäischen Dienstleistungsrichtlinie (Richtlinie 2006/123/EG – DLRL) fallen. +Für diese Informationen wird die Richtigkeit und Aktualität gewährleistet. + +## Links + +Von unseren eigenen Inhalten sind Querverweise ("Links") auf die Webseiten anderer Anbieter zu unterscheiden. +Durch diese Links ermöglichen wir lediglich den Zugang zur Nutzung fremder Inhalte nach § 8 Telemediengesetz. +Bei der erstmaligen Verknüpfung mit diesen Internetangeboten haben wir diese fremden Inhalte daraufhin überprüft, ob durch sie eine mögliche zivilrechtliche oder strafrechtliche Verantwortlichkeit ausgelöst wird. +Wir können diese fremden Inhalte aber nicht ständig auf Veränderungen überprüfen und daher auch keine Verantwortung dafür übernehmen. +Für illegale, fehlerhafte oder unvollständige Inhalte und insbesondere für Schäden, die aus der Nutzung oder Nichtnutzung von Informationen Dritter entstehen, haftet allein der jeweilige Anbieter der Seite. diff --git a/webclient/content/about/ueber-uns.md b/webclient/content/about/ueber-uns.md index d32a85112..365828c0a 100644 --- a/webclient/content/about/ueber-uns.md +++ b/webclient/content/about/ueber-uns.md @@ -1,51 +1,51 @@ -# Über NavigaTUM - -NavigaTUM ist ein von Studierenden für Studierende entwickeltes Tool, um sich bei der [TUM](https://tum.de) zurechtzufinden. -Du kannst gerne selbst mitmachen, [der Code ist Open Source verfügbar](https://github.com/TUM-Dev/navigatum) und wir freuen uns über neue Mitwirkende. - -## Datenquellen - -Die Daten in NavigaTUM sollten möglichst umfangreich, aktuell und hilfreich sein. -Deswegen verwendet NavigaTUM neben eigenen Daten auch Daten aus externen Quellen, -insbesondere [TUMonline](https://campus.tum.de) und dem -TUM [Roomfinder](https://portal.mytum.de/campus/roomfinder). - -Eine Übersicht woher welche Daten stammen findest du hier: - -- **Standorte:** Die Standorte wurden von NavigaTUM selbst gesammelt und gruppiert aus der Liste von Gebäuden. Zusätzlich Quellen: - - [Offizielle Standortübersicht der TUM](https://www.tum.de/die-tum/die-universitaet/standorte) - - [Standortübersicht der MPI](https://mpi.fs.tum.de/neu-an-der-tum/standorte/) -- **Gebäude:** Die Liste an Gebäude stammt aus der gesammelten Liste von Gebäuden in TUMonline, sowie der Gebäudeauswahl im Roomfinder. Allerdings verwendet NavigaTUM zum Teil andere Namen oder eine andere Struktur (z.B. bei Gebäudekomplexen). Weitere Informationen zu den Gebäuden wurden evtl. übernommen aus: - - Für alle: [Open Street Map](https://www.openstreetmap.org) - - Stammgelände: [Karte Stammgelände](https://portal.mytum.de/campus/stammgelaende/TUM_Campus_Muenchen_klein) - - Klinkikum rechts der Isar (MRI): - - [Karte MRI](https://portal.mytum.de/campus/rechts_der_isar/mri) - - [MRI Lageplan I](https://www.mri.tum.de/lageplaene-und-wegweiser) - - [MRI Lageplan II](http://www.imi-muenchen.de/fileadmin/user_upload/pdf/MRI_Lageplan.pdf) - - [Anfahrt Frauenklinik](http://www.frauenklinik.med.tum.de/inhalt/anfahrt) - - [Wegweiser für Patienten](https://www.mri.tum.de/sites/default/files/seiten/wegweiser_patienten_ambulant_20200312_web.pdf) - - Olympia: [Karte Olympiapark](https://portal.mytum.de/campus/olympiapark/olympiapark) - - Pasing: [Standort Pasing](https://www.bgu.tum.de/gb/ueber-uns/standort-muenchen-pasing/) - - Heilbronn: - - [Bildungscampus Heilbronn](https://bildungscampus.hn/ueber-uns/leben-am-campus) - - [TUM Heilbronn](https://www.wi.tum.de/tum-campus-heilbronn/welcome-tum-campus-heilbronn/) - - Straubing: - - [Campus Straubing](https://www.cs.tum.de/campus-straubing/campus/?lang=en) - - [Anfahrt und Lageplan Straubing](https://www.cs.tum.de/campus-straubing/anfahrt-und-lageplan/) - - [Karte Straubing](https://www.cs.tum.de/wp-content/uploads/2020/01/200127_TUM_Plan_Straubing_WEB.png) - - Wissenschaftszentrum Weihenstephan: - - [Lageplan Lehrräume](https://www.wzw.tum.de/fileadmin/lageplan/SoLS-Plan-Lehrraume.jpg) - - [Campusplan Weihenstephan](https://www.gm.wzw.tum.de/en/campusplan-stand-oktober-2019/) - - [Versuchsstationen](https://www.wzw.tum.de/?id=239) - - Garching: - - [Karte Garching I](https://portal.mytum.de/campus/garching/TUM_Campus_Garching_web) - - [Karte Garching II](https://www.forschung-garching.tum.de/fileadmin/w00btp/www/00_Startseite_normal/161015_KarteGarchingKomplett_RGB.pdf) - - [Gebäudeplan MW](https://www.mw.tum.de/fileadmin/w00btx/mw/Fakultaet/Anfahrt/Lageplan_Gebaeude_MW.pdf) - - [Gebäudeplan Physik](https://www.ph.tum.de/about/visit/TUM_Physik_Orientierungsplan.pdf) - - [Gebäudeplan Chemie](https://www.ch.tum.de/fileadmin/tuchfak/www/Lageplan/Infoblatt_2020-06.pdf) -- **Räume:** Die Räume wurden großteils aus TUMonline übernommen und ggf. mit Informationen aus dem Roomfinder ergänzt. Ausnahmen sind spezielle Räume oder Bereiche wie Teilbibliotheken. - - [Teilbibliotheken](https://www.ub.tum.de/teilbibliotheken) -- **Bilder:** Die Bilder wurden unabhängig der sonstigen Daten gesammelt und den Einträgen zugeordnet. -- **Öffentliche Verkehrsmittel:** Stationen und Fahrpläne stammen vom MVV - - [Stationen](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/opendata/index.html) - - [Fahrpläne](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/homepage-services/index.html) +# Über NavigaTUM + +NavigaTUM ist ein von Studierenden für Studierende entwickeltes Tool, um sich bei der [TUM](https://tum.de) zurechtzufinden. +Du kannst gerne selbst mitmachen, [der Code ist Open Source verfügbar](https://github.com/TUM-Dev/navigatum) und wir freuen uns über neue Mitwirkende. + +## Datenquellen + +Die Daten in NavigaTUM sollten möglichst umfangreich, aktuell und hilfreich sein. +Deswegen verwendet NavigaTUM neben eigenen Daten auch Daten aus externen Quellen, +insbesondere [TUMonline](https://campus.tum.de) und dem +TUM [Roomfinder](https://portal.mytum.de/campus/roomfinder). + +Eine Übersicht woher welche Daten stammen findest du hier: + +- **Standorte:** Die Standorte wurden von NavigaTUM selbst gesammelt und gruppiert aus der Liste von Gebäuden. Zusätzlich Quellen: + - [Offizielle Standortübersicht der TUM](https://www.tum.de/die-tum/die-universitaet/standorte) + - [Standortübersicht der MPI](https://mpi.fs.tum.de/neu-an-der-tum/standorte/) +- **Gebäude:** Die Liste an Gebäude stammt aus der gesammelten Liste von Gebäuden in TUMonline, sowie der Gebäudeauswahl im Roomfinder. Allerdings verwendet NavigaTUM zum Teil andere Namen oder eine andere Struktur (z.B. bei Gebäudekomplexen). Weitere Informationen zu den Gebäuden wurden evtl. übernommen aus: + - Für alle: [Open Street Map](https://www.openstreetmap.org) + - Stammgelände: [Karte Stammgelände](https://portal.mytum.de/campus/stammgelaende/TUM_Campus_Muenchen_klein) + - Klinkikum rechts der Isar (MRI): + - [Karte MRI](https://portal.mytum.de/campus/rechts_der_isar/mri) + - [MRI Lageplan I](https://www.mri.tum.de/lageplaene-und-wegweiser) + - [MRI Lageplan II](http://www.imi-muenchen.de/fileadmin/user_upload/pdf/MRI_Lageplan.pdf) + - [Anfahrt Frauenklinik](http://www.frauenklinik.med.tum.de/inhalt/anfahrt) + - [Wegweiser für Patienten](https://www.mri.tum.de/sites/default/files/seiten/wegweiser_patienten_ambulant_20200312_web.pdf) + - Olympia: [Karte Olympiapark](https://portal.mytum.de/campus/olympiapark/olympiapark) + - Pasing: [Standort Pasing](https://www.bgu.tum.de/gb/ueber-uns/standort-muenchen-pasing/) + - Heilbronn: + - [Bildungscampus Heilbronn](https://bildungscampus.hn/ueber-uns/leben-am-campus) + - [TUM Heilbronn](https://www.wi.tum.de/tum-campus-heilbronn/welcome-tum-campus-heilbronn/) + - Straubing: + - [Campus Straubing](https://www.cs.tum.de/campus-straubing/campus/?lang=en) + - [Anfahrt und Lageplan Straubing](https://www.cs.tum.de/campus-straubing/anfahrt-und-lageplan/) + - [Karte Straubing](https://www.cs.tum.de/wp-content/uploads/2020/01/200127_TUM_Plan_Straubing_WEB.png) + - Wissenschaftszentrum Weihenstephan: + - [Lageplan Lehrräume](https://www.wzw.tum.de/fileadmin/lageplan/SoLS-Plan-Lehrraume.jpg) + - [Campusplan Weihenstephan](https://www.gm.wzw.tum.de/en/campusplan-stand-oktober-2019/) + - [Versuchsstationen](https://www.wzw.tum.de/?id=239) + - Garching: + - [Karte Garching I](https://portal.mytum.de/campus/garching/TUM_Campus_Garching_web) + - [Karte Garching II](https://www.forschung-garching.tum.de/fileadmin/w00btp/www/00_Startseite_normal/161015_KarteGarchingKomplett_RGB.pdf) + - [Gebäudeplan MW](https://www.mw.tum.de/fileadmin/w00btx/mw/Fakultaet/Anfahrt/Lageplan_Gebaeude_MW.pdf) + - [Gebäudeplan Physik](https://www.ph.tum.de/about/visit/TUM_Physik_Orientierungsplan.pdf) + - [Gebäudeplan Chemie](https://www.ch.tum.de/fileadmin/tuchfak/www/Lageplan/Infoblatt_2020-06.pdf) +- **Räume:** Die Räume wurden großteils aus TUMonline übernommen und ggf. mit Informationen aus dem Roomfinder ergänzt. Ausnahmen sind spezielle Räume oder Bereiche wie Teilbibliotheken. + - [Teilbibliotheken](https://www.ub.tum.de/teilbibliotheken) +- **Bilder:** Die Bilder wurden unabhängig der sonstigen Daten gesammelt und den Einträgen zugeordnet. +- **Öffentliche Verkehrsmittel:** Stationen und Fahrpläne stammen vom MVV + - [Stationen](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/opendata/index.html) + - [Fahrpläne](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/homepage-services/index.html) diff --git a/webclient/content/en/about/about-us.md b/webclient/content/en/about/about-us.md index 2595c9543..4074a8e78 100644 --- a/webclient/content/en/about/about-us.md +++ b/webclient/content/en/about/about-us.md @@ -1,50 +1,50 @@ -# About NavigaTUM - -NavigaTUM is a tool developed by students for students, to help you get around at [TUM](https://tum.de). -Feel free to contribute, [the code is open source](https://github.com/TUM-Dev/navigatum) and we are open to new contributors. - -## Data Sources - -The data used in NavigaTUM should be as complete, up-to-date and helpful as possible. -For this reason it uses besides its own data information from externen sources, especially [TUMonline](https://campus.tum.de) and the -TUM [Roomfinder](https://portal.mytum.de/campus/roomfinder). - -You can find an overview where which data comes here: - -- **Sites/Areas:** The sites/areas have been collected by NavigaTUM based on the list of buildings. Additional sources are: - - [Official Locations overview of TUM](https://www.tum.de/en/about-tum/our-university/locations) - - [Locations overview by MPI](https://mpi.fs.tum.de/en/entering-tum/locations//) -- **Buildings:** The list of buildings was derived from the collected list of buildings in TUMonline and the buildings selection in the Roomfinder. However, sometimes their names or structure was changed (e.g. for complex buildings). Additional information about buildings may have been included from: - - For all: [Open Street Map](https://www.openstreetmap.org) - - Stammgelände: [Map of Stammgelände](https://portal.mytum.de/campus/stammgelaende/TUM_Campus_Muenchen_klein) - - Klinkikum rechts der Isar (MRI): - - [Map of MRI](https://portal.mytum.de/campus/rechts_der_isar/mri) - - [MRI Lageplan I](https://www.mri.tum.de/lageplaene-und-wegweiser) - - [MRI Lageplan II](http://www.imi-muenchen.de/fileadmin/user_upload/pdf/MRI_Lageplan.pdf) - - [Anfahrt Frauenklinik](http://www.frauenklinik.med.tum.de/inhalt/anfahrt) - - [Wegweiser für Patienten](https://www.mri.tum.de/sites/default/files/seiten/wegweiser_patienten_ambulant_20200312_web.pdf) - - Olympia: [Map of Olympiapark](https://portal.mytum.de/campus/olympiapark/olympiapark) - - Pasing: [Standort Pasing](https://www.bgu.tum.de/gb/ueber-uns/standort-muenchen-pasing/) - - Heilbronn: - - [Bildungscampus Heilbronn](https://bildungscampus.hn/ueber-uns/leben-am-campus) - - [TUM Heilbronn](https://www.wi.tum.de/tum-campus-heilbronn/welcome-tum-campus-heilbronn/) - - Straubing: - - [Campus Straubing](https://www.cs.tum.de/campus-straubing/campus/?lang=en) - - [Anfahrt und Lageplan Straubing](https://www.cs.tum.de/campus-straubing/anfahrt-und-lageplan/) - - [Map of Straubing](https://www.cs.tum.de/wp-content/uploads/2020/01/200127_TUM_Plan_Straubing_WEB.png) - - Wissenschaftszentrum Weihenstephan: - - [Lageplan Lehrräume](https://www.wzw.tum.de/fileadmin/lageplan/SoLS-Plan-Lehrraume.jpg) - - [Campusplan Weihenstephan](https://www.gm.wzw.tum.de/en/campusplan-stand-oktober-2019/) - - [Versuchsstationen](https://www.wzw.tum.de/?id=239) - - Garching: - - [Map of Garching I](https://portal.mytum.de/campus/garching/TUM_Campus_Garching_web) - - [Map of Garching II](https://www.forschung-garching.tum.de/fileadmin/w00btp/www/00_Startseite_normal/161015_KarteGarchingKomplett_RGB.pdf) - - [Building map MW](https://www.mw.tum.de/fileadmin/w00btx/mw/Fakultaet/Anfahrt/Lageplan_Gebaeude_MW.pdf) - - [Building map Physics](https://www.ph.tum.de/about/visit/TUM_Physik_Orientierungsplan.pdf) - - [Building map Chemistry](https://www.ch.tum.de/fileadmin/tuchfak/www/Lageplan/Infoblatt_2020-06.pdf) -- **Rooms:** The rooms were mainly taken from TUMonline and extended with information from the Roomfinder. Exceptions are special rooms or spaces such as branch libraries. - - [Branch Libraries](https://www.ub.tum.de/en/branch-libraries) -- **Images:** All images were collected independently and assigned to the entries. -- **Public transport:** Station locations and departure data is taken from the MVV - - [Station Data](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/opendata/index.html) - - [Departure Data](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/homepage-services/index.html) +# About NavigaTUM + +NavigaTUM is a tool developed by students for students, to help you get around at [TUM](https://tum.de). +Feel free to contribute, [the code is open source](https://github.com/TUM-Dev/navigatum) and we are open to new contributors. + +## Data Sources + +The data used in NavigaTUM should be as complete, up-to-date and helpful as possible. +For this reason it uses besides its own data information from externen sources, especially [TUMonline](https://campus.tum.de) and the +TUM [Roomfinder](https://portal.mytum.de/campus/roomfinder). + +You can find an overview where which data comes here: + +- **Sites/Areas:** The sites/areas have been collected by NavigaTUM based on the list of buildings. Additional sources are: + - [Official Locations overview of TUM](https://www.tum.de/en/about-tum/our-university/locations) + - [Locations overview by MPI](https://mpi.fs.tum.de/en/entering-tum/locations//) +- **Buildings:** The list of buildings was derived from the collected list of buildings in TUMonline and the buildings selection in the Roomfinder. However, sometimes their names or structure was changed (e.g. for complex buildings). Additional information about buildings may have been included from: + - For all: [Open Street Map](https://www.openstreetmap.org) + - Stammgelände: [Map of Stammgelände](https://portal.mytum.de/campus/stammgelaende/TUM_Campus_Muenchen_klein) + - Klinkikum rechts der Isar (MRI): + - [Map of MRI](https://portal.mytum.de/campus/rechts_der_isar/mri) + - [MRI Lageplan I](https://www.mri.tum.de/lageplaene-und-wegweiser) + - [MRI Lageplan II](http://www.imi-muenchen.de/fileadmin/user_upload/pdf/MRI_Lageplan.pdf) + - [Anfahrt Frauenklinik](http://www.frauenklinik.med.tum.de/inhalt/anfahrt) + - [Wegweiser für Patienten](https://www.mri.tum.de/sites/default/files/seiten/wegweiser_patienten_ambulant_20200312_web.pdf) + - Olympia: [Map of Olympiapark](https://portal.mytum.de/campus/olympiapark/olympiapark) + - Pasing: [Standort Pasing](https://www.bgu.tum.de/gb/ueber-uns/standort-muenchen-pasing/) + - Heilbronn: + - [Bildungscampus Heilbronn](https://bildungscampus.hn/ueber-uns/leben-am-campus) + - [TUM Heilbronn](https://www.wi.tum.de/tum-campus-heilbronn/welcome-tum-campus-heilbronn/) + - Straubing: + - [Campus Straubing](https://www.cs.tum.de/campus-straubing/campus/?lang=en) + - [Anfahrt und Lageplan Straubing](https://www.cs.tum.de/campus-straubing/anfahrt-und-lageplan/) + - [Map of Straubing](https://www.cs.tum.de/wp-content/uploads/2020/01/200127_TUM_Plan_Straubing_WEB.png) + - Wissenschaftszentrum Weihenstephan: + - [Lageplan Lehrräume](https://www.wzw.tum.de/fileadmin/lageplan/SoLS-Plan-Lehrraume.jpg) + - [Campusplan Weihenstephan](https://www.gm.wzw.tum.de/en/campusplan-stand-oktober-2019/) + - [Versuchsstationen](https://www.wzw.tum.de/?id=239) + - Garching: + - [Map of Garching I](https://portal.mytum.de/campus/garching/TUM_Campus_Garching_web) + - [Map of Garching II](https://www.forschung-garching.tum.de/fileadmin/w00btp/www/00_Startseite_normal/161015_KarteGarchingKomplett_RGB.pdf) + - [Building map MW](https://www.mw.tum.de/fileadmin/w00btx/mw/Fakultaet/Anfahrt/Lageplan_Gebaeude_MW.pdf) + - [Building map Physics](https://www.ph.tum.de/about/visit/TUM_Physik_Orientierungsplan.pdf) + - [Building map Chemistry](https://www.ch.tum.de/fileadmin/tuchfak/www/Lageplan/Infoblatt_2020-06.pdf) +- **Rooms:** The rooms were mainly taken from TUMonline and extended with information from the Roomfinder. Exceptions are special rooms or spaces such as branch libraries. + - [Branch Libraries](https://www.ub.tum.de/en/branch-libraries) +- **Images:** All images were collected independently and assigned to the entries. +- **Public transport:** Station locations and departure data is taken from the MVV + - [Station Data](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/opendata/index.html) + - [Departure Data](https://www.mvv-muenchen.de/fahrplanauskunft/fuer-entwickler/homepage-services/index.html) diff --git a/webclient/content/en/about/imprint.md b/webclient/content/en/about/imprint.md index b9dee47ac..15be45817 100644 --- a/webclient/content/en/about/imprint.md +++ b/webclient/content/en/about/imprint.md @@ -1,70 +1,70 @@ -# Imprint - -## Publisher - -```plain -Technische Universität München -Postanschrift: Arcisstraße 21, 80333 München -Telefon: +49-(0)89-289-17123 -E-Mail: poststelle (at-symbol) tum.de -``` - -## Legal representative - -Die Technische Universität München wird gesetzlich vertreten durch den Präsidenten Prof. Dr. Thomas F. Hofmann. - -## Sales tax identification number - -`DE811193231` (gemäß § 27a Umsatzsteuergesetz) - -## Responsible for the content - -```plain -Frank Elsinga -Postal address: Josef-Fischhaber-Straße 46, 82319 Starnberg, Germany -Telephone: +49-(0)176 - 56-727-579 -E-mail: navigatum (at-symbol) tum.de -``` - -
- ---- - -
- -## Terms of use - -Texts, images, graphics and the design of these Internet pages may be subject to copyright. -The following are not protected by copyright according to § 5 of the Copyright Act (UrhG) - -- laws, ordinances, official decrees and notices as well as decisions and officially written guidelines for decisions and -- other official works that have been published in the official interest for general knowledge, with the restriction that the provisions on the prohibition of alteration and indication of source in Section 62 (1) to (3) and Section 63 (1) and (2) of the Copyright Act apply accordingly. - -As a private individual, you may use copyrighted material for private and other personal use within the scope of Section 53 UrhG. -Any reproduction or use of copyrighted material from these pages or parts thereof in other electronic or printed publications and their publication is only permitted with our consent. -This consent will be granted on request by the person responsible for the content. -The reprinting and exploitation of press releases and speeches is generally permitted provided the source is acknowledged. - -Furthermore, texts, images, graphics and other files may be subject in whole or in part to the copyright of third parties. -The persons responsible for the content will also provide you with more detailed information on the existence of possible third-party rights. - -## Disclaimer - -All information provided on this website has been compiled and checked to the best of our knowledge and belief. -However, we cannot guarantee that the information provided is up-to-date, correct, complete or available at all times. -A contractual relationship with the users of the internet offer is not established. - -We are not liable for any damage caused by the use of this website. -This exclusion of liability does not apply if the provisions of § 839 BGB (liability for breach of official duty) are relevant. -We accept no liability for any damage caused by malware or the installation or use of software when calling up or downloading data. - -If necessary in individual cases: The exclusion of liability does not apply to information that falls within the scope of the European Services Directive (Directive 2006/123/EC - DLRL). -This information is guaranteed to be correct and up to date. - -## Links - -Cross-references ("links") to the websites of other providers are to be distinguished from our own content. -Through these links, we merely provide access to the use of third-party content in accordance with § 8 of the German Telemedia Act. -When first linking to these internet offers, we have checked this external content to see whether it could trigger any possible civil or criminal liability. -However, we cannot constantly check these external contents for changes and therefore cannot assume any responsibility for them. -The respective provider of the page is solely liable for illegal, incorrect or incomplete content and in particular for damages arising from the use or non-use of third-party information. +# Imprint + +## Publisher + +```plain +Technische Universität München +Postanschrift: Arcisstraße 21, 80333 München +Telefon: +49-(0)89-289-17123 +E-Mail: poststelle (at-symbol) tum.de +``` + +## Legal representative + +Die Technische Universität München wird gesetzlich vertreten durch den Präsidenten Prof. Dr. Thomas F. Hofmann. + +## Sales tax identification number + +`DE811193231` (gemäß § 27a Umsatzsteuergesetz) + +## Responsible for the content + +```plain +Frank Elsinga +Postal address: Josef-Fischhaber-Straße 46, 82319 Starnberg, Germany +Telephone: +49-(0)176 - 56-727-579 +E-mail: navigatum (at-symbol) tum.de +``` + +
+ +--- + +
+ +## Terms of use + +Texts, images, graphics and the design of these Internet pages may be subject to copyright. +The following are not protected by copyright according to § 5 of the Copyright Act (UrhG) + +- laws, ordinances, official decrees and notices as well as decisions and officially written guidelines for decisions and +- other official works that have been published in the official interest for general knowledge, with the restriction that the provisions on the prohibition of alteration and indication of source in Section 62 (1) to (3) and Section 63 (1) and (2) of the Copyright Act apply accordingly. + +As a private individual, you may use copyrighted material for private and other personal use within the scope of Section 53 UrhG. +Any reproduction or use of copyrighted material from these pages or parts thereof in other electronic or printed publications and their publication is only permitted with our consent. +This consent will be granted on request by the person responsible for the content. +The reprinting and exploitation of press releases and speeches is generally permitted provided the source is acknowledged. + +Furthermore, texts, images, graphics and other files may be subject in whole or in part to the copyright of third parties. +The persons responsible for the content will also provide you with more detailed information on the existence of possible third-party rights. + +## Disclaimer + +All information provided on this website has been compiled and checked to the best of our knowledge and belief. +However, we cannot guarantee that the information provided is up-to-date, correct, complete or available at all times. +A contractual relationship with the users of the internet offer is not established. + +We are not liable for any damage caused by the use of this website. +This exclusion of liability does not apply if the provisions of § 839 BGB (liability for breach of official duty) are relevant. +We accept no liability for any damage caused by malware or the installation or use of software when calling up or downloading data. + +If necessary in individual cases: The exclusion of liability does not apply to information that falls within the scope of the European Services Directive (Directive 2006/123/EC - DLRL). +This information is guaranteed to be correct and up to date. + +## Links + +Cross-references ("links") to the websites of other providers are to be distinguished from our own content. +Through these links, we merely provide access to the use of third-party content in accordance with § 8 of the German Telemedia Act. +When first linking to these internet offers, we have checked this external content to see whether it could trigger any possible civil or criminal liability. +However, we cannot constantly check these external contents for changes and therefore cannot assume any responsibility for them. +The respective provider of the page is solely liable for illegal, incorrect or incomplete content and in particular for damages arising from the use or non-use of third-party information. diff --git a/webclient/content/en/about/privacy.md b/webclient/content/en/about/privacy.md index f01b5427f..747f93f9b 100644 --- a/webclient/content/en/about/privacy.md +++ b/webclient/content/en/about/privacy.md @@ -1,254 +1,254 @@ -# Privacy Policy - -## A. General Information - -### Name and contact details of the person responsible - -The responsible person within the meaning of the data protection laws, in particular the EU General Data Protection -Regulation (DSGVO), is: - -Frank Elsinga representing ["OpenSource @ TUM e.V."](https://tum.dev). - -```plain -Postal address: Boltzmannstr. 3, 85748 Garching b. München, Germany. -Telephone: 089/289-17052 -E-mail: navigatum (at-symbol) tum.de -``` - -### Contact details of the data protection officer - -```plain -The Data Protection Officer of the Technical University of Munich -Postal address: Arcisstr. 21, 80333 Munich, Germany -Telephone: 089/289-17052 -E-mail: beauftragter(at)datenschutz.tum.de -``` - -### Purposes and legal basis for processing - -#### Feedback - -The feedback form is used on a purely voluntary basis. -The processing is based on Art. 6 para. 1 lit. a DSGVO. -In order to use the feedback form, -the [Tearms of Service and GitHub Privacy Policy](https://docs.github.com/en/github/site-policy) must be agreed to. -Please note that data may be transferred outside the European Union. -For non-public communication, please refer to the contact option via the [Imprint](/en/about/imprint). - -### Recipients of personal data - -The technical operation of our data processing systems is carried out by: - -```plain -Leibniz Computing Centre (LRZ) of the Bavarian Academy of Sciences and Humanities -Boltzmannstraße 1 -D-85748 Garching near Munich -Telephone: (089) 35831 8000 -Fax: (089) 35831 9700 -E-mail: lrzpost(at)lrz.de -www.lrz.de -``` - -If necessary, your data will be transmitted to the competent supervisory and auditing authorities for the exercise of -the respective control rights. - -In the event of electronic transmission, data may be forwarded to the State Office for Information Security in order to -prevent threats to information technology security and processed there on the basis of Art. 12 et seq. of the Bavarian -E-Government Act. - -### Duration of storage of personal data - -#### Feedback - -The data voluntarily provided by a user will not be technically deleted unless the user so requests. - -In addition, a user can have his or her comment deleted by us at any time. -To do so, please write an e-mail to us (navigatum (at-symbol) tum.de) and provide the link to your comment. -In addition, you can also contact the data protection officer listed below and/or the person responsible for data -protection. - -## Your rights - -If we process your personal data, you have the following rights as a data subject: - -- You have the right to information about the data stored about you (Art. 15 DSGVO). -- If incorrect personal data is processed, you have the right to have it corrected (Art. 16 DSGVO). -- If the legal requirements are met, you can request the deletion or restriction of processing (Art. 17 and 18 DSGVO). -- If you have consented to the processing or if there is a contract for data processing and the data processing is - carried out with the help of automated procedures, you may have the right to data portability (Art. 20 DSGVO). -- If you have consented to the processing and the processing is based on this consent, you can revoke the consent at any - time for the future. - The lawfulness of the data processing carried out on the basis of the consent until the revocation is not affected by - this. - -You have the right to object to the processing of your data at any time on grounds relating to your particular -situation, if the processing is carried out exclusively on the basis of Art. 6(1)(e) or (f) DSGVO (Art. 21(1) sentence 1 -DSGVO). - -### Right of complaint to the supervisory authority - -Furthermore, you have the right to lodge a complaint with the Bavarian State Commissioner for Data Protection. -You can contact the Bavarian State Commissioner for Data Protection at the following address: - -```plain -Postal address: P.O. Box 22 12 19, 80502 Munich, Germany. -Address: Wagmüllerstraße 18, 80538 Munich, Germany -Telephone: 089 212672-0 -Fax: 089 212672-50 -E-mail: post office(at)datenschutz-bayern.de -https://www.datenschutz-bayern.de/ -``` - -## Changes to our data protection policy - -We reserve the right to adapt this data protection declaration so that it always complies with the current legal -requirements or in order to implement changes to our services in the data protection declaration, e.g. when introducing -new services. The new data protection statement will then apply to your next visit. - -## Questions to the data protection officer - -If you have any questions about data protection, please write us an e-mail or contact the person responsible for data -protection in our organisation directly. -You can find this person under the contact options mentioned in the imprint. - -## B. Information about the website - -### Further information - -For more detailed information on the processing of your data and your rights, you can contact us using the contact -details given above (at the beginning of A.). - -## Information on the Internet presence - -### Technical implementation - -Our web server is operated by the Leibniz Computing Centre of the Bavarian Academy of Sciences and Humanities (LRZ). -The personal data you transmit when visiting our website is therefore processed by the LRZ on our behalf: - -```plain -Leibniz Computing Centre (LRZ) of the Bavarian Academy of Sciences and Humanities -Boltzmannstrasse 1 -D-85748 Garching near Munich -Telephone: (089) 35831 8000 -Fax: (089) 35831 9700 -E-mail: lrzpost(at)lrz.de -www.lrz.de -``` - -### Logging - -When you call up this or other Internet pages, you transmit data to our web server via your Internet browser. -The following data is temporarily recorded in a log file during an ongoing connection for communication between your -internet browser and our web server: - -- Date and time of the request -- Amount of time the request took -- Name of the requested file -- Page from which the file was requested -- Access status (file transferred, file not found, etc.) -- web browser and operating system used -- amount of data transferred. - -**In particular, no IP addresses are logged.** - -The data in this log file is processed as follows: - -- The log entries are continuously evaluated automatically in order to detect attacks on the web servers and to be able - to react accordingly. -- In individual cases, i.e. in the case of reported malfunctions, errors and security incidents, a manual analysis is - carried out. - -Since no information is logged that can be clearly traced back to individuals, it is not possible to draw conclusions -about individual persons. - -Log entries are automatically deleted after a maximum of 2 weeks. - -### External service providers - -We have no current contracts with external service providers. - -### Active components - -Active components such as JavaScript, Java applets or Active-X controls are used on this website. -This function can be switched off by you through the settings of your Internet browser. - -## SSL encryption - -To protect the security of your data during transmission, we use state-of-the-art encryption procedures (e.g. SSL) via -HTTPS. - -## Search queries - -Search queries are not stored beyond the regular logging (see above). -However, to reduce the server's response times, queries can be cached (temporarily stored) in the server's main memory. -The caching period is a maximum of one week. - -## Anonymous statistics - -In order to recognise problems and to further improve the offer, anonymous statistics are collected when using the -services. -These do not allow any traceability to the persons using the services. - -### Cookies - -Like many other websites, we also use so-called "cookies". -Cookies are small text files that are stored on your end device (laptop, tablet, smartphone or similar) when you visit -our website. - -You can delete individual cookies or the entire cookie inventory. -In addition, you will receive information and instructions on how to delete these cookies or block their storage in -advance. -Depending on the provider of your browser, you will find the necessary information under the following links: - -- Mozilla Firefox: -- Internet Explorer: -- Google Chrome: -- Opera: -- Safari: - -#### Technically necessary cookies - -##### Type and purpose of processing - -We use cookies to make our website more user-friendly. -Some elements of our website require that settings selected by the user are also available after a page change. -The purpose of using technically necessary cookies is to make websites easier for users to use. -Some functions of our website cannot be offered without the use of cookies. - -We require cookies for the following applications: - -- Adoption of language settings -- Acceptance of theme settings - -This website uses these cookies solely for the purpose of storing language and theme settings. -A corresponding, non-personal, cookie is only set when the default setting is changed. - -##### Storage period - -Cookies are not logged or stored on the server side. -Therefore, tracking via cookies is not possible. -In the browser, the storage period is one year. - -## C. Information on individual processing - -### Feedback - -When contacting us via a feedback form, the user's details are processed for the purpose of handling the contact enquiry -and its processing pursuant to Art. 6 Para. 1 lit. b) DSGVO. -A traceability to the person is only possible insofar as personal data is contained in the sent text. -In addition to the data provided by the user, the room about which feedback was given, the date and the time of the -feedback creation are also sent. -It is also stored whether the user wishes the transmitted data to be deleted after the feedback processing has been -completed. - -#### Recipient - -The transmitted feedback is stored publicly accessible on [GitHub](https://github.com/TUM-Dev/navigatum/issues) as part -of our commitment to transparency. -This means that they are not technically limited to one group of people. -The user is presented with an issue link to track the processing of the feedback. -If the user has requested immediate deletion, this function can no longer be technically provided. - -#### Provision mandatory or required - -The provision of this non-personal data is voluntary. +# Privacy Policy + +## A. General Information + +### Name and contact details of the person responsible + +The responsible person within the meaning of the data protection laws, in particular the EU General Data Protection +Regulation (DSGVO), is: + +Frank Elsinga representing ["OpenSource @ TUM e.V."](https://tum.dev). + +```plain +Postal address: Boltzmannstr. 3, 85748 Garching b. München, Germany. +Telephone: 089/289-17052 +E-mail: navigatum (at-symbol) tum.de +``` + +### Contact details of the data protection officer + +```plain +The Data Protection Officer of the Technical University of Munich +Postal address: Arcisstr. 21, 80333 Munich, Germany +Telephone: 089/289-17052 +E-mail: beauftragter(at)datenschutz.tum.de +``` + +### Purposes and legal basis for processing + +#### Feedback + +The feedback form is used on a purely voluntary basis. +The processing is based on Art. 6 para. 1 lit. a DSGVO. +In order to use the feedback form, +the [Tearms of Service and GitHub Privacy Policy](https://docs.github.com/en/github/site-policy) must be agreed to. +Please note that data may be transferred outside the European Union. +For non-public communication, please refer to the contact option via the [Imprint](/en/about/imprint). + +### Recipients of personal data + +The technical operation of our data processing systems is carried out by: + +```plain +Leibniz Computing Centre (LRZ) of the Bavarian Academy of Sciences and Humanities +Boltzmannstraße 1 +D-85748 Garching near Munich +Telephone: (089) 35831 8000 +Fax: (089) 35831 9700 +E-mail: lrzpost(at)lrz.de +www.lrz.de +``` + +If necessary, your data will be transmitted to the competent supervisory and auditing authorities for the exercise of +the respective control rights. + +In the event of electronic transmission, data may be forwarded to the State Office for Information Security in order to +prevent threats to information technology security and processed there on the basis of Art. 12 et seq. of the Bavarian +E-Government Act. + +### Duration of storage of personal data + +#### Feedback + +The data voluntarily provided by a user will not be technically deleted unless the user so requests. + +In addition, a user can have his or her comment deleted by us at any time. +To do so, please write an e-mail to us (navigatum (at-symbol) tum.de) and provide the link to your comment. +In addition, you can also contact the data protection officer listed below and/or the person responsible for data +protection. + +## Your rights + +If we process your personal data, you have the following rights as a data subject: + +- You have the right to information about the data stored about you (Art. 15 DSGVO). +- If incorrect personal data is processed, you have the right to have it corrected (Art. 16 DSGVO). +- If the legal requirements are met, you can request the deletion or restriction of processing (Art. 17 and 18 DSGVO). +- If you have consented to the processing or if there is a contract for data processing and the data processing is + carried out with the help of automated procedures, you may have the right to data portability (Art. 20 DSGVO). +- If you have consented to the processing and the processing is based on this consent, you can revoke the consent at any + time for the future. + The lawfulness of the data processing carried out on the basis of the consent until the revocation is not affected by + this. + +You have the right to object to the processing of your data at any time on grounds relating to your particular +situation, if the processing is carried out exclusively on the basis of Art. 6(1)(e) or (f) DSGVO (Art. 21(1) sentence 1 +DSGVO). + +### Right of complaint to the supervisory authority + +Furthermore, you have the right to lodge a complaint with the Bavarian State Commissioner for Data Protection. +You can contact the Bavarian State Commissioner for Data Protection at the following address: + +```plain +Postal address: P.O. Box 22 12 19, 80502 Munich, Germany. +Address: Wagmüllerstraße 18, 80538 Munich, Germany +Telephone: 089 212672-0 +Fax: 089 212672-50 +E-mail: post office(at)datenschutz-bayern.de +https://www.datenschutz-bayern.de/ +``` + +## Changes to our data protection policy + +We reserve the right to adapt this data protection declaration so that it always complies with the current legal +requirements or in order to implement changes to our services in the data protection declaration, e.g. when introducing +new services. The new data protection statement will then apply to your next visit. + +## Questions to the data protection officer + +If you have any questions about data protection, please write us an e-mail or contact the person responsible for data +protection in our organisation directly. +You can find this person under the contact options mentioned in the imprint. + +## B. Information about the website + +### Further information + +For more detailed information on the processing of your data and your rights, you can contact us using the contact +details given above (at the beginning of A.). + +## Information on the Internet presence + +### Technical implementation + +Our web server is operated by the Leibniz Computing Centre of the Bavarian Academy of Sciences and Humanities (LRZ). +The personal data you transmit when visiting our website is therefore processed by the LRZ on our behalf: + +```plain +Leibniz Computing Centre (LRZ) of the Bavarian Academy of Sciences and Humanities +Boltzmannstrasse 1 +D-85748 Garching near Munich +Telephone: (089) 35831 8000 +Fax: (089) 35831 9700 +E-mail: lrzpost(at)lrz.de +www.lrz.de +``` + +### Logging + +When you call up this or other Internet pages, you transmit data to our web server via your Internet browser. +The following data is temporarily recorded in a log file during an ongoing connection for communication between your +internet browser and our web server: + +- Date and time of the request +- Amount of time the request took +- Name of the requested file +- Page from which the file was requested +- Access status (file transferred, file not found, etc.) +- web browser and operating system used +- amount of data transferred. + +**In particular, no IP addresses are logged.** + +The data in this log file is processed as follows: + +- The log entries are continuously evaluated automatically in order to detect attacks on the web servers and to be able + to react accordingly. +- In individual cases, i.e. in the case of reported malfunctions, errors and security incidents, a manual analysis is + carried out. + +Since no information is logged that can be clearly traced back to individuals, it is not possible to draw conclusions +about individual persons. + +Log entries are automatically deleted after a maximum of 2 weeks. + +### External service providers + +We have no current contracts with external service providers. + +### Active components + +Active components such as JavaScript, Java applets or Active-X controls are used on this website. +This function can be switched off by you through the settings of your Internet browser. + +## SSL encryption + +To protect the security of your data during transmission, we use state-of-the-art encryption procedures (e.g. SSL) via +HTTPS. + +## Search queries + +Search queries are not stored beyond the regular logging (see above). +However, to reduce the server's response times, queries can be cached (temporarily stored) in the server's main memory. +The caching period is a maximum of one week. + +## Anonymous statistics + +In order to recognise problems and to further improve the offer, anonymous statistics are collected when using the +services. +These do not allow any traceability to the persons using the services. + +### Cookies + +Like many other websites, we also use so-called "cookies". +Cookies are small text files that are stored on your end device (laptop, tablet, smartphone or similar) when you visit +our website. + +You can delete individual cookies or the entire cookie inventory. +In addition, you will receive information and instructions on how to delete these cookies or block their storage in +advance. +Depending on the provider of your browser, you will find the necessary information under the following links: + +- Mozilla Firefox: +- Internet Explorer: +- Google Chrome: +- Opera: +- Safari: + +#### Technically necessary cookies + +##### Type and purpose of processing + +We use cookies to make our website more user-friendly. +Some elements of our website require that settings selected by the user are also available after a page change. +The purpose of using technically necessary cookies is to make websites easier for users to use. +Some functions of our website cannot be offered without the use of cookies. + +We require cookies for the following applications: + +- Adoption of language settings +- Acceptance of theme settings + +This website uses these cookies solely for the purpose of storing language and theme settings. +A corresponding, non-personal, cookie is only set when the default setting is changed. + +##### Storage period + +Cookies are not logged or stored on the server side. +Therefore, tracking via cookies is not possible. +In the browser, the storage period is one year. + +## C. Information on individual processing + +### Feedback + +When contacting us via a feedback form, the user's details are processed for the purpose of handling the contact enquiry +and its processing pursuant to Art. 6 Para. 1 lit. b) DSGVO. +A traceability to the person is only possible insofar as personal data is contained in the sent text. +In addition to the data provided by the user, the room about which feedback was given, the date and the time of the +feedback creation are also sent. +It is also stored whether the user wishes the transmitted data to be deleted after the feedback processing has been +completed. + +#### Recipient + +The transmitted feedback is stored publicly accessible on [GitHub](https://github.com/TUM-Dev/navigatum/issues) as part +of our commitment to transparency. +This means that they are not technically limited to one group of people. +The user is presented with an issue link to track the processing of the feedback. +If the user has requested immediate deletion, this function can no longer be technically provided. + +#### Provision mandatory or required + +The provision of this non-personal data is voluntary. diff --git a/webclient/env.d.ts b/webclient/env.d.ts index 15ae819cb..d922d95a3 100644 --- a/webclient/env.d.ts +++ b/webclient/env.d.ts @@ -1,10 +1,10 @@ -/// - -interface ImportMetaEnv { - readonly VITE_APP_URL: string; - // more env variables... -} - -interface ImportMeta { - readonly env: ImportMetaEnv; -} +/// + +interface ImportMetaEnv { + readonly VITE_APP_URL: string; + // more env variables... +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/webclient/layouts/default.vue b/webclient/layouts/default.vue index f72580c2d..e7600cc51 100644 --- a/webclient/layouts/default.vue +++ b/webclient/layouts/default.vue @@ -1,39 +1,39 @@ - - - + + + diff --git a/webclient/layouts/details.vue b/webclient/layouts/details.vue index 44caae670..08d9559b5 100644 --- a/webclient/layouts/details.vue +++ b/webclient/layouts/details.vue @@ -1,37 +1,37 @@ - - - + + + diff --git a/webclient/nuxt.config.ts b/webclient/nuxt.config.ts index b3a482744..878a49837 100644 --- a/webclient/nuxt.config.ts +++ b/webclient/nuxt.config.ts @@ -1,160 +1,160 @@ -// https://nuxt.com/docs/api/configuration/nuxt-config -export default defineNuxtConfig({ - runtimeConfig: { - public: { - apiURL: "https://nav.tum.de", - cdnURL: "https://nav.tum.de", - feedbackURL: "https://nav.tum.de", - mapsURL: "https://nav.tum.de", - }, - }, - modules: [ - "@nuxtjs/i18n", - "@nuxtjs/tailwindcss", - "@nuxtjs/color-mode", - "@vueuse/nuxt", - "@nuxt/content", - "@nuxtjs/partytown", - "@nuxt/image", - ], - app: { - head: { - bodyAttrs: { class: "bg-zinc-50" }, - charset: "utf-8", - viewport: "width=device-width, initial-scale=1", - link: [ - { rel: "apple-touch-icon", sizes: "180x180", href: "/favicons/apple-touch-icon.png" }, - { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicons/favicon-32x32.png" }, - { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicons/favicon-16x16.png" }, - { rel: "manifest", href: "/site.webmanifest" }, - { rel: "mask-icon", href: "/favicons/safari-pinned-tab.svg", color: "#0065bd" }, - ], - meta: [ - { name: "msapplication-TileColor", content: "#0065bd" }, - { name: "theme-color", content: "#ffffff" }, - { name: "author", content: "OpenSource @ TUM e.V. partnering with TUM IT Management" }, - { name: "copyright", content: "GNU General Public License v3.0. Images may be licensed differently." }, - { name: "robots", content: "index, follow" }, - { name: "rating", content: "safe for kids" }, - { name: "og:url", content: "https://nav.tum.de" }, - { name: "og:image:alt", content: "Navigatum Logo" }, - { name: "og:image:width", content: "1200" }, - { name: "og:image:height", content: "630" }, - { name: "og:image:mime", content: "image/png" }, - { name: "og:site_name", content: "NavigaTUM" }, - ], - script: [ - { - innerHTML: `{ -"@context": "https://schema.org", -"@type": "WebSite", -"url": "https://nav.tum.de/", -"potentialAction": [ - { - "@type": "SearchAction", - "target": { - "@type": "EntryPoint", - "urlTemplate": "https://nav.tum.de/search?q={search_term_string}" - }, - "query-input": "required name=search_term_string" - } -] -}`, - type: "application/ld+json", - }, - { - innerHTML: `{ -"@context": "https://schema.org", -"@type": "Organization", -"url": "https://nav.tum.de/", -"logo": "https://nav.tum.de/logos/org_logo.svg" -}`, - type: "application/ld+json", - }, - { innerHTML: "window.$plausible = [];" }, - { - src: "https://analytics.nav.tum.sexy/js/plausible.js", - defer: true, - type: "text/partytown", - "data-domain": "nav.tum.de", - }, - ], - }, - }, - i18n: { - baseUrl: "https://nav.tum.de", - strategy: "prefix_except_default", - locales: [ - { - code: "en", - iso: "en-US", - }, - { - code: "de", - iso: "de-DE", - }, - ], - defaultLocale: "de", - detectBrowserLanguage: { - cookieKey: "lang", - cookieCrossOrigin: true, - redirectOn: "root", // only redirect if somebody visits / to have better SEO - }, - }, - devtools: { enabled: true }, - postcss: { - plugins: { - "tailwindcss/nesting": {}, - tailwindcss: {}, - autoprefixer: {}, - }, - }, - colorMode: { - classSuffix: "", - storageKey: "theme", - preference: "system", - fallback: "light", - }, - content: {}, - nitro: { - compressPublicAssets: { - gzip: true, - brotli: true, - }, - }, - routeRules: { - "/": { prerender: true }, - "/about/**": { prerender: true }, - "/en/about/**": { prerender: true }, - "/en/api": { prerender: true }, - "/api": { prerender: true }, - "/view/**": { swr: 3600 }, - "/campus/**": { swr: 3600 }, - "/site/**": { swr: 3600 }, - "/building/**": { swr: 3600 }, - "/room/**": { swr: 3600 }, - "/poi/**": { swr: 3600 }, - "/en/view/**": { swr: 3600 }, - "/en/campus/**": { swr: 3600 }, - "/en/site/**": { swr: 3600 }, - "/en/building/**": { swr: 3600 }, - "/en/room/**": { swr: 3600 }, - "/en/poi/**": { swr: 3600 }, - }, - typescript: { - typeCheck: true, - strict: true, - }, - partytown: { - forward: ["$plausible", "$plausible.push"], - }, - sourcemap: true, - image: { - domains: ["nav.tum.de"], - }, - build: { - transpile: [ - "sharp", // sharp somehow has problems when not transpiled causing "module not transpiled" errors - ], - }, -}); +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + runtimeConfig: { + public: { + apiURL: "https://nav.tum.de", + cdnURL: "https://nav.tum.de", + feedbackURL: "https://nav.tum.de", + mapsURL: "https://nav.tum.de", + }, + }, + modules: [ + "@nuxtjs/i18n", + "@nuxtjs/tailwindcss", + "@nuxtjs/color-mode", + "@vueuse/nuxt", + "@nuxt/content", + "@nuxtjs/partytown", + "@nuxt/image", + ], + app: { + head: { + bodyAttrs: { class: "bg-zinc-50" }, + charset: "utf-8", + viewport: "width=device-width, initial-scale=1", + link: [ + { rel: "apple-touch-icon", sizes: "180x180", href: "/favicons/apple-touch-icon.png" }, + { rel: "icon", type: "image/png", sizes: "32x32", href: "/favicons/favicon-32x32.png" }, + { rel: "icon", type: "image/png", sizes: "16x16", href: "/favicons/favicon-16x16.png" }, + { rel: "manifest", href: "/site.webmanifest" }, + { rel: "mask-icon", href: "/favicons/safari-pinned-tab.svg", color: "#0065bd" }, + ], + meta: [ + { name: "msapplication-TileColor", content: "#0065bd" }, + { name: "theme-color", content: "#ffffff" }, + { name: "author", content: "OpenSource @ TUM e.V. partnering with TUM IT Management" }, + { name: "copyright", content: "GNU General Public License v3.0. Images may be licensed differently." }, + { name: "robots", content: "index, follow" }, + { name: "rating", content: "safe for kids" }, + { name: "og:url", content: "https://nav.tum.de" }, + { name: "og:image:alt", content: "Navigatum Logo" }, + { name: "og:image:width", content: "1200" }, + { name: "og:image:height", content: "630" }, + { name: "og:image:mime", content: "image/png" }, + { name: "og:site_name", content: "NavigaTUM" }, + ], + script: [ + { + innerHTML: `{ +"@context": "https://schema.org", +"@type": "WebSite", +"url": "https://nav.tum.de/", +"potentialAction": [ + { + "@type": "SearchAction", + "target": { + "@type": "EntryPoint", + "urlTemplate": "https://nav.tum.de/search?q={search_term_string}" + }, + "query-input": "required name=search_term_string" + } +] +}`, + type: "application/ld+json", + }, + { + innerHTML: `{ +"@context": "https://schema.org", +"@type": "Organization", +"url": "https://nav.tum.de/", +"logo": "https://nav.tum.de/logos/org_logo.svg" +}`, + type: "application/ld+json", + }, + { innerHTML: "window.$plausible = [];" }, + { + src: "https://analytics.nav.tum.sexy/js/plausible.js", + defer: true, + type: "text/partytown", + "data-domain": "nav.tum.de", + }, + ], + }, + }, + i18n: { + baseUrl: "https://nav.tum.de", + strategy: "prefix_except_default", + locales: [ + { + code: "en", + iso: "en-US", + }, + { + code: "de", + iso: "de-DE", + }, + ], + defaultLocale: "de", + detectBrowserLanguage: { + cookieKey: "lang", + cookieCrossOrigin: true, + redirectOn: "root", // only redirect if somebody visits / to have better SEO + }, + }, + devtools: { enabled: true }, + postcss: { + plugins: { + "tailwindcss/nesting": {}, + tailwindcss: {}, + autoprefixer: {}, + }, + }, + colorMode: { + classSuffix: "", + storageKey: "theme", + preference: "system", + fallback: "light", + }, + content: {}, + nitro: { + compressPublicAssets: { + gzip: true, + brotli: true, + }, + }, + routeRules: { + "/": { prerender: true }, + "/about/**": { prerender: true }, + "/en/about/**": { prerender: true }, + "/en/api": { prerender: true }, + "/api": { prerender: true }, + "/view/**": { swr: 3600 }, + "/campus/**": { swr: 3600 }, + "/site/**": { swr: 3600 }, + "/building/**": { swr: 3600 }, + "/room/**": { swr: 3600 }, + "/poi/**": { swr: 3600 }, + "/en/view/**": { swr: 3600 }, + "/en/campus/**": { swr: 3600 }, + "/en/site/**": { swr: 3600 }, + "/en/building/**": { swr: 3600 }, + "/en/room/**": { swr: 3600 }, + "/en/poi/**": { swr: 3600 }, + }, + typescript: { + typeCheck: true, + strict: true, + }, + partytown: { + forward: ["$plausible", "$plausible.push"], + }, + sourcemap: true, + image: { + domains: ["nav.tum.de"], + }, + build: { + transpile: [ + "sharp", // sharp somehow has problems when not transpiled causing "module not transpiled" errors + ], + }, +}); diff --git a/webclient/package.json b/webclient/package.json index 64d9136e4..66e2e11d0 100644 --- a/webclient/package.json +++ b/webclient/package.json @@ -1,57 +1,57 @@ -{ - "name": "navigatum", - "private": true, - "scripts": { - "dev": "nuxt dev", - "build": "nuxt build", - "generate": "nuxt generate", - "preview": "nuxt preview", - "postinstall": "nuxt prepare", - "type-check": "nuxt typecheck", - "type-refresh": "openapi-typescript ../openapi.yaml --output ./api_types/index.ts --export-type --immutable-types --support-array-length && npm run format && npm run lint", - "lint": "eslint . --ext .vue,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", - "format": "prettier --plugin=prettier-plugin-tailwindcss --end-of-line lf --write ." - }, - "dependencies": { - "@headlessui/vue": "1.7.21", - "@heroicons/vue": "2.1.3", - "@nuxt/content": "2.12.1", - "@nuxt/image": "1.6.0", - "@nuxtjs/color-mode": "3.4.1", - "@nuxtjs/partytown": "1.5.0", - "@vueuse/core": "10.9.0", - "@vueuse/nuxt": "10.9.0", - "maplibre-gl": "4.1.3", - "nightwind": "1.1.13", - "nuxt": "3.11.2", - "sharp": "0.33.3", - "swagger-ui": "5.17.2", - "swaggerdark": "github:octycs/SwaggerDark#f02d394c8ff698cdd93e09c2188b058d2d686ca3", - "vue": "3.4.25", - "vue-router": "4.3.2", - "vue3-carousel": "0.3.3" - }, - "devDependencies": { - "@nuxtjs/i18n": "8.3.1", - "@nuxtjs/tailwindcss": "6.12.0", - "@types/node": "20.12.7", - "@types/swagger-ui": "3.52.4", - "@vue/eslint-config-prettier": "9.0.0", - "@vue/eslint-config-typescript": "13.0.0", - "@vue/tsconfig": "0.5.1", - "autoprefixer": "10.4.19", - "eslint": "8.57.0", - "eslint-plugin-vue": "9.25.0", - "openapi-typescript": "6.7.5", - "postcss": "8.4.38", - "prettier": "3.2.5", - "prettier-plugin-tailwindcss": "0.5.14", - "sass": "1.75.0", - "stylelint-scss": "6.2.1", - "tailwindcss": "3.4.3", - "typescript": "5.4.5", - "vue-tsc": "1.8.27" - }, - "type": "module", - "packageManager": "pnpm@9.0.6" -} +{ + "name": "navigatum", + "private": true, + "scripts": { + "dev": "nuxt dev", + "build": "nuxt build", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare", + "type-check": "nuxt typecheck", + "type-refresh": "openapi-typescript ../openapi.yaml --output ./api_types/index.ts --export-type --immutable-types --support-array-length && npm run format && npm run lint", + "lint": "eslint . --ext .vue,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", + "format": "prettier --plugin=prettier-plugin-tailwindcss --end-of-line lf --write ." + }, + "dependencies": { + "@headlessui/vue": "1.7.21", + "@heroicons/vue": "2.1.3", + "@nuxt/content": "2.12.1", + "@nuxt/image": "1.6.0", + "@nuxtjs/color-mode": "3.4.1", + "@nuxtjs/partytown": "1.5.0", + "@vueuse/core": "10.9.0", + "@vueuse/nuxt": "10.9.0", + "maplibre-gl": "4.1.3", + "nightwind": "1.1.13", + "nuxt": "3.11.2", + "sharp": "0.33.3", + "swagger-ui": "5.17.2", + "swaggerdark": "github:octycs/SwaggerDark#f02d394c8ff698cdd93e09c2188b058d2d686ca3", + "vue": "3.4.25", + "vue-router": "4.3.2", + "vue3-carousel": "0.3.3" + }, + "devDependencies": { + "@nuxtjs/i18n": "8.3.1", + "@nuxtjs/tailwindcss": "6.12.0", + "@types/node": "20.12.7", + "@types/swagger-ui": "3.52.4", + "@vue/eslint-config-prettier": "9.0.0", + "@vue/eslint-config-typescript": "13.0.0", + "@vue/tsconfig": "0.5.1", + "autoprefixer": "10.4.19", + "eslint": "8.57.0", + "eslint-plugin-vue": "9.25.0", + "openapi-typescript": "6.7.5", + "postcss": "8.4.38", + "prettier": "3.2.5", + "prettier-plugin-tailwindcss": "0.5.14", + "sass": "1.75.0", + "stylelint-scss": "6.2.1", + "tailwindcss": "3.4.3", + "typescript": "5.4.5", + "vue-tsc": "1.8.27" + }, + "type": "module", + "packageManager": "pnpm@9.0.6" +} diff --git a/webclient/pages/[...slug].vue b/webclient/pages/[...slug].vue index adb4a1288..3cd63fcc8 100644 --- a/webclient/pages/[...slug].vue +++ b/webclient/pages/[...slug].vue @@ -1,60 +1,60 @@ - - - - - -de: - open_feedback: Open the feedback-form - description: Dies könnte sein, weil wir einen Fehler gemacht haben. - got_here: "Ich habe diesen Fehler so gefunden:\r\n1. ..." - header: Die angeforderte Seite wurde nicht gefunden. - img_alt: Illustration einer männlichen Person, die auf großen '404'-Buchstaben sitzt und einer weiblichen person vor dem TUM Hauptgebäude - go_home: Zurück gehen - call_to_action: Feedback geben -en: - open_feedback: Open the feedback-form - description: This could be because we made a mistake. - got_here: "I have found the error by:\r\n1. ..." - header: The requested website could not to be found. - img_alt: illustration of a female and male person sitting on large '404'-letters in front of the tum main building - go_home: Go back home - call_to_action: Give Feedback - + + + + + +de: + open_feedback: Open the feedback-form + description: Dies könnte sein, weil wir einen Fehler gemacht haben. + got_here: "Ich habe diesen Fehler so gefunden:\r\n1. ..." + header: Die angeforderte Seite wurde nicht gefunden. + img_alt: Illustration einer männlichen Person, die auf großen '404'-Buchstaben sitzt und einer weiblichen person vor dem TUM Hauptgebäude + go_home: Zurück gehen + call_to_action: Feedback geben +en: + open_feedback: Open the feedback-form + description: This could be because we made a mistake. + got_here: "I have found the error by:\r\n1. ..." + header: The requested website could not to be found. + img_alt: illustration of a female and male person sitting on large '404'-letters in front of the tum main building + go_home: Go back home + call_to_action: Give Feedback + diff --git a/webclient/pages/[view]/[id].vue b/webclient/pages/[view]/[id].vue index c2fae0602..fd86e0873 100644 --- a/webclient/pages/[view]/[id].vue +++ b/webclient/pages/[view]/[id].vue @@ -1,311 +1,311 @@ - - - - - -de: - image_alt: Header-Bild, zeigt das Gebäude - details_for: Details für - map: - interactive: Interaktive Karte - roomfinder: Lagepläne - no_floor_overlay: Für den angezeigten Raum gibt es leider keine Indoor Karte. - header: - calendar: Kalender öffnen - copy_link: Link kopieren - favorites: Zu Favoriten hinzufügen - Loading data...: Lädt daten... -en: - image_alt: Header image, showing the building - details_for: Details for - map: - interactive: Interactive Map - roomfinder: Site Plans - no_floor_overlay: There is unfortunately no indoor map for the displayed room. - header: - calendar: Open calendar - copy_link: Copy link - favorites: Add to favorites - Loading data...: Loading data... - + + + + + +de: + image_alt: Header-Bild, zeigt das Gebäude + details_for: Details für + map: + interactive: Interaktive Karte + roomfinder: Lagepläne + no_floor_overlay: Für den angezeigten Raum gibt es leider keine Indoor Karte. + header: + calendar: Kalender öffnen + copy_link: Link kopieren + favorites: Zu Favoriten hinzufügen + Loading data...: Lädt daten... +en: + image_alt: Header image, showing the building + details_for: Details for + map: + interactive: Interactive Map + roomfinder: Site Plans + no_floor_overlay: There is unfortunately no indoor map for the displayed room. + header: + calendar: Open calendar + copy_link: Copy link + favorites: Add to favorites + Loading data...: Loading data... + diff --git a/webclient/pages/about/[name].vue b/webclient/pages/about/[name].vue index 04e5bbf21..c0528c3a3 100644 --- a/webclient/pages/about/[name].vue +++ b/webclient/pages/about/[name].vue @@ -1,42 +1,42 @@ - - - + + + diff --git a/webclient/pages/api.vue b/webclient/pages/api.vue index ca7ae2879..ba8a7d339 100644 --- a/webclient/pages/api.vue +++ b/webclient/pages/api.vue @@ -1,9 +1,9 @@ - - - + + + diff --git a/webclient/pages/index.vue b/webclient/pages/index.vue index 98ef45e40..1b460ceaa 100644 --- a/webclient/pages/index.vue +++ b/webclient/pages/index.vue @@ -1,112 +1,112 @@ - - - - - -de: - less: weniger - less_aria: weniger Gebäude anzeigen - more: mehr - more_aria: mehr Gebäude anzeigen - overview_map: Übersichtskarte - sites: Standorte - "Loading data...": Lädt daten... - show_details_for_campus: show the details for the campus '{0}' - show_details_for_building: show the details for the building '{0}' - description: Finde Räume, Gebäude und andere Orte an der TUM mit Exzellenz. Eine moderne Alternative zum RoomFinder, entwickelt von Studierenden. -en: - less: less - less_aria: show more buildings - more: more - more_aria: show more buildings - overview_map: Overview Map - sites: Sites - "Loading data...": Loading data... - show_details_for_campus: show the details for the campus '{0}' - show_details_for_building: show the details for the building '{0}' - description: Find rooms, buildings and other places at TUM with excellence. A modern alternative to RoomFinder, developed by students. - + + + + + +de: + less: weniger + less_aria: weniger Gebäude anzeigen + more: mehr + more_aria: mehr Gebäude anzeigen + overview_map: Übersichtskarte + sites: Standorte + "Loading data...": Lädt daten... + show_details_for_campus: show the details for the campus '{0}' + show_details_for_building: show the details for the building '{0}' + description: Finde Räume, Gebäude und andere Orte an der TUM mit Exzellenz. Eine moderne Alternative zum RoomFinder, entwickelt von Studierenden. +en: + less: less + less_aria: show more buildings + more: more + more_aria: show more buildings + overview_map: Overview Map + sites: Sites + "Loading data...": Loading data... + show_details_for_campus: show the details for the campus '{0}' + show_details_for_building: show the details for the building '{0}' + description: Find rooms, buildings and other places at TUM with excellence. A modern alternative to RoomFinder, developed by students. + diff --git a/webclient/pages/search.vue b/webclient/pages/search.vue index 7e6353a6f..f7dd17c3c 100644 --- a/webclient/pages/search.vue +++ b/webclient/pages/search.vue @@ -1,123 +1,123 @@ - - - - - -de: - sections: - buildings: Gebäude / Standorte - rooms: Räume - and: und - no_buildings_rooms_found: Keine Gebäude / Standorte oder Räume konnten gefunden werden. - of_which_visible: davon sichtbar - were_found: wurden gefunden. - feedback: - give: Feedback zu Sucheergebnissen geben - open: Feedback-Formular für Rückmeldungen zur Suchanfrage geben - runtime: Laufzeit - search_for: Suche nach -en: - sections: - buildings: Buildings / Sites - rooms: Rooms - and: and - no_buildings_rooms_found: No buildings / locations or rooms could be found. - of_which_visible: of them visible - were_found: were found. - feedback: - give: Send feedback about search results - open: Open the feedback-form for feedback about the search - runtime: Runtime - search_for: Search for - + + + + + +de: + sections: + buildings: Gebäude / Standorte + rooms: Räume + and: und + no_buildings_rooms_found: Keine Gebäude / Standorte oder Räume konnten gefunden werden. + of_which_visible: davon sichtbar + were_found: wurden gefunden. + feedback: + give: Feedback zu Sucheergebnissen geben + open: Feedback-Formular für Rückmeldungen zur Suchanfrage geben + runtime: Laufzeit + search_for: Suche nach +en: + sections: + buildings: Buildings / Sites + rooms: Rooms + and: and + no_buildings_rooms_found: No buildings / locations or rooms could be found. + of_which_visible: of them visible + were_found: were found. + feedback: + give: Send feedback about search results + open: Open the feedback-form for feedback about the search + runtime: Runtime + search_for: Search for + diff --git a/webclient/public/.well-known/gpc.json b/webclient/public/.well-known/gpc.json index 5144018d4..6c9f4abef 100644 --- a/webclient/public/.well-known/gpc.json +++ b/webclient/public/.well-known/gpc.json @@ -1,4 +1,4 @@ -{ - "gpc": true, - "lastUpdate": "2022-01-29" -} +{ + "gpc": true, + "lastUpdate": "2022-01-29" +} diff --git a/webclient/public/googlebef9161f1176c5e0.html b/webclient/public/googlebef9161f1176c5e0.html index 1576654e5..a3120f1ee 100644 --- a/webclient/public/googlebef9161f1176c5e0.html +++ b/webclient/public/googlebef9161f1176c5e0.html @@ -1 +1 @@ -google-site-verification: googlebef9161f1176c5e0.html +google-site-verification: googlebef9161f1176c5e0.html diff --git a/webclient/public/site.webmanifest b/webclient/public/site.webmanifest index d3dc65c09..b7e0eab55 100644 --- a/webclient/public/site.webmanifest +++ b/webclient/public/site.webmanifest @@ -1,19 +1,19 @@ -{ - "name": "NavigaTUM", - "short_name": "NavigaTUM", - "icons": [ - { - "src": "/favicons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/favicons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} +{ + "name": "NavigaTUM", + "short_name": "NavigaTUM", + "icons": [ + { + "src": "/favicons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/favicons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/webclient/shims.d.ts b/webclient/shims.d.ts index 883391158..053838e5e 100644 --- a/webclient/shims.d.ts +++ b/webclient/shims.d.ts @@ -1,11 +1,11 @@ -declare module "*.vue" { - import type { ComponentOptions } from "vue"; - const Component: ComponentOptions; - export default Component; -} - -declare module "*.md" { - import type { ComponentOptions } from "vue"; - const Component: ComponentOptions; - export default Component; -} +declare module "*.vue" { + import type { ComponentOptions } from "vue"; + const Component: ComponentOptions; + export default Component; +} + +declare module "*.md" { + import type { ComponentOptions } from "vue"; + const Component: ComponentOptions; + export default Component; +} diff --git a/webclient/tailwind.config.ts b/webclient/tailwind.config.ts index cab25811d..4ab84893f 100644 --- a/webclient/tailwind.config.ts +++ b/webclient/tailwind.config.ts @@ -1,38 +1,38 @@ -import type { Config } from "tailwindcss"; -import { current, inherit, orange, red, transparent, white, zinc } from "tailwindcss/colors"; - -export default >{ - darkMode: "class", - content: ["./**/*.{vue,js,ts,jsx,tsx}"], - theme: { - colors: { - inherit, - current, - transparent, - white, - zinc, - orange, - red, - blue: { - 50: "#f3f6fc", - 100: "#e5edf9", - 200: "#c6d9f1", - 300: "#93bae6", - 400: "#5a97d6", - DEFAULT: "#3070b3", - 500: "#3070b3", - 600: "#245fa5", - 700: "#1f4d85", - 800: "#1d426f", - 900: "#1d385d", - 950: "#13243e", - }, - }, - extend: { - aspectRatio: { - "4/3": "4 / 3", - }, - }, - }, - plugins: [require("nightwind")], -}; +import type { Config } from "tailwindcss"; +import { current, inherit, orange, red, transparent, white, zinc } from "tailwindcss/colors"; + +export default >{ + darkMode: "class", + content: ["./**/*.{vue,js,ts,jsx,tsx}"], + theme: { + colors: { + inherit, + current, + transparent, + white, + zinc, + orange, + red, + blue: { + 50: "#f3f6fc", + 100: "#e5edf9", + 200: "#c6d9f1", + 300: "#93bae6", + 400: "#5a97d6", + DEFAULT: "#3070b3", + 500: "#3070b3", + 600: "#245fa5", + 700: "#1f4d85", + 800: "#1d426f", + 900: "#1d385d", + 950: "#13243e", + }, + }, + extend: { + aspectRatio: { + "4/3": "4 / 3", + }, + }, + }, + plugins: [require("nightwind")], +};