diff --git a/packages/unigraph-dev-explorer/src/components/ObjectView/ExecutableView.tsx b/packages/unigraph-dev-explorer/src/components/ObjectView/ExecutableView.tsx index 1c194ecd..60254878 100644 --- a/packages/unigraph-dev-explorer/src/components/ObjectView/ExecutableView.tsx +++ b/packages/unigraph-dev-explorer/src/components/ObjectView/ExecutableView.tsx @@ -23,9 +23,9 @@ export const Executable: DynamicViewRenderer = ({ data, callbacks }) => { window.newTab(window.layoutModel, { type: 'tab', name: 'Component preview', - component: `/pages/${data.uid}`, + component: `/pages/library/object`, enableFloat: 'true', - config: {}, + config: { uid: data.uid, type: '$/schema/executable' }, }); }, 'lambda/js': async () => { diff --git a/packages/unigraph-dev-explorer/src/examples/todo/TodoDefaultViews.tsx b/packages/unigraph-dev-explorer/src/examples/todo/TodoDefaultViews.tsx index d5cad3cd..7d053bdd 100644 --- a/packages/unigraph-dev-explorer/src/examples/todo/TodoDefaultViews.tsx +++ b/packages/unigraph-dev-explorer/src/examples/todo/TodoDefaultViews.tsx @@ -5,31 +5,6 @@ import { DynamicObjectListView } from '../../components/ObjectView/DynamicObject import { withUnigraphSubscription } from '../../unigraph-react'; import { ATodoList, filters, groupByTags, groupers } from './utils'; -function TodoListBody({ data }: { data: ATodoList[] }) { - const todoList = data; - - const [filteredItems, setFilteredItems] = React.useState(todoList); - - React.useEffect(() => { - const res = todoList; - setFilteredItems(res); - console.log('TodoListBody', { data }); - }, [todoList]); - - return ( -
- -
- ); -} - export const TodoInbox = (props: any) => ( ) => { }, ); }; + +function TodoListBodyFactory(filtersMaker: any[], attrs?: any) { + return function ({ data }: { data: ATodoList[] }) { + const todoList = data; + + // eslint-disable-next-line react-hooks/rules-of-hooks + const [filteredItems, setFilteredItems] = React.useState(todoList); + + // eslint-disable-next-line react-hooks/rules-of-hooks + React.useEffect(() => { + const res = todoList; + setFilteredItems(res); + // console.log('TodoListBody', { data }); + }, [todoList]); + + return ( +
+ +
+ ); + }; +} + +const TodoListBody = TodoListBodyFactory(['only-incomplete']); +const UntaggedTodoListBody = TodoListBodyFactory(['only-incomplete', 'only-untagged']); +const TodoTodayBody = TodoListBodyFactory(['only-incomplete', 'until-today'], { groupBy: 'due_date' }); +const TodoUpcomingBody = TodoListBodyFactory(['only-incomplete'], { groupBy: 'due_date' }); + export const TodoAll = (props: any) => { const Component = withSubscribeTodos(TodoListBody); return ; }; -function TodoTodayBody({ data }: { data: ATodoList[] }) { - const todoList = data; - - const [filteredItems, setFilteredItems] = React.useState(todoList); - - React.useEffect(() => { - const res = todoList; - setFilteredItems(res); - console.log('TodoUpcomingBody', { data }); - }, [todoList]); - - return ( -
- -
- ); -} +export const TodoUntagged = (props: any) => { + const Component = withSubscribeTodos(UntaggedTodoListBody); + return ; +}; export const TodoToday = (props: any) => { const Component = withSubscribeTodos(TodoTodayBody); return ; }; -function TodoUpcomingBody({ data }: { data: ATodoList[] }) { - const todoList = data; - - const [filteredItems, setFilteredItems] = React.useState(todoList); - - React.useEffect(() => { - const res = todoList; - setFilteredItems(res); - console.log('TodoUpcomingBody', { data }); - }, [todoList]); - - return ( -
- -
- ); -} - export const TodoUpcoming = (props: any) => { const Component = withSubscribeTodos(TodoUpcomingBody); return ; diff --git a/packages/unigraph-dev-explorer/src/examples/todo/TodoSidebar.tsx b/packages/unigraph-dev-explorer/src/examples/todo/TodoSidebar.tsx index ab14f873..acd869a3 100644 --- a/packages/unigraph-dev-explorer/src/examples/todo/TodoSidebar.tsx +++ b/packages/unigraph-dev-explorer/src/examples/todo/TodoSidebar.tsx @@ -1,4 +1,11 @@ -import { mdiBookOpenOutline, mdiCalendarAlert, mdiCalendarOutline, mdiInboxOutline, mdiTagOutline } from '@mdi/js'; +import { + mdiBookOpenOutline, + mdiCalendarAlert, + mdiCalendarOutline, + mdiInboxOutline, + mdiTagOffOutline, + mdiTagOutline, +} from '@mdi/js'; import Icon from '@mdi/react'; import { Drawer, ListItemText, ListSubheader } from '@mui/material'; import List from '@mui/material/List'; @@ -10,9 +17,10 @@ import { useEffectOnce } from 'react-use'; import { getRandomInt, UnigraphObject } from 'unigraph-dev-common/lib/utils/utils'; import { DynamicObjectListView } from '../../components/ObjectView/DynamicObjectListView'; import { pointerHoverSx, TabContext } from '../../utils'; -import { TodoAll, TodoInbox, TodoToday, TodoUpcoming } from './TodoDefaultViews'; +import { TodoAll, TodoInbox, TodoToday, TodoUntagged, TodoUpcoming } from './TodoDefaultViews'; import { TodoTagView } from './TodoTagView'; import { + filters, getAllTodoCountFromRes, getAllTodoCountQuery, getTaggedTodoCountFromRes, @@ -21,6 +29,8 @@ import { getTodayTodoCountQuery, getTodoInboxCountFromRes, getTodoInboxCountQuery, + getUntaggedTodoCountFromRes, + getUntaggedTodoCountQuery, getUpcomingTodoCountFromRes, getUpcomingTodoCountQuery, } from './utils'; @@ -91,6 +101,13 @@ export const todoDefaultMenuItems: TodoMenuItems = { getCountQuery: getUpcomingTodoCountQuery, getCountFromRes: getUpcomingTodoCountFromRes, }, + untagged: { + iconPath: mdiTagOffOutline, + text: 'Untagged', + component: TodoUntagged, + getCountQuery: getUntaggedTodoCountQuery, + getCountFromRes: getUntaggedTodoCountFromRes, + }, }; const useCount = (query: string | undefined, getCountFromRes: any | undefined) => { @@ -149,7 +166,22 @@ const useTags = () => { // Subscribe to tags in general const subsId = getRandomInt(); - tabContext.subscribeToType('$/schema/tag', setValidTags, subsId); + tabContext.subscribeToType('$/schema/tag', setValidTags, subsId, { + queryAs: `{ + _value { + name { + <_value.%> + } + } + type { } + uid + @filter(NOT eq(<_hide>, true)) { + type @filter(eq(, "$/schema/todo")) { + uid + } + } + }`, + }); return function cleanup() { tabContext.unsubscribe(subsId); @@ -282,14 +314,29 @@ export const TodoMenuSidebar = ({ mode, setMode, todoViews, setTodoViews, todoLi .filter((key) => !_.keys(todoMenuItems.archivedTags).includes(key)) .map(renderMenuItem)} */} !_.keys(todoMenuItems.archivedTags).includes(tag.get('name').as('primitive')), - )} + items={tags + .filter( + (tag: any) => !_.keys(todoMenuItems.archivedTags).includes(tag.get('name').as('primitive')), + ) + .sort((a: any, b: any) => { + return a.get('name')?.as('primitive') < b.get('name')?.as('primitive') ? 1 : -1; + })} context={null} noDrop noBar loadAll compact + filters={[ + ...filters, + { + id: 'only-with-todo', + fn: (obj: any) => { + return obj?.['unigraph.origin']?.length > 0; + }, + }, + ]} + defaultFilter="only-with-todo" + itemStyle={{ margin: '0px', padding: '0px' }} style={{ height: 'auto' }} components={{ '$/schema/tag': { diff --git a/packages/unigraph-dev-explorer/src/examples/todo/utils.ts b/packages/unigraph-dev-explorer/src/examples/todo/utils.ts index b6eef63e..c1da7d91 100644 --- a/packages/unigraph-dev-explorer/src/examples/todo/utils.ts +++ b/packages/unigraph-dev-explorer/src/examples/todo/utils.ts @@ -26,6 +26,14 @@ export type ATodoList = { }; export const filters = [ + { + id: 'only-untagged', + fn: (obj: any) => { + const children = new UnigraphObject(obj).get('children')?.['_value['] || []; + const tags = children.filter((el: any) => el?._value?._value?.type?.['unigraph.id'] === '$/schema/tag'); + return tags.length === 0; + }, + }, { id: 'only-incomplete', fn: (obj: any) => { @@ -249,6 +257,34 @@ export const getAllTodoCountQuery = () => `; export const getAllTodoCountFromRes = flow(prop(['0', '~type']), findLast(has('todoCounts')), prop('todoCounts')); +export const getUntaggedTodoCountQuery = () => + `todos(func: uid(todos)) @filter(NOT uid(tagged) AND type(Entity)) { + todoCounts: count(uid) + } + var(func: eq(, "$/schema/todo")) @cascade { + <~type> @filter(NOT eq(<_hide>, true)) { + todos as uid + } + } + tagged as var(func: uid(todos)) @cascade { + uid + _value { + children { + <_value[> { + _value { + _value { + type @filter(eq(, "$/schema/tag")) { + uid + } + } + } + } + } + } + } + `; +export const getUntaggedTodoCountFromRes = prop(['0', 'todoCounts']); + export const getUpcomingTodoCountQuery = () => `todos(func: eq(, "$/schema/todo")) @cascade{ <~type> {