mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
merged main
This commit is contained in:
commit
6977b5c76f
@ -7,21 +7,46 @@ import { useSetPermissionData, useSetPermissionApi, useSetAdminRole } from './ho
|
||||
import type { ItemsApi } from '#types/ItemsApi'
|
||||
import type { Permission } from '#types/Permission'
|
||||
|
||||
/**
|
||||
* @category Types
|
||||
*/
|
||||
export interface PermissionsProps {
|
||||
data?: Permission[]
|
||||
api?: ItemsApi<Permission>
|
||||
adminRole?: string
|
||||
}
|
||||
export type { Permission } from '#types/Permission'
|
||||
export type { ItemsApi } from '#types/ItemsApi'
|
||||
|
||||
/**
|
||||
* This Components injects Permissions comming from an {@link ItemsApi | `API`}
|
||||
* ```tsx
|
||||
* <Permissions api={itemsApiInstance} adminRole="8141dee8-8e10-48d0-baf1-680aea271298" />
|
||||
* ```
|
||||
* or from on {@link Permission| `Array`}
|
||||
* ```tsx
|
||||
* <Permissions data={permissions} adminRole="8141dee8-8e10-48d0-baf1-680aea271298" />
|
||||
* ```
|
||||
* Can be child of {@link AppShell | `AppShell`}
|
||||
* ```tsx
|
||||
* <AppShell>
|
||||
* ...
|
||||
* <Permissions api={itemsApiInstance} adminRole="8141dee8-8e10-48d0-baf1-680aea271298" />
|
||||
* </AppShell>
|
||||
* ```
|
||||
* Or child of {@link UtopiaMap | `UtopiaMap`}
|
||||
* ```tsx
|
||||
* <UtopiaMap>
|
||||
* ...
|
||||
* <Permissions api={itemsApiInstance} adminRole="8141dee8-8e10-48d0-baf1-680aea271298" />
|
||||
* </UtopiaMap>
|
||||
* ```
|
||||
* @category Map
|
||||
*/
|
||||
export function Permissions({ data, api, adminRole }: PermissionsProps) {
|
||||
export function Permissions({
|
||||
data,
|
||||
api,
|
||||
adminRole,
|
||||
}: {
|
||||
/** Array with all the permissions inside */
|
||||
data?: Permission[]
|
||||
/** API to fetch all the permissions from a server */
|
||||
api?: ItemsApi<Permission>
|
||||
/** UUID of the admin role which has always all the permissions */
|
||||
adminRole?: string
|
||||
}) {
|
||||
const setPermissionData = useSetPermissionData()
|
||||
const setPermissionApi = useSetPermissionApi()
|
||||
const setAdminRole = useSetAdminRole()
|
||||
|
||||
@ -8,6 +8,28 @@ import type { ItemsApi } from '#types/ItemsApi'
|
||||
import type { Tag } from '#types/Tag'
|
||||
|
||||
/**
|
||||
* This Components injects Tags comming from an {@link ItemsApi | `API`}
|
||||
* ```tsx
|
||||
* <Tags api={tagsApi} />
|
||||
* ```
|
||||
* or from on {@link Tag| `Array`}
|
||||
* ```tsx
|
||||
* <Tags data={tags} />
|
||||
* ```
|
||||
* Can be child of {@link AppShell | `AppShell`}
|
||||
* ```tsx
|
||||
* <AppShell>
|
||||
* ...
|
||||
* <Tags api={tagsApi} />
|
||||
* </AppShell>
|
||||
* ```
|
||||
* Or child of {@link UtopiaMap | `UtopiaMap`}
|
||||
* ```tsx
|
||||
* <UtopiaMap>
|
||||
* ...
|
||||
* <Tags api={tagsApi} />
|
||||
* </UtopiaMap>
|
||||
* ```
|
||||
* @category Map
|
||||
*/
|
||||
export function Tags({ data, api }: { data?: Tag[]; api?: ItemsApi<Tag> }) {
|
||||
|
||||
@ -5,9 +5,40 @@ import { ContextWrapper } from '#components/AppShell/ContextWrapper'
|
||||
|
||||
import { UtopiaMapInner } from './UtopiaMapInner'
|
||||
|
||||
import type { UtopiaMapProps } from '#types/UtopiaMapProps'
|
||||
import type { GeoJsonObject } from 'geojson'
|
||||
|
||||
/**
|
||||
* This component creates the map.
|
||||
* ```tsx
|
||||
* <UtopiaMap center={[50.6, 9.5]} zoom={5} height="100dvh" width="100dvw" />
|
||||
* ```
|
||||
* You can define its {@link Layer | `Layers`} as supcomponents.
|
||||
* ```tsx
|
||||
* <UtopiaMap center={[50.6, 15.5]} zoom={5} height="100dvh" width="100dvw">
|
||||
* <Layer
|
||||
* name="events"
|
||||
* markerIcon="calendar"
|
||||
* markerShape="square"
|
||||
* markerDefaultColor="#700"
|
||||
* data={events}
|
||||
* />
|
||||
* <Layer
|
||||
* name="places"
|
||||
* markerIcon="point"
|
||||
* markerShape="circle"
|
||||
* markerDefaultColor="#007"
|
||||
* data={places}
|
||||
* />
|
||||
* </UtopiaMap>
|
||||
* ```
|
||||
* You can also pass {@link Tags | `Tags`} or {@link Permissions | `Permissions`} as subcomponents.
|
||||
* ```tsx
|
||||
* <UtopiaMap center={[50.6, 15.5]} zoom={5} height="100dvh" width="100dvw">
|
||||
* ...
|
||||
* <Tags data={tags} />
|
||||
* <Permissions data={permissions} />
|
||||
* </UtopiaMap>
|
||||
* ```
|
||||
* @category Map
|
||||
*/
|
||||
function UtopiaMap({
|
||||
@ -22,9 +53,33 @@ function UtopiaMap({
|
||||
showLayerControl = true,
|
||||
showThemeControl = false,
|
||||
defaultTheme,
|
||||
infoText,
|
||||
donationWidget,
|
||||
}: UtopiaMapProps) {
|
||||
}: {
|
||||
/** height of the map (default '500px') */
|
||||
height?: string
|
||||
/** width of the map (default '100%') */
|
||||
width?: string
|
||||
/** initial centered position of the map (default [50.6, 9.5]) */
|
||||
center?: [number, number]
|
||||
/** initial zoom level of the map (default 10) */
|
||||
zoom?: number
|
||||
/** React child-components */
|
||||
children?: React.ReactNode
|
||||
/** GeoJSON to display on the map */
|
||||
geo?: GeoJsonObject
|
||||
/** show the filter control widget (default false) */
|
||||
showFilterControl?: boolean
|
||||
/** show the gratitude control widget (default false) */
|
||||
showLayerControl?: boolean
|
||||
/** show the layer control widget (default true) */
|
||||
showGratitudeControl?: boolean
|
||||
/** show a widget to switch the theme */
|
||||
showThemeControl: boolean
|
||||
/** the defaut theme */
|
||||
defaultTheme: string
|
||||
/** ask to donate to the Utopia Project OpenCollective campaign (default false) */
|
||||
donationWidget?: boolean
|
||||
}) {
|
||||
return (
|
||||
<ContextWrapper>
|
||||
<MapContainer
|
||||
@ -39,7 +94,6 @@ function UtopiaMap({
|
||||
showFilterControl={showFilterControl}
|
||||
showGratitudeControl={showGratitudeControl}
|
||||
showLayerControl={showLayerControl}
|
||||
infoText={infoText}
|
||||
donationWidget={donationWidget}
|
||||
showThemeControl={showThemeControl}
|
||||
defaultTheme={defaultTheme}
|
||||
|
||||
@ -36,8 +36,7 @@ import { TextView } from './Subcomponents/ItemPopupComponents/TextView'
|
||||
import { SelectPosition } from './Subcomponents/SelectPosition'
|
||||
|
||||
import type { ItemFormPopupProps } from '#types/ItemFormPopupProps'
|
||||
import type { UtopiaMapProps } from '#types/UtopiaMapProps'
|
||||
import type { Feature, Geometry as GeoJSONGeometry } from 'geojson'
|
||||
import type { Feature, Geometry as GeoJSONGeometry, GeoJsonObject } from 'geojson'
|
||||
|
||||
export function UtopiaMapInner({
|
||||
children,
|
||||
@ -48,7 +47,16 @@ export function UtopiaMapInner({
|
||||
showThemeControl = false,
|
||||
defaultTheme = '',
|
||||
donationWidget,
|
||||
}: UtopiaMapProps) {
|
||||
}: {
|
||||
children?: React.ReactNode
|
||||
geo?: GeoJsonObject
|
||||
showFilterControl?: boolean
|
||||
showLayerControl?: boolean
|
||||
showGratitudeControl?: boolean
|
||||
donationWidget?: boolean
|
||||
showThemeControl?: boolean
|
||||
defaultTheme?: string
|
||||
}) {
|
||||
const selectNewItemPosition = useSelectPosition()
|
||||
const setSelectNewItemPosition = useSetSelectPosition()
|
||||
const setClusterRef = useSetClusterRef()
|
||||
|
||||
44
src/Components/Profile/ItemFunctions.spec.tsx
Normal file
44
src/Components/Profile/ItemFunctions.spec.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
|
||||
import { linkItem } from './itemFunctions'
|
||||
|
||||
const toastErrorMock: (t: string) => void = vi.fn()
|
||||
const toastSuccessMock: (t: string) => void = vi.fn()
|
||||
|
||||
vi.mock('react-toastify', () => ({
|
||||
toast: {
|
||||
error: (t: string) => toastErrorMock(t),
|
||||
success: (t: string) => toastSuccessMock(t),
|
||||
},
|
||||
}))
|
||||
|
||||
describe('linkItem', () => {
|
||||
const id = 'some-id'
|
||||
let updateApi: () => void = vi.fn()
|
||||
const item = { layer: { api: { updateItem: () => updateApi() } } }
|
||||
const updateItem = vi.fn()
|
||||
|
||||
beforeEach(() => {
|
||||
updateApi = vi.fn()
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('api rejects', () => {
|
||||
it('toasts an error', async () => {
|
||||
updateApi = vi.fn().mockRejectedValue('autsch')
|
||||
await linkItem(id, item, updateItem)
|
||||
expect(toastErrorMock).toHaveBeenCalledWith('autsch')
|
||||
expect(updateItem).not.toHaveBeenCalled()
|
||||
expect(toastSuccessMock).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('api resolves', () => {
|
||||
it('toasts success and calls updateItem()', async () => {
|
||||
await linkItem(id, item, updateItem)
|
||||
expect(toastErrorMock).not.toHaveBeenCalled()
|
||||
expect(updateItem).toHaveBeenCalledTimes(1)
|
||||
expect(toastSuccessMock).toHaveBeenCalledWith('Item linked')
|
||||
})
|
||||
})
|
||||
})
|
||||
31
src/types/Tag.d.ts
vendored
31
src/types/Tag.d.ts
vendored
@ -1,4 +1,35 @@
|
||||
/**
|
||||
* Tags are used to tag items within the app and the map and to filter by keywords. Every tag has a color.
|
||||
* @example
|
||||
* ```ts
|
||||
* export const tags: Tag[] = [
|
||||
* {
|
||||
* "id": "e19f46a7-77a4-4a50-99a2-a942dce843a3",
|
||||
* "name": "nature",
|
||||
* "color": "#9bc53d"
|
||||
* },
|
||||
* {
|
||||
* "id": "2c2099a6-23ac-4308-b91c-86eefeff3a1d",
|
||||
* "name": "utopia",
|
||||
* "color": "#c3423f"
|
||||
* },
|
||||
* {
|
||||
* "id": "48b2de97-2b9e-432b-b230-7bdc9a5fb6c0",
|
||||
* "name": "map",
|
||||
* "color": "#5bc0eb"
|
||||
* },
|
||||
* {
|
||||
* "id": "c88f52e6-357b-45fb-a171-9c2b1dceeb8e",
|
||||
* "name": "food",
|
||||
* "color": "#6761a8"
|
||||
* },
|
||||
* {
|
||||
* "id": "8928cb92-a3c1-4d83-9495-c2eb4fac0bbe",
|
||||
* "name": "permaculture",
|
||||
* "color": "#44344f"
|
||||
* },
|
||||
*];
|
||||
```
|
||||
* @category Types
|
||||
*/
|
||||
export interface Tag {
|
||||
|
||||
@ -16,9 +16,6 @@ export default defineConfig({
|
||||
reporter: ['html', 'json-summary'],
|
||||
thresholds: {
|
||||
lines: 1,
|
||||
functions: 56,
|
||||
branches: 58,
|
||||
statements: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user