LIST / GRAPH FILTERING AND PAGING

This all applies equally to a report or a list or a graph so all work basically the same but will refer only to "list" for simplicity:

At client user can view a list and select from a dropdown of saved filters for that type of list which corresponds to an api route.
User creates filters in separate UI from the actual list, i.e. clicks on the filter button above a list to make or edit filter.
Two types of filters Named or Default:
    User can save a filter with a name for later selection or it will always default to "Default" (localized) if not edited but will always require saving to server.
    Generic "default" filter is always personal, not public / shared
    - This is a client issue, Server doesn't care what the filters are called adn has no special processing for default filters
Named filters can be made public or personal.  If public then all users with rights to that object can see them, personal are always only personal.
Filter is constructed from an FILTEROPTIONS object fetched from the server list route that has a list type name which is unique to that list route 
and also lists all the fields filterable, their type and the locale key to display it
    - e.g.: {ListKey:"widget",fields:[{fld:"name",lt:"WidgetName",type:"text"},{fld:"dollarAmount",lt:"WidgetDollarAmount",type:"currency"}]}
    - List key 
Certain types have extended abilities, for example dates have the classic floating AyaNova date ranges pre-defined or specific dates
Filters are saved to the database:
    - Filter: Name, OwnerId, Public, ListKey, Filter (Json string) 
        - ListKey is always lower case to match biz object list key name
        - Filter format:
            - Array [{fld:"fieldname",op:"See filtercomparisonoperator class",value:"compareValue"},...] these are all AND in sql, no OR 
            - fld=name of field to filter by
                - always all lower case 
                - Straight up field name like "name"
                - Could be compound for joins like "table.name" (no a prepends the table name)
                - Special indirect values such as "[TAGS]" which means cross filter with tags
            - op=one of the values specified in the FilterComparisonOperator class in Biz namespace
            - value= straight up direct comparison value
                - If string then a string fragment, case is sensitive
                - If date then iso style date //RAVEN NOTE: it is my intention that dates come in iso8601 UTC format from the client
                - could be whole number or decimal number
                - Could be a special "macro" filter value like "[THIS_MONTH]" (always surrounded by square brackets, no need to disambiguate with a string because only applies to non string values)
                - Could be a series of id values like this "[23,45,56,123]" as in tag id's or something related to that case.
   
Upon user selecting a filter to use the list query string has the regular paging info but also the filter id as a query parameter 
    - Server loads the filter if it's public or has the user ID if it's personal only
    - If list not found then it will return a 404 instead of the list    
    - server loads the filter, generates the sql based on the stored filter, adds the sort by and offset / page, runs the query and then returns the data as json collection to the client

--------------------------------------------------------
NOTES ABOUT WHY I DID THE FILTEROPTIONS LIKE I DID:
//Need a collection of fields and types and locale keys for
    //  - Client fetching filteroptions via list class
    //      - Just a static list of items localized and sent to the client
    //  - DataFilter validation via list class
    //      - static list of items to compare against
    //  - ToSql from DataFilter validation and query building via list class
    //      - Static list of filter options so that it can build sql fragment (needs to know type, possibly the field name [or that is inferred probably])
    //      - Ideally each list object will have it's own chunk of code to handle it's shit with tosql just making the fragments of sql like in v7
    //      - Again, a static list of items to check against


    //Where to store that?
    //all cases are via list class so really the whole thing is self contained and no need for an interface at all
--------------------------------------------------



LIST FILTERING TODO
    - DONE test for fetching widget filter options (localized, so have two users test each for expected response)
    - Add test for excercising all of DataFilterController route including rights to non personal alternative owner etc
    - Add test for correctly validated Widget datafilter when saved or updated via datafiltercontroller (sanity check of the filter settings and options IFilterableObject implemented)

Add test for providing saved filter id to widgetlist and recieving correct filtered / paged / sorted results (test all those)
    - Requires filter to sql code to be written and changes to the widgetlist route
    - This is where it gets real! Happy monday!! :)
    - Copy as much from v7 as possible

- Client side
  - Implement filter editor dialog and test


