basic public item support

This commit is contained in:
Anton Tranelis 2024-05-03 12:49:19 +02:00
parent 1ab589d3b1
commit 06755d7f80
8 changed files with 42 additions and 11 deletions

View File

@ -43,6 +43,7 @@ export const Layer = ({
onlyOnePerOwner = false, onlyOnePerOwner = false,
customEditLink, customEditLink,
customEditParameter, customEditParameter,
public_edit_items,
setItemFormPopup, setItemFormPopup,
itemFormPopup, itemFormPopup,
clusterRef clusterRef
@ -78,8 +79,8 @@ export const Layer = ({
useEffect(() => { useEffect(() => {
data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, setItemFormPopup, itemFormPopup, clusterRef }); data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, setItemFormPopup, itemFormPopup, clusterRef });
api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, setItemFormPopup, itemFormPopup, clusterRef }); api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, setItemFormPopup, itemFormPopup, clusterRef });
}, [data, api]) }, [data, api])
useMapEvents({ useMapEvents({

View File

@ -11,7 +11,7 @@ export default function AddButton({ triggerAction }: { triggerAction: React.Disp
const canAddItems = () => { const canAddItems = () => {
let canAdd = false; let canAdd = false;
layers.map(layer => { layers.map(layer => {
if (layer.api?.createItem && hasUserPermission(layer.api.collectionName!, "create")) canAdd = true; if (layer.api?.createItem && hasUserPermission(layer.api.collectionName!, "create", undefined, layer)) canAdd = true;
}) })
return canAdd; return canAdd;
} }
@ -28,7 +28,7 @@ export default function AddButton({ triggerAction }: { triggerAction: React.Disp
</label> </label>
<ul tabIndex={0} className="tw-dropdown-content tw-pr-1 tw-list-none"> <ul tabIndex={0} className="tw-dropdown-content tw-pr-1 tw-list-none">
{layers.map((layer) => ( {layers.map((layer) => (
layer.api?.createItem && hasUserPermission(layer.api.collectionName!, "create") && ( layer.api?.createItem && hasUserPermission(layer.api.collectionName!, "create", undefined, layer) && (
<li key={layer.name} > <li key={layer.name} >
<a> <a>
<div className="tw-tooltip tw-tooltip-left" data-tip={layer.menuText}> <div className="tw-tooltip tw-tooltip-left" data-tip={layer.menuText}>

View File

@ -96,7 +96,7 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
} }
if(success) { if(success) {
props.layer.onlyOnePerOwner && item && updateItem({...item, ...formItem}); props.layer.onlyOnePerOwner && item && updateItem({...item, ...formItem});
(!props.layer.onlyOnePerOwner || !item) && addItem({...formItem, name: formItem.name ? formItem.name : user?.first_name , user_created: user, type: props.layer.itemType, id: uuid, layer: props.layer}); (!props.layer.onlyOnePerOwner || !item) && addItem({...formItem, name: formItem.name ? formItem.name : user?.first_name , user_created: user, type: props.layer.itemType, id: uuid, layer: props.layer, public_edit: !user ? true : false});
toast.success("New item created"); toast.success("New item created");
resetFilterTags(); resetFilterTags();
} }

View File

@ -0,0 +1,15 @@
import * as React from 'react'
import { TextInput } from '../../../Input'
import { Item } from '../../../../types'
export const PopupCheckboxInput = ({ dataField, label, item }:
{
dataField: string,
label: string,
item?: Item
}) => {
return (
<label htmlFor={item?.id} className="tw-label tw-justify-normal tw-pt-1 tw-pb-1"><input id={item?.id} type="checkbox" name={dataField} className="tw-checkbox tw-checkbox-xs tw-checkbox-success" checked={item?.public_edit} /><span className='tw-text-sm tw-label-text tw-mx-2 tw-cursor-pointer'>{label}</span></label>
)
}

View File

@ -1,6 +1,6 @@
import { useCallback, useReducer, createContext, useContext } from "react"; import { useCallback, useReducer, createContext, useContext } from "react";
import * as React from "react"; import * as React from "react";
import { Item, ItemsApi, Permission, PermissionAction } from "../../../types"; import { Item, ItemsApi, LayerProps, Permission, PermissionAction } from "../../../types";
import { useAuth } from "../../Auth"; import { useAuth } from "../../Auth";
type ActionType = type ActionType =
@ -22,7 +22,7 @@ function usePermissionsManager(initialPermissions: Permission[]): {
setPermissionApi: (api: ItemsApi<any>) => void; setPermissionApi: (api: ItemsApi<any>) => void;
setPermissionData: (data: Permission[]) => void; setPermissionData: (data: Permission[]) => void;
setAdminRole: (adminRole: string) => void; setAdminRole: (adminRole: string) => void;
hasUserPermission: (collectionName: string, action: PermissionAction, item?: Item) => boolean; hasUserPermission: (collectionName: string, action: PermissionAction, item?: Item, layer?: LayerProps) => boolean;
} { } {
const [permissions, dispatch] = useReducer((state: Permission[], action: ActionType) => { const [permissions, dispatch] = useReducer((state: Permission[], action: ActionType) => {
switch (action.type) { switch (action.type) {
@ -63,7 +63,7 @@ function usePermissionsManager(initialPermissions: Permission[]): {
}, []); }, []);
const hasUserPermission = useCallback( const hasUserPermission = useCallback(
(collectionName: string, action: PermissionAction, item?: Item) => { (collectionName: string, action: PermissionAction, item?: Item, layer?: LayerProps) => {
if (permissions.length === 0) return true; if (permissions.length === 0) return true;
else if (user && user.role === adminRole) return true; else if (user && user.role === adminRole) return true;
else { else {
@ -80,7 +80,17 @@ function usePermissionsManager(initialPermissions: Permission[]): {
item.user_created?.id === user?.id item.user_created?.id === user?.id
) )
) )
// || ( !user && p.role == null ) || ( !user && p.role == null ) &&
(layer?.public_edit_items || item?.layer?.public_edit_items) &&
(
// Wenn 'item' nicht gesetzt ist, ignorieren wir die Überprüfung von 'public_edit'
!item ||
p.permissions?._and?.some(condition =>
condition.public_edit &&
condition.public_edit._eq == true &&
item.public_edit == true
)
)
); );
} }
}, },

View File

@ -7,6 +7,7 @@ export {ItemView} from './ItemView';
export {PopupTextAreaInput} from './Subcomponents/ItemPopupComponents/PopupTextAreaInput'; export {PopupTextAreaInput} from './Subcomponents/ItemPopupComponents/PopupTextAreaInput';
export {PopupStartEndInput} from './Subcomponents/ItemPopupComponents/PopupStartEndInput'; export {PopupStartEndInput} from './Subcomponents/ItemPopupComponents/PopupStartEndInput';
export {PopupTextInput} from './Subcomponents/ItemPopupComponents/PopupTextInput'; export {PopupTextInput} from './Subcomponents/ItemPopupComponents/PopupTextInput';
export {PopupCheckboxInput} from './Subcomponents/ItemPopupComponents/PopupCheckboxInput'
export {TextView} from './Subcomponents/ItemPopupComponents/TextView'; export {TextView} from './Subcomponents/ItemPopupComponents/TextView';
export {StartEndView} from './Subcomponents/ItemPopupComponents/StartEndView' export {StartEndView} from './Subcomponents/ItemPopupComponents/StartEndView'
export {PopupButton} from './Subcomponents/ItemPopupComponents/PopupButton' export {PopupButton} from './Subcomponents/ItemPopupComponents/PopupButton'

View File

@ -1,4 +1,4 @@
export { UtopiaMap, Layer, Tags, Permissions, ItemForm, ItemView, PopupTextAreaInput, PopupStartEndInput, PopupTextInput, PopupButton, TextView, StartEndView } from './Components/Map'; export { UtopiaMap, Layer, Tags, Permissions, ItemForm, ItemView, PopupTextAreaInput, PopupStartEndInput, PopupTextInput, PopupButton, TextView, StartEndView, PopupCheckboxInput } from './Components/Map';
export {AppShell, Content, SideBar} from "./Components/AppShell" export {AppShell, Content, SideBar} from "./Components/AppShell"
export {AuthProvider, useAuth, LoginPage, SignupPage, RequestPasswordPage, SetNewPasswordPage} from "./Components/Auth" export {AuthProvider, useAuth, LoginPage, SignupPage, RequestPasswordPage, SetNewPasswordPage} from "./Components/Auth"
export {UserSettings, ProfileSettings, OverlayProfile, OverlayProfileSettings, OverlayUserSettings, OverlayItemProfile, OverlayItemProfileSettings} from './Components/Profile' export {UserSettings, ProfileSettings, OverlayProfile, OverlayProfileSettings, OverlayUserSettings, OverlayItemProfile, OverlayItemProfileSettings} from './Components/Profile'

View File

@ -37,6 +37,7 @@ export interface LayerProps {
onlyOnePerOwner?: boolean, onlyOnePerOwner?: boolean,
customEditLink?: string, customEditLink?: string,
customEditParameter?: string, customEditParameter?: string,
public_edit_items?: boolean
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>, setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
itemFormPopup?: ItemFormPopupProps | null, itemFormPopup?: ItemFormPopupProps | null,
clusterRef?: any clusterRef?: any
@ -63,6 +64,7 @@ export class Item {
relations?: Relation[]; relations?: Relation[];
parent?:string; parent?:string;
subname?: string; subname?: string;
public_edit?: boolean;
[key: string]: any; [key: string]: any;
constructor(id:string,name:string,text:string,position:Geometry, layer?: LayerProps, api?: ItemsApi<any>){ constructor(id:string,name:string,text:string,position:Geometry, layer?: LayerProps, api?: ItemsApi<any>){
this.id = id; this.id = id;
@ -138,7 +140,9 @@ export type PermissionCondition = {
user_created?: { user_created?: {
_eq: string; // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID _eq: string; // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID
}; };
// Hier können weitere Bedingungen nach Bedarf hinzugefügt werden public_edit?: {
_eq: boolean; // Erwartet den speziellen Wert "$CURRENT_USER" oder eine spezifische UUID
};
}; };
export type Permission = { export type Permission = {