diff --git a/CHANGELOG.md b/CHANGELOG.md index cf2a77b..43875d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +0.30.0 +------ +- chore: Typescript strict mode + 0.29.2 ------ - fix: Email input diff --git a/package.json b/package.json index 3b61ab7..55447b5 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.29.2", + "version": "0.30.0", "repository": { "type": "git", "url": "git@github.com:guillotinaweb/guillotina_react.git" @@ -37,6 +37,7 @@ "@testing-library/user-event": "12.6.0", "@typescript-eslint/eslint-plugin": "^6.18.1", "@typescript-eslint/parser": "^6.18.1", + "@types/uuid":"9.0.8", "babel-plugin-formatjs": "^10.5.10", "eslint": "^8.56.0", "eslint-plugin-react": "^7.33.2", @@ -45,7 +46,7 @@ "prettier": "2.2.1", "sass": "1.69.5", "serialize-javascript": "5.0.1", - "typescript": "^5.3.3", + "typescript": "5.4.2", "vitest": "^0.34.6", "@types/react-beautiful-dnd": "13.1.8" }, diff --git a/src/guillo-gmi/actions/add_item.tsx b/src/guillo-gmi/actions/add_item.tsx index aeec658..60c11c4 100644 --- a/src/guillo-gmi/actions/add_item.tsx +++ b/src/guillo-gmi/actions/add_item.tsx @@ -1,6 +1,7 @@ import { useTraversal } from '../contexts' import { Modal } from '../components/modal' import { useCrudContext } from '../hooks/useCrudContext' +import { IndexSignature } from '../types/global' interface Props { type: string @@ -18,7 +19,7 @@ export function AddItem(props: Props) { Ctx.cancelAction() } - async function doSubmit(data) { + async function doSubmit(data: IndexSignature) { const form = Object.assign( {}, { '@type': type }, @@ -41,7 +42,6 @@ export function AddItem(props: Props) {
console.log(err)} actionName={'Add ' + type} title={'Add ' + type} type={type} diff --git a/src/guillo-gmi/actions/change_pass.tsx b/src/guillo-gmi/actions/change_pass.tsx index 1dbb092..057754c 100644 --- a/src/guillo-gmi/actions/change_pass.tsx +++ b/src/guillo-gmi/actions/change_pass.tsx @@ -5,6 +5,7 @@ import { Input } from '../components/input/input' import { Button } from '../components/input/button' import { Form } from '../components/input/form' import { useState } from 'react' +import { IndexSignature } from '../types/global' const initial = { pass1: '', @@ -13,7 +14,7 @@ const initial = { export function ChangePassword() { const [state, setState] = useState(initial) - const [perror, setPerror] = useState(undefined) + const [perror, setPerror] = useState(undefined) const Ctx = useTraversal() const { patch } = useCrudContext() @@ -50,8 +51,8 @@ export function ChangePassword() { Ctx.refresh() } - const setPass = (field) => (val) => { - const n = {} + const setPass = (field: string) => (val: string) => { + const n: IndexSignature = {} n[field] = val setState((state) => ({ ...state, ...n })) setPerror(undefined) diff --git a/src/guillo-gmi/actions/copy_item.tsx b/src/guillo-gmi/actions/copy_item.tsx index 38553e8..42bb455 100644 --- a/src/guillo-gmi/actions/copy_item.tsx +++ b/src/guillo-gmi/actions/copy_item.tsx @@ -3,10 +3,11 @@ import { PathTree } from '../components/modal' import { useTraversal } from '../contexts' import { useCrudContext } from '../hooks/useCrudContext' import { getNewId } from '../lib/utils' -import { ItemModel } from '../models' +import { IndexSignature } from '../types/global' +import { GuillotinaCommonObject } from '../types/guillotina' interface Props { - item: ItemModel + item: GuillotinaCommonObject } export function CopyItem(props: Props) { @@ -14,7 +15,7 @@ export function CopyItem(props: Props) { const { post } = useCrudContext() const { item } = props - async function copyItem(path, form) { + async function copyItem(path: string, form: IndexSignature) { const input = form[1] || {} const { isError, errorMessage } = await post( { diff --git a/src/guillo-gmi/actions/copy_items.tsx b/src/guillo-gmi/actions/copy_items.tsx index d32a702..cba87e6 100644 --- a/src/guillo-gmi/actions/copy_items.tsx +++ b/src/guillo-gmi/actions/copy_items.tsx @@ -3,8 +3,9 @@ import { PathTree } from '../components/modal' import { useTraversal } from '../contexts' import { getNewId } from '../lib/utils' import { ItemModel } from '../models' +import { IndexSignature } from '../types/global' -const withError = (res) => res.status >= 300 +const withError = (res: Response) => res.status >= 300 interface Props { items: Array @@ -13,11 +14,11 @@ export function CopyItems(props: Props) { const Ctx = useTraversal() const { items = [] } = props - async function copyItems(path, form) { + async function copyItems(path: string, form: IndexSignature) { const responses = await Promise.all( items.map((item, i) => { const input = form[i + 1] || {} - return Ctx.client.post(`${Ctx.path}${item['@name']}/@duplicate`, { + return Ctx.client.post(`${Ctx.path}${item.id}/@duplicate`, { destination: path, new_id: input.value || getNewId(item.id), }) @@ -55,7 +56,7 @@ export function CopyItems(props: Props) { diff --git a/src/guillo-gmi/actions/move_item.tsx b/src/guillo-gmi/actions/move_item.tsx index c6b02cb..436067c 100644 --- a/src/guillo-gmi/actions/move_item.tsx +++ b/src/guillo-gmi/actions/move_item.tsx @@ -2,20 +2,20 @@ import { PathTree } from '../components/modal' import { useGuillotinaClient, useTraversal } from '../contexts' import { useCrudContext } from '../hooks/useCrudContext' import { useLocation } from '../hooks/useLocation' -import { ItemModel } from '../models' +import { GuillotinaCommonObject } from '../types/guillotina' interface Props { - item: ItemModel + item: GuillotinaCommonObject } export function MoveItem(props: Props) { const Ctx = useTraversal() - const { post } = useCrudContext() + const { post } = useCrudContext<{ '@url': string }>() const [, navigate] = useLocation() const client = useGuillotinaClient() const { item } = props - async function moveItem(path) { + async function moveItem(path: string) { const { isError, errorMessage, result } = await post( { destination: path, @@ -26,7 +26,7 @@ export function MoveItem(props: Props) { if (!isError) { navigate({ - path: `/${client.cleanPath(result['@url'])}/`, + path: `/${client.cleanPath(result!['@url'])}/`, tab: '', }) Ctx.flash(`Field moved!`, 'success') diff --git a/src/guillo-gmi/actions/move_items.tsx b/src/guillo-gmi/actions/move_items.tsx index f9a2846..08c454c 100644 --- a/src/guillo-gmi/actions/move_items.tsx +++ b/src/guillo-gmi/actions/move_items.tsx @@ -2,7 +2,7 @@ import { PathTree } from '../components/modal' import { useTraversal } from '../contexts' import { ItemModel } from '../models' -const withError = (res) => res.status >= 300 +const withError = (res: Response) => res.status >= 300 interface Props { items: ItemModel[] @@ -11,12 +11,12 @@ export function MoveItems(props: Props) { const Ctx = useTraversal() const { items = [] } = props - async function moveItems(path) { + async function moveItems(path: string) { const responses = await Promise.all( items.map((item) => { - return Ctx.client.post(`${Ctx.path}${item['@name']}/@move`, { + return Ctx.client.post(`${Ctx.path}${item.id}/@move`, { destination: path, - new_id: item['@name'], + new_id: item.id, }) }) ) diff --git a/src/guillo-gmi/actions/remove_item.tsx b/src/guillo-gmi/actions/remove_item.tsx index c0c8637..dc42ac0 100644 --- a/src/guillo-gmi/actions/remove_item.tsx +++ b/src/guillo-gmi/actions/remove_item.tsx @@ -2,10 +2,10 @@ import { Confirm } from '../components/modal' import { useGuillotinaClient, useTraversal } from '../contexts' import { useCrudContext } from '../hooks/useCrudContext' import { useLocation } from '../hooks/useLocation' -import { ItemModel } from '../models' +import { GuillotinaCommonObject } from '../types/guillotina' interface Props { - item: ItemModel + item: GuillotinaCommonObject } export function RemoveItem(props: Props) { diff --git a/src/guillo-gmi/actions/remove_items.tsx b/src/guillo-gmi/actions/remove_items.tsx index 2acf104..5e577dd 100644 --- a/src/guillo-gmi/actions/remove_items.tsx +++ b/src/guillo-gmi/actions/remove_items.tsx @@ -13,18 +13,18 @@ export function RemoveItems(props: Props) { const cfg = useConfig() const [loading, setLoading] = useState(false) const { items = [] } = props - const last = items[items.length - 1]['@name'] + const last = items[items.length - 1].id const itemsNames = items - .map((item) => item['@name']) + .map((item) => item.id) .join(', ') .replace(`, ${last}`, ` and ${last}`) async function removeItems() { - const errors = [] + const errors: unknown[] = [] setLoading(true) const actions = items.map(async (item) => { - const res = await Ctx.client.delete(`${Ctx.path}${item['@name']}`) + const res = await Ctx.client.delete(`${Ctx.path}${item.id}`, {}) if (!res.ok) { const err = await res.json() errors.push(err) diff --git a/src/guillo-gmi/components/Link.tsx b/src/guillo-gmi/components/Link.tsx index 57f30e9..0c4574e 100644 --- a/src/guillo-gmi/components/Link.tsx +++ b/src/guillo-gmi/components/Link.tsx @@ -12,7 +12,7 @@ export function Link({ aRef, model, children, ...props }: Props) { const [path, navigate] = useLocation() const aStyle = { textDecoration: 'none', color: 'currentColor' } - function onClick(e) { + function onClick(e: React.MouseEvent) { e.stopPropagation() if (actAsLink(e)) return e.preventDefault() @@ -32,6 +32,6 @@ export function Link({ aRef, model, children, ...props }: Props) { ) } -function actAsLink(e) { +function actAsLink(e: React.MouseEvent) { return e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || e.button !== 0 } diff --git a/src/guillo-gmi/components/TdLink.tsx b/src/guillo-gmi/components/TdLink.tsx index a64336b..ddf041e 100644 --- a/src/guillo-gmi/components/TdLink.tsx +++ b/src/guillo-gmi/components/TdLink.tsx @@ -9,7 +9,7 @@ interface Props { style?: IndexSignature } export function TdLink({ model, children, style = {} }: Props) { - const link = useRef() + const link = useRef(null) function onClick() { if (link && link.current) { diff --git a/src/guillo-gmi/components/behavior_view.tsx b/src/guillo-gmi/components/behavior_view.tsx index 02c48b0..c4288eb 100644 --- a/src/guillo-gmi/components/behavior_view.tsx +++ b/src/guillo-gmi/components/behavior_view.tsx @@ -12,16 +12,21 @@ export function BehaviorsView({ context, schema }: Props) { const Ctx = useTraversal() const { getBehavior } = Ctx.registry - const behaviors = [].concat( - context.__behaviors__, - context['@static_behaviors'] - ) - const GetBehavior = (b) => { - const Cls = getBehavior(b, BehaviorNotImplemented) + const behaviors: string[] = [ + ...(context.__behaviors__ ?? []), + ...Object(context['@static_behaviors']), + ] + + const GetBehavior = (behaviorName: string) => { + const Cls = getBehavior(behaviorName, BehaviorNotImplemented) return ( ) } diff --git a/src/guillo-gmi/components/behaviors/iattachment.tsx b/src/guillo-gmi/components/behaviors/iattachment.tsx index 72e326f..2a0dfff 100644 --- a/src/guillo-gmi/components/behaviors/iattachment.tsx +++ b/src/guillo-gmi/components/behaviors/iattachment.tsx @@ -7,11 +7,13 @@ import { useIntl } from 'react-intl' import { genericMessages } from '../../locales/generic_messages' import { GuillotinaFile, - GuillotinaSchemaProperties, + GuillotinaSchemaProperty, } from '../../types/guillotina' interface Props { - properties: GuillotinaSchemaProperties + properties: { + file: GuillotinaSchemaProperty + } values: { file: GuillotinaFile } @@ -38,9 +40,9 @@ export function IAttachment({ properties, values }: Props) { diff --git a/src/guillo-gmi/components/behaviors/iimageattachment.tsx b/src/guillo-gmi/components/behaviors/iimageattachment.tsx index 64e5e49..502716e 100644 --- a/src/guillo-gmi/components/behaviors/iimageattachment.tsx +++ b/src/guillo-gmi/components/behaviors/iimageattachment.tsx @@ -15,7 +15,9 @@ import { import { GuillotinaFile, GuillotinaSchemaProperties, + GuillotinaSchemaProperty, } from '../../types/guillotina' +import { LightFile } from '../../types/global' const _sizesImages = ['large', 'preview', 'mini', 'thumb'] @@ -31,15 +33,18 @@ export function IImageAttachment({ properties, values }: Props) { const Ctx = useTraversal() const modifyContent = Ctx.hasPerm('guillotina.ModifyContent') const sizesImages = cfg.SizeImages || _sizesImages - const [file, setFile] = useState(null) + const [file, setFile] = useState(null) const [loading, setLoading] = useState(false) - const [error, setError] = useState(undefined) + const [error, setError] = useState(undefined) const [showConfirmToDelete, setShowConfirmToDelete] = useState(false) - const uploadFile = async (ev) => { + const uploadFile = async (ev: React.MouseEvent) => { ev.preventDefault() setLoading(true) setError(undefined) + if (!file) { + return + } const endpoint = `${Ctx.path}@upload/image` const req = await Ctx.client.upload(endpoint, file) if (req.status !== 200) { @@ -69,7 +74,7 @@ export function IImageAttachment({ properties, values }: Props) { } } - setFile(undefined) + setFile(null) setLoading(false) Ctx.flash(intl.formatMessage(genericFileMessages.image_uploaded), 'success') Ctx.refresh() @@ -119,7 +124,7 @@ export function IImageAttachment({ properties, values }: Props) { field={'image'} value={values['image']} ns="guillotina.behaviors.behaviors.IImageAttachment" - schema={properties['image']} + schema={properties['image'] as GuillotinaSchemaProperty} modifyContent={false} />
diff --git a/src/guillo-gmi/components/behaviors/imultiattachment.tsx b/src/guillo-gmi/components/behaviors/imultiattachment.tsx index e8c33be..d6d31dc 100644 --- a/src/guillo-gmi/components/behaviors/imultiattachment.tsx +++ b/src/guillo-gmi/components/behaviors/imultiattachment.tsx @@ -17,7 +17,9 @@ import { LightFile } from '../../types/global' import { GuillotinaFile, GuillotinaSchemaProperties, + GuillotinaSchemaProperty, } from '../../types/guillotina' +import { get } from '../../lib/utils' interface Props { properties: GuillotinaSchemaProperties @@ -31,14 +33,16 @@ export function IMultiAttachment({ properties, values }: Props) { const intl = useIntl() const [fileKey, setFileKey] = useState('') const [file, setFile] = useState(undefined) - const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined) + const [fileKeyToDelete, setFileKeyToDelete] = useState( + undefined + ) const [loading, setLoading] = useState(false) - const [error, setError] = useState(undefined) + const [error, setError] = useState(undefined) const { Ctx } = useCrudContext() const modifyContent = Ctx.hasPerm('guillotina.ModifyContent') - const uploadFile = async (ev) => { + const uploadFile = async (ev: React.MouseEvent) => { ev.preventDefault() if (!fileKey && !file) { setError(intl.formatMessage(genericFileMessages.error_file_key_name)) @@ -46,6 +50,9 @@ export function IMultiAttachment({ properties, values }: Props) { } setLoading(true) setError(undefined) + if (!file) { + return + } const endpoint = `${Ctx.path}@upload/files/${fileKey}` const req = await Ctx.client.upload(endpoint, file) if (req.status !== 200) { @@ -106,7 +113,13 @@ export function IMultiAttachment({ properties, values }: Props) { field={`files/${key}`} value={values['files'][key]} ns="guillotina.behaviors.attachment.IMultiAttachment.files" - schema={properties['files']['additionalProperties']} + schema={ + get( + properties, + 'files.additionalProperties', + {} + ) as GuillotinaSchemaProperty + } modifyContent={false} />
diff --git a/src/guillo-gmi/components/behaviors/imultiimageattachment.tsx b/src/guillo-gmi/components/behaviors/imultiimageattachment.tsx index dff68d9..6170424 100644 --- a/src/guillo-gmi/components/behaviors/imultiimageattachment.tsx +++ b/src/guillo-gmi/components/behaviors/imultiimageattachment.tsx @@ -17,7 +17,10 @@ import { import { GuillotinaFile, GuillotinaSchemaProperties, + GuillotinaSchemaProperty, } from '../../types/guillotina' +import { LightFile } from '../../types/global' +import { get } from '../../lib/utils' const _sizesImages = ['large', 'preview', 'mini', 'thumb'] @@ -33,16 +36,18 @@ export function IMultiImageAttachment({ properties, values }: Props) { const intl = useIntl() const cfg = useConfig() const [fileKey, setFileKey] = useState('') - const [file, setFile] = useState(null) - const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined) + const [file, setFile] = useState(undefined) + const [fileKeyToDelete, setFileKeyToDelete] = useState( + undefined + ) const [loading, setLoading] = useState(false) - const [error, setError] = useState(undefined) + const [error, setError] = useState(undefined) const { Ctx } = useCrudContext() const modifyContent = Ctx.hasPerm('guillotina.ModifyContent') const sizesImages = cfg.SizeImages || _sizesImages - const uploadFile = async (ev) => { + const uploadFile = async (ev: React.MouseEvent) => { ev.preventDefault() if (!fileKey && !file) { setError(intl.formatMessage(genericFileMessages.error_file_key_name)) @@ -50,6 +55,9 @@ export function IMultiImageAttachment({ properties, values }: Props) { } setLoading(true) setError(undefined) + if (!file) { + return + } const endpoint = `${Ctx.path}@upload/images/${fileKey}` const req = await Ctx.client.upload(endpoint, file) if (req.status !== 200) { @@ -132,7 +140,13 @@ export function IMultiImageAttachment({ properties, values }: Props) { field={`images/${key}`} value={values['images'][key]} ns="guillotina.contrib.image.behaviors.IMultiImageAttachment.images" - schema={properties['images']['additionalProperties']} + schema={ + get( + properties, + 'images.additionalProperties', + {} + ) as GuillotinaSchemaProperty + } modifyContent={false} required={false} /> diff --git a/src/guillo-gmi/components/behaviors/imultiimageorderedattachment.tsx b/src/guillo-gmi/components/behaviors/imultiimageorderedattachment.tsx index 24ebfab..8255cab 100644 --- a/src/guillo-gmi/components/behaviors/imultiimageorderedattachment.tsx +++ b/src/guillo-gmi/components/behaviors/imultiimageorderedattachment.tsx @@ -9,6 +9,7 @@ import { useEffect, useState } from 'react' import { DragDropContext, Draggable, + DropResult, Droppable, DroppableProvided, DroppableStateSnapshot, @@ -22,7 +23,10 @@ import { import { GuillotinaFile, GuillotinaSchemaProperties, + GuillotinaSchemaProperty, } from '../../types/guillotina' +import { get } from '../../lib/utils' +import { LightFile } from '../../types/global' interface StrictModeDroppableProps { children( @@ -49,7 +53,7 @@ const StrictModeDroppable = ({ return {children} } -const reorder = (list, startIndex, endIndex) => { +const reorder = (list: string[], startIndex: number, endIndex: number) => { const result: string[] = Array.from(list) const [removed] = result.splice(startIndex, 1) result.splice(endIndex, 0, removed) @@ -72,7 +76,9 @@ const messages = defineMessages({ interface Props { properties: GuillotinaSchemaProperties values: { - images: GuillotinaFile[] + images: { + [key: string]: GuillotinaFile + } } } export function IMultiImageOrderedAttachment({ properties, values }: Props) { @@ -81,17 +87,19 @@ export function IMultiImageOrderedAttachment({ properties, values }: Props) { const [sortedList, setSortedList] = useState( Object.keys(values['images']) ) - const [file, setFile] = useState(null) - const [fileKeyToDelete, setFileKeyToDelete] = useState(undefined) + const [file, setFile] = useState(undefined) + const [fileKeyToDelete, setFileKeyToDelete] = useState( + undefined + ) const [loading, setLoading] = useState(false) - const [error, setError] = useState(undefined) + const [error, setError] = useState(undefined) const { Ctx } = useCrudContext() const modifyContent = Ctx.hasPerm('guillotina.ModifyContent') const sizesImages = cfg.SizeImages || _sizesImages - async function onDragEnd(result) { + async function onDragEnd(result: DropResult) { if (!result.destination) { return } @@ -121,7 +129,7 @@ export function IMultiImageOrderedAttachment({ properties, values }: Props) { Ctx.refresh() } - const uploadFile = async (ev) => { + const uploadFile = async (ev: React.MouseEvent) => { ev.preventDefault() if (!file) { setError(intl.formatMessage(genericFileMessages.error_file_key_name)) @@ -216,7 +224,13 @@ export function IMultiImageOrderedAttachment({ properties, values }: Props) { field={`images/${key}`} value={values['images'][key]} ns="guillotina.contrib.image.behaviors.IMultiImageAttachment.images" - schema={properties['images']['additionalProperties']} + schema={ + get( + properties, + 'images.additionalProperties', + {} + ) as GuillotinaSchemaProperty + } modifyContent={false} required={false} /> diff --git a/src/guillo-gmi/components/behaviors/iworkflow.tsx b/src/guillo-gmi/components/behaviors/iworkflow.tsx index db1aa93..7009dc2 100644 --- a/src/guillo-gmi/components/behaviors/iworkflow.tsx +++ b/src/guillo-gmi/components/behaviors/iworkflow.tsx @@ -1,12 +1,12 @@ import { useTraversal } from '../../contexts' import { Confirm } from '../modal' import { useCrudContext } from '../../hooks/useCrudContext' -import { ItemModel } from '../../models' import { defineMessages, useIntl } from 'react-intl' import { useEffect, useState } from 'react' import { useVocabulary } from '../../hooks/useVocabulary' import { get } from '../../lib/utils' +import { Workflow } from '../../types/guillotina' const messages = defineMessages({ status_changed_ok: { id: 'status_changed_ok', @@ -33,16 +33,16 @@ const messages = defineMessages({ export function IWorkflow() { const intl = useIntl() const Ctx = useTraversal() - const { post, loading } = useCrudContext() + const { post, loading } = useCrudContext() const modifyContent = Ctx.hasPerm('guillotina.ModifyContent') - const [definition, setDefinition] = useState(undefined) - const [workflowAction, setWorkflowAction] = useState(null) - const model = new ItemModel(Ctx.context) + const [definition, setDefinition] = useState(undefined) + const [workflowAction, setWorkflowAction] = useState( + undefined + ) const vocabulary = useVocabulary('workflow_states') - const currentState = - model.item['guillotina.contrib.workflows.interfaces.IWorkflowBehavior'][ - 'review_state' - ] + const currentState = Ctx.context[ + 'guillotina.contrib.workflows.interfaces.IWorkflowBehavior' + ]!['review_state'] async function loadDefinition() { const response = await Ctx.client.get(`${Ctx.path}/@workflow`) @@ -73,11 +73,12 @@ export function IWorkflow() { } Ctx.refresh() - setWorkflowAction(null) + setWorkflowAction(undefined) } + const getStateTitle = () => { - if (vocabulary.data?.items?.length > 0) { - const vocabularyValue = vocabulary.data.items.find( + if ((vocabulary.data?.items ?? []).length > 0) { + const vocabularyValue = vocabulary?.data?.items.find( (item) => item.token === currentState ) if (vocabularyValue) { @@ -109,7 +110,7 @@ export function IWorkflow() { {workflowAction && ( setWorkflowAction(null)} + onCancel={() => setWorkflowAction(undefined)} onConfirm={doWorkflowAction} message={intl.formatMessage(messages.confirm_message, { title: Ctx.context.title || Ctx.context['@name'], diff --git a/src/guillo-gmi/components/context_toolbar.tsx b/src/guillo-gmi/components/context_toolbar.tsx index 60d115b..bbcb43f 100644 --- a/src/guillo-gmi/components/context_toolbar.tsx +++ b/src/guillo-gmi/components/context_toolbar.tsx @@ -10,12 +10,13 @@ import { useLocation } from '../hooks/useLocation' import { Select } from './input/select' import { useIntl } from 'react-intl' import { genericMessages } from '../locales/generic_messages' +import { FilterFormElement } from '../types/global' interface State { - types?: string[] + types: string[] isActive?: boolean } -const initialState = { types: undefined } +const initialState = { types: [] } export function CreateButton() { const intl = useIntl() @@ -24,7 +25,7 @@ export function CreateButton() { const Config = useConfig() useEffect(() => { async function anyNameFunction() { - const types = await Ctx.client.getTypes(Ctx.path) + const types: string[] = await Ctx.client.getTypes(Ctx.path) setState({ types: types.filter((item) => !Config.DisabledTypes.includes(item)), }) @@ -32,7 +33,7 @@ export function CreateButton() { anyNameFunction() }, [Ctx.path]) - const doAction = (item) => { + const doAction = (item: string) => { Ctx.doAction('addItem', { type: item }) setState({ isActive: false }) } @@ -77,7 +78,7 @@ export function ContextToolbar({ AddButton }: Props) { const [location, setLocation, del] = useLocation() const traversal = useTraversal() const Config = useConfig() - const searchText = location.get('q') + const searchText = location.get('q') || '' const [searchValue, setSearchValue] = useState(searchText || '') useEffect(() => { @@ -89,19 +90,22 @@ export function ContextToolbar({ AddButton }: Props) { }, [searchText]) async function loadTypes() { - const types = await traversal.client.getTypes(traversal.path) + const types: string[] = await traversal.client.getTypes(traversal.path) setState({ types: types.filter((item) => !Config.DisabledTypes.includes(item)), }) } - const onSearchQuery = (ev) => { - const search = ev.target[0].value - setLocation({ q: search, tab: 'Items', page: 0 }) - ev.preventDefault() + const onSearchQuery = (event: React.FormEvent) => { + event.preventDefault() + setLocation({ + q: event.currentTarget.elements.filterInput.value, + tab: 'Items', + page: 0, + }) } - const onSearchByType = (typeText) => { + const onSearchByType = (typeText: string) => { if (typeText && typeText !== '') { setLocation({ type: typeText, tab: 'Items', page: 0 }) } else { @@ -122,6 +126,7 @@ export function ContextToolbar({ AddButton }: Props) { className="input is-size-7" placeholder={intl.formatMessage(genericMessages.search)} data-test="inputFilterTest" + id="filterInput" />
@@ -145,7 +150,7 @@ export function ContextToolbar({ AddButton }: Props) { text: item, value: item, }))} - onChange={onSearchByType} + onChange={(value) => onSearchByType(value as string)} />
{traversal.hasPerm('guillotina.AddContent') && ( diff --git a/src/guillo-gmi/components/error_boundary.tsx b/src/guillo-gmi/components/error_boundary.tsx index ebd71d8..a2e23ac 100644 --- a/src/guillo-gmi/components/error_boundary.tsx +++ b/src/guillo-gmi/components/error_boundary.tsx @@ -1,11 +1,11 @@ -import { Component } from 'react' +import { Component, ErrorInfo } from 'react' import { IntlShape, injectIntl } from 'react-intl' const style = { color: '#F44336', fontSize: 20, paddingBottom: 20 } class ErrorBoundaryComponent extends Component< { intl: IntlShape; children: React.ReactNode }, - { hasError: boolean; errorMsg: string; errorStack: string } + { hasError: boolean; errorMsg: string; errorStack: string | null | undefined } > { state = { hasError: false, @@ -13,7 +13,7 @@ class ErrorBoundaryComponent extends Component< errorStack: '', } - componentDidCatch(error, errorInfo) { + componentDidCatch(error: Error, errorInfo: ErrorInfo) { this.setState({ hasError: true, errorMsg: error.message, diff --git a/src/guillo-gmi/components/fields/downloadField.tsx b/src/guillo-gmi/components/fields/downloadField.tsx index b742956..cddd132 100644 --- a/src/guillo-gmi/components/fields/downloadField.tsx +++ b/src/guillo-gmi/components/fields/downloadField.tsx @@ -16,7 +16,7 @@ export const DownloadField = ({ value }: DownloadFieldProps) => { const Ctx = useTraversal() const { data, field } = value - const getField = async (downloadFile) => { + const getField = async (downloadFile: boolean) => { const endpoint = `${Ctx.path}@download/${field}` const res = await Ctx.client.download(endpoint) const text = await res.blob() diff --git a/src/guillo-gmi/components/fields/editComponent.tsx b/src/guillo-gmi/components/fields/editComponent.tsx index be219cd..f040268 100644 --- a/src/guillo-gmi/components/fields/editComponent.tsx +++ b/src/guillo-gmi/components/fields/editComponent.tsx @@ -10,13 +10,20 @@ import { SearchInputList } from '../input/search_input_list' import { SearchInput } from '../input/search_input' import { useTraversal } from '../../contexts' import { Ref, forwardRef } from 'react' -import { GuillotinaItemsProperty } from '../../types/guillotina' -import { IndexSignature } from '../../types/global' +import { + GuillotinaFile, + GuillotinaSchemaProperty, +} from '../../types/guillotina' +import { + EditableFieldValue, + IndexSignature, + LightFile, +} from '../../types/global' interface Props { - schema: GuillotinaItemsProperty - val: any - setValue: (value: any) => void + schema: GuillotinaSchemaProperty + val: EditableFieldValue + setValue: (value: EditableFieldValue) => void dataTest?: string className?: string placeholder?: string @@ -45,7 +52,7 @@ export const EditComponent = forwardRef( <> {placeholder && } setValue(ev)} queryCondition={ @@ -55,7 +62,7 @@ export const EditComponent = forwardRef( labelProperty={ schema?.labelProperty ? schema.labelProperty : 'title' } - typeNameQuery={schema?.typeNameQuery ? schema.typeNameQuery : null} + typeNameQuery={schema?.typeNameQuery} /> ) @@ -64,7 +71,7 @@ export const EditComponent = forwardRef( <> {placeholder && } setValue(ev)} queryCondition={ @@ -74,14 +81,14 @@ export const EditComponent = forwardRef( labelProperty={ schema?.labelProperty ? schema.labelProperty : 'title' } - typeNameQuery={schema?.typeNameQuery ? schema.typeNameQuery : null} + typeNameQuery={schema?.typeNameQuery} /> ) } else if (schema?.widget === 'textarea' || schema?.widget === 'richtext') { return (