Gathering detailed insights and metrics for @tty-pt/types
Gathering detailed insights and metrics for @tty-pt/types
Gathering detailed insights and metrics for @tty-pt/types
Gathering detailed insights and metrics for @tty-pt/types
Automate table and filter creation and other things by having your data models in the client.
npm install @tty-pt/types
Typescript
Module System
Node Version
NPM Version
JavaScript (99.38%)
C (0.45%)
Makefile (0.16%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
BSD-2-Clause License
98 Commits
1 Forks
1 Watchers
8 Branches
2 Contributors
Updated on Oct 25, 2024
Latest Version
0.5.1
Package Id
@tty-pt/types@0.5.1
Unpacked Size
447.90 kB
Size
117.36 kB
File Count
61
NPM Version
10.8.2
Node Version
20.17.0
Published on
Oct 25, 2024
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
5
Automatic fetching and displaying of data through declarative data types.
This library is indended to facilitate displaying data on simple components by having a model of your data.
It can save you A lot of coding in you application!
With it, you can easily grab data from a "MetaHandler" from whatever sources, and use it anywhere with the same API (agnostic to how you fetch the data).
1npm i --save-dev @tty-pt/types
Here, we don't use a MetaHandler, just some other features of types, to display a simple table:
1import { Str, Table } from "@tty-pt/types" 2 3const type = new Shape("Actor", {}, { 4 name: new Str("Name"), 5}); 6 7export default function NameTable() { 8 return (<Table 9 type={type} 10 data={[{ name: "Joe Smith" }]} 11 columns={[ "name" ]} 12 options={{}} 13 details={[[ "name" ]]} 14 />); 15}
1import { Str, Shape, Enum, Bool } from "@tty-pt/types";
2import { IconGood, IconBad, IconNeutral } from "example";
3import { fetcher, indexer } from "lib/dependencies";
4
5const STATE = {
6 good: 0,
7 bad: 1,
8 neutral: 2,
9};
10
11const STATE_MAP = {
12 0: { title: "good", icon: IconGood },
13 1: { title: "bad", icon: IconBad },
14 1: { title: "neutral", icon: IconNeutral },
15};
16
17const incomingType = new Shape("Actor", {}, {
18 name: new Str("Name"),
19 state: new Enum("State", {
20 default: STATE.good, // data will be set to this, even if it is not received
21 getter: (_, data) => data.deeper.state
22 }, STATE, STATE_MAP);
23 alive: new Bool("Alive", {
24 // a global meta handler will run these calls, but not a local one.
25 onChange: (value) => console.log("Alive changed", value),
26 }, STATE, STATE_MAP),
27});
28
29class ExampleMetaHandler extends MetaHandler {
30 constructor(type, options = {}) {
31 super(type, options.fetcher, options.indexer, options);
32 }
33}
34
35function createHandler(type, options = {}) {
36 return new MetaHandler(type, options.fetcher, options.indexer, options);
37}
38
39
40// most of the above could easily be in other files and be shared across views
41
42// if you had a different outcoming type from the incoming type,
43// you would provide an "adapter" to map the data to the options argument
44const tableHandler = createHandler(incomingType, { fetcher, indexer });
45const outgoingType = incomingType;
46
47function App() {
48 const data = useMeta(tableHandler);
49 return (<Table
50 type={outgoingType}
51 data={data}
52 columns={["name", "state", "alive"]}
53 options={{}}
54 />);
55}
For every type, the first argument of the constructor is the title of the data field. This text is shown in the details and table header. The second (optional) argument is "meta": It can be used to customize the behavior of the type. In this section we discuss the "meta" properties that can be used in all types.
This is a function with the following signature:
1function getter(type, data, meta, parentKey) { /* ... */ }
It is used to customize how the data is obtained.
This is a string but it is somewhat similar to "getter", it is used to automatically fetch from a property of "data".
When the data is undefined, return the value of this property.
This is a function with the following signature:
1function onChange(value) { /* ... */ }
It will be run if the MetaHandler has an option named "global", and if the data corresponding to the data field of the type has changed. This is useful to have global onChange logic outside of components.
This is the value of the declaration to be used when the value of the type is undefined.
This is the value of the tooltip to displayed on undefined values.
Instance of a function that does string internationalization.
These are some base types provided with this library. These types have a lot of functionalities associated with them. For example they can render their value using icons, in most cases. They each have slightly different ways of being displayed in different situations, and to be filtered through.
An integer number
1const type = new Integer("Age"); // or new Integer("Age", { default: 0 })
A String
1const type = new Str("Name"); // or new Str("Name", { default: "Joe" })
Same as Str but it is used for rendering components. This serves to provide generic functionality to many other types.
A percentual value between 0 and 100. This shows any of a number of icons, according to its value.
1const type = new Percent("Battery", {}, [IconA, IconB, IconC]);
An Enum or an integer value that corresponds to some properties.
1const type = new Enum("Status", {}, declaration, map);
Like Enum but for boolean values
1const map = { 2 [true]: { title: "true", icon: TrueIcon }, 3 [false]: { title: "false", icon: FalseIcon }, 4}; 5 6const type = new Bool("Status", {}, map);
Like Bool but renders a checkbox instead of an icon
1const type = new Checkbox("Status", {}, map);
Like Bool but it has a notion of recursion. It has a map of sub-types.
1const type = new Shape("Human", {}, map, {
2 name: new Str("Name"),
3 age: new Integer("Age"),
4});
Like Shape but it has a different notion of recursion. It has a map in which each key may correspond to a value of a certain type.
1const type = new Dictionary("Names", {}, map, Str, []);
Fourth argument is the SubType, and the fifth is the array of arguments provided to the SubType constructor.
This has a value of type Date.
1const type = new DateTime("DateTime"); // or new DateTime("Time", { format: "time", measure: 0.001 });
This type has the following custom meta properties:
This meta property is a numeric value. This value is to be multiplied by the received data in order to get the Date object.
This is used to customize the way that the DateTime string is presented. This can be "date", "time" or other values. If the value is "date", only the date is shown, if it is "time" only the time is shown. Otherwise the time is always shown, and the date is shown when it differs from current date.
This is of a Function type. It is rendered as a button that calls that function.
1const type = new Fun("Callback");
This is a class that helps fetch data based on type information.
1const options = {}
2const exampleHandler = new MetaHandler(type, fetcher, indexer, options);
It receives four arguments in the constructor, the type, the fetcher, the indexer and the options object.
Fetcher is an instance of a class that must have three methods: getAll, subscribe and unsubscribe. The getAll method receives a callback with the received data as an argument. The subscribe method receives a callback with the received data as an argument. And it returns a subscription key. The unsubscribe method receives a subscription key.
Indexer is an instance of a class that must have two methods: subscribe and unsubscribe. The subscribe method receives a callback with the received data as an argument. And it returns a subscription key. The unsubscribe method receives a subscription key.
Now suppose you want to create a type based on Dictionary, but that has a preset map that it uses. So that we don't need to provide the map every time you want a field of that type. You can do something like this:
1// file: src/types.js 2import { extend, Dictionary as InnerDictionary } from "@tty-pt/types"; 3 4export class Dictionary extends InnerDictionary { 5 constructor(title, meta, SubType, subTypeArgs) { 6 super(title, meta, BOOL_STATUS_MAP, SubType, subTypeArgs); 7 } 8} 9 10Dictionary.extend = (SubType, subTypeArgs = [], options = {}) => 11 extend(Dictionary, [SubType, subTypeArgs], options);
Then you can use it like so:
1// file: src/views/Test.js 2import { Dictionary } from "../types"; 3 4const type = new Dictionary("Names", {}, Str, []); 5 6/* ... */
You can also do the following signature to easily extend one of these classes:
1export const Status = Bool.extend(BOOL_STATUS_MAP);
To simplify specifying the props of the components, we will use typescript as pseudo-code.
1// I will explain the following line a bit later, if you don't mind. 2const Filters = (string | { filters: Filters, className: string } | React.ElementType)[]; 3 4interface TooltipProps { 5 tooltip: string; 6 children: React.Node; 7 className: string; 8} 9 10interface GlobalFilterProps { 11 value: any; 12 dataKey: string; // TODO rename to typeKey 13 onChange: any => void; // TODO fix return type 14} 15 16// these are classNames 17interface Cast { 18 invalid: string, // invalid field 19 line: string, // draw a line 20 rotate: string, // rotate 90 degrees 21 outline: string, // outline all round 22 TextCenter: string, // center text 23 FHCenter: string, // flex center 24 Table: { 25 root: string, 26 title: string, 27 table, // main table component 28 th: string, 29 td: string, 30 Toolbar: { 31 root: string, 32 content: string, // usually contains filters 33 }, 34 }, 35 Label: { 36 title: string, 37 }, 38 Details: { 39 root: string, 40 column: string, 41 header: string, // the main line 42 container: string, // for recurse types 43 title: string, // left side of header 44 }, 45 List: { 46 root: string, 47 Toolbar: string, 48 }, 49 Tooltip: { 50 root: string, 51 content: string, 52 }, 53 TooltipCircle: string, 54 Str: { 55 Filter: string, 56 }, 57 DateTime: { 58 Filter: string, 59 }, 60 Enum: { 61 Label: string, 62 Filter: { 63 root: string, 64 active: string, // active chip 65 inactive: string, // inactive chip 66 }, 67 }, 68} 69 70interface TableProps { 71 columns: string[]; /* here you can specify paths to things that will be displayed, 72 * for example robot.name. This is similar to what you can give 73 * as filters. You can also give strings like these to filters. 74 */ 75 filters: Filters; // Sorry, please wait a bit more for a full explanation. 76 data: object[]; // Simply the data that is received for example from a MetaHandler. 77 icons: { // mui icons or similar 78 DetailPanel: React.Component; // expand icon (FIXME) 79 }; 80 details?: string[][]; // these can only be simple words for now (FIXME) 81 t?: string => string; // translate functionality 82 type: Shape; 83 title?: string; 84 name?: string; // used for identifying which inputs belong to this table, in case the table has inputs. 85 components?: { 86 Tooltip?: React.Component<TooltipProps>; // Custom Tooltip for detail headers 87 }; 88 cast?: Cast; 89 renderValue?: Boolean; // do you wish to render icons for enums, etc? 90 titleFormat?: string => string; // you can change how titles are displayed here 91 detailsTable?: Boolean; // do you wish to try to show details as sub-tables? 92 global?: { // provide this to specify that you want some sort of global filtering 93 filter?: (type: BaseType, item: object, filters: object) => Boolean; 94 Component?: React.Component<GlobalFilterProps>; 95 }; 96}
Well this is just to display a list of components. It has no special use other than filtering. The API may change.
1interface ListItemProps { 2 index: Number; 3 data: object; 4} 5 6interface ListProps { 7 data: object[]; 8 style: object; 9 type: Shape; 10 filters: Filters; // just a bit more... 11 onClick: object; // FIXME 12 Component: React.Component<ListItemProps>; 13 [key: string]?: any; 14}
Filters, as previously stated, has a format like the following:
1const Filters = (string | { filters: Filters, className: string } | React.ElementType)[];
So, it is an array. It can be an array of strings, Elements or that option in the middle. Aka:
1const BoxFilters = { filters: Filters, className: string };
If it is in this format, well it has a sort of recursive behavior in which you can specify the layout a bit better to account for a couple of situations.
No vulnerabilities found.
No security vulnerabilities found.