Todo App v4 (metrics)
In this version of the Todo app, we add a Metrics
object that tracks the number of todos of each type and how many are not yet done. This allows us to show people how well they are getting through them.
We're making changes to the Todo App v3 (persistence) demo.
Additional Initialization
We create a Metrics
object with the useCreateMetrics
hook, and will need the useMetric
hook so that we can get the metrics out of it:
-const {createIndexes, createStore} = TinyBase;
+const {createIndexes, createMetrics, createStore} = TinyBase;
const {createLocalPersister, createSessionPersister} = TinyBasePersisterBrowser;
const {
CellView,
Provider,
SliceView,
useAddRowCallback,
useCell,
useCreateIndexes,
+ useCreateMetrics,
useCreatePersister,
useCreateStore,
+ useMetric,
useSetCellCallback,
useSetValueCallback,
useValue,
} = TinyBaseUiReact;
Adding Metrics
We define a metric to count how many todos are pending (i.e. not done), and then set up additional metrics to track the number of pending todos of each type. We use the useCreateMetrics
hook to memoize this whole initialization:
const indexes = useCreateIndexes(store, (store) =>
createIndexes(store).setIndexDefinition('types', 'todos', 'type'),
);
+ const metrics = useCreateMetrics(store, (store) => {
+ const metrics = createMetrics(store);
+ metrics.setMetricDefinition('pending', 'todos', 'sum', (getCell) =>
+ !getCell('done') ? 1 : 0,
+ );
+ TYPES.forEach((type) => {
+ metrics.setMetricDefinition(type, 'todos', 'sum', (getCell) =>
+ getCell('type') == type && !getCell('done') ? 1 : 0,
+ );
+ });
+ return metrics;
+ });
As before, we make this Metrics
object available though the Provider
component as the default for the app:
return (
- <Provider store={store} storesById={{viewStore}} indexes={indexes}>+ <Provider
+ store={store}
+ storesById={{viewStore}}
+ indexes={indexes}
+ metrics={metrics}
+ > <Title />
<NewTodo />
<Types />
<Todos />
<Inspector />
</Provider>
);
};
Upgrading The Title
Component
Now that we are tracking the total number of pending todos, we can have that number appear in the title. We simply use the useMetric
hook to get the pending
metric that was previously defined:
-const Title = () => 'Todos';
+const Title = () => {
+ const pending = useMetric('pending');
+
+ return pending > 0 ? `Todo: ${pending}` : 'All done!';
+};
Upgrading The Type
Component
We also have a metric for each type that represents the number of pending todos of that type. We can display those alongside each type name in the side-bar. Apart from the addition of the pending
variable, this component is as it was in the previous version:
const Type = ({type}) => {
+ const pending = useMetric(type);
const currentType = useValue('type', 'viewStore');
const handleClick = useSetValueCallback(
'type',
() => type,
[type],
'viewStore',
);
const className = 'type' + (type == currentType ? ' current' : '');
return (
<li className={className} onClick={handleClick}>
{type}+ {pending > 0 ? ` (${pending})` : ''}
</li>
);
};
Summary
We now have a fairly useful app for tracking todos. As a final flourish, we will add an undo and redo feature. Please continue to the Todo App v5 (checkpoints) demo.