(2023-10-08) Start Noodling on TeamGarden

Start Noodling on TeamGarden.....

Oct08'2023 going to start noodling on this

Oct10

  • try stupid approach to Bootstrap update
    • move away all the CSS and JS files, except cherwell.css which I think was part of the stuff I grabbed from BenW
    • download bootstrap.min.css and bootstrap.bundle.min.js, put them in /static/
    • change various template/header files to refer to these new filenames
  • status: not horrible looking, but
    • no header, hamburger menu with login/etc
    • no side-by-side columns, just 1 long stream
    • not following the color scheme I had set up

Oct14

  • bring back default.css which came from WithKnown. No change.
  • bring back a bunch of other mystery CSS files. No change.
  • options
    • start from scratch, try to build up what I want from bs-5-native recommendations
    • try to learn the old stuff better to adjust it
    • sounds like the 1st option is better!
  • realize I have base-vs-layout as semi-redundant template shells - clean that up to use just base, clean up tabs a bit, rip some stuff out... but still not enough...
  • meta, focus on node-page first, before dealing with FrontPage
  • ok, I'm going to start from nothing. Take Bootstrap shell of page, insert {% block body %}{% endblock %}, get super-plain page
  • bring over logic around title tag, good.
  • next - hamburger menu
    • want this one? Nope realize that involves a 3rd party plug-in, want to stay as "native" as possible.
    • looks like key is "navbar", ah this looks promising... paste it and it works.
    • merge in my version of the contents... works!
  • paste in my footer stuff, without lots of tag-shmutz... fine (though not centered)
  • paste in my header stuff (mostly metatags)... fine
  • check w3c HTML validator - fine.
  • could be finished with main page-template, but want some whitespace...
    • ah, just put <div class="container-fluid"> around the {% block body %}{% endblock %}, not bad

Oct16

  • for FrontPage template, change 'span8' to 'col-8' (and equiv '4'), and now the multi-column view works great.
  • want to play with fonts, etc.
    • ok have to bring back an over-ride CSS file - in past generation it was default.css and it was very long. I'm going to use a flux.css and keep it as small as possible
  • put in my 2 link styles like a.wikilog - works!
  • FrontPage uses panel for each item - convert them to use card, also use card-header and card-body "properly"
    • -> hmm lots of borders and padding, and light gray background for each block's header - too busy?
    • yeah drop the card-header, that reduces a lot of it
  • do I want to over-ride the native-font-stack choice? I'll let it go for now, trying to stay as "lean" as possible...
  • realize my 2 search form fields in the header were using search-query, change them to form-control - they look a little nicer now, and are collapsed at a reasonable window-width...
    • uh-oh, suddenly notice the hamburger doesn't expand at all - is that from this fresh change, or did it happen earlier? Revert to search-query, it doesn't make it better, to revert-again to form-control....
    • ah, there was some broken-html-fragment way further down in the page, which was probably causing the JS file not to load. Now all good, including the hidden forms being the right width when expanded, etc. (Though if I widen the page, the forms are short and side-by-side.... play with a break? Put each in an <li>?)
  • (login to private space works, too)

Oct17

  • hrm should I move straight to ToDoList stuff, or get TwinPages/SisterSites/WikiGraph working "locally", so I don't have the cross-domain JavaScript issue? Probably the latter....
  • do I have the table structure set up in any of my servers?
CREATE TABLE "spaces" (
    "name" varchar(32) NOT NULL UNIQUE,
    "page_pattern" varchar(128) NOT NULL,
    "all_pages_name" varchar(32) NOT NULL,
    "owner_user_id" integer);
CREATE TABLE "pages" (
    "space_name" varchar(32) NOT NULL REFERENCES "spaces" ("name"),
    "name" varchar(128) NOT NULL);
  • vs the tables in my main wikiflux/fluxgarden db:
CREATE TABLE public.spaces (
    id integer NOT NULL,
    path character varying(128),
    title character varying(128),
    owner_id integer,
    privacy_type character varying(32),
    created timestamp without time zone,
    modified timestamp without time zone
);
CREATE TABLE public.nodes (
    wiki_name_lower character varying(128) NOT NULL,
    wiki_name character varying(128) NOT NULL,
    space_id integer NOT NULL,
    body text,
    created timestamp without time zone,
    modified timestamp without time zone,
    title character varying(128),
    __ts_vector__ tsvector GENERATED ALWAYS AS (to_tsvector('english'::regconfig, (((title)::text || ' '::text) || body))) STORED
);
  • those schema made me pretty sure, but I confirmed I don't have this data merged in.
  • if I want to merge it, do I want to merge those similar tables together, or rename the WikiGraph tables? The latter would be "simpler".... What scenarios would make merging make more sense?
    • if I had so many FluxGarden customers that double-listing their pages in nodes and pages didn't make sense
    • if i planned to scrape SisterSites for their in-space connections
    • I don't think either of those are very likely....
  • further, I don't really feel like doing this work until it's really possible to finish (aka my new infrastructure is done). So I'm putting it aside.... back notes TeamGarden.....
  • what will I call to-do items? todos, tasks, actions ((2020-03-08) Taylor A Process Model Ontology)... I'm leaning toward tasks
  • what fields do I need to add? How many should get actual 'fields' vs being smushed into a json blob field?
    • parents: for notes, also
      • hmm, I have a mentions table (FrontLinks), which I use to generate BackLinks.... should I had a flag field on that table? In a sense the parent/child relation is a front/backlink which might not be explicit in the body.... so that record would be managed separately from the auto-dump/scrape upon page-edit, which kinda makes it feel like a separate table is better.... but...?
    • type or equiv to distinguish from notes?
      • Or does the presence of a field like 'status' indicate that?
      • Down the road, might a node have multiple types/templates?
    • status
    • watchers/participants/roles/permissions/priorities? {'bob':{'role':'assignee', 'priority':67, 'private':0}, 'jane':{'role':'creator', 'priority':2, 'private':0}}? (do I need a groups concept for people, for permissions?) (is there a permissions model I can steal from somewhere?)
  • conclusion: KISS/YAGNI: add a json-b field node_data for status and person/priority just (where I'm the only user), take it from there...)

Oct22

  • SQL alter table nodes add column node_data JSONB;, models.py from sqlalchemy import Column, Integer, String, Text, UnicodeText, DateTime, ForeignKey, Boolean, JSON, JSONB and node_data = Column(JSONB) -> ImportError: cannot import name 'JSONB' from 'sqlalchemy' (I'm running 1.3.23). Ah, have to use from sqlalchemy.dialects.postgresql import JSONB
  • UI to start creating a task?
    • Do I have to make it a Subtask of an existing node? My YAGNI says no, I'm going to rely on links/backlinks
    • Do I add some sort of field to the Edit form? Maybe a pulldown of status values, with null as a starting point, and if I pick a non-null value then that sets the value and tells me it's a task? Yeah, let's do that.... And contrary to earlier note I'll have status values be just ToDo, InProgress, and Done.
  • forms.py: status = SelectField('Status:', choices=['ToDo', 'InProcess', 'Done'])... routes.py: node_data=jsonify(status)
  • do "quick" add -> record saved but node_data is empty
  • needed to add to: node = Node(space.id, page_url, title, body, created, modified, node_data)
  • try again -> Object of type Response is not JSON serializable.... 'node_data': <Response 7 bytes [200 OK]>
  • change routes.py to node_data=json.dumps({"status": status}) -> works? command-line query shows value as "{\"status\": \"InProcess\"}"
  • add if status=='Status': node_data = None -> "All fields required". Ah that's my own code, tied to form.errors... not a valid choice. Have to add 'Status' to the 'choices' list in forms.py so form will validate, then I can still over-ride that to set node_data = None. All good.
  • have created a few tasks. All of them are included on FrontPage/RecentChanges. All appear as Backlinks for the appropriate Parent/Note page.
  • how should my Tasks-list page work? I want
    • a prioritized list where I can drag/drop to reprioritize
    • what about new items with priority=null? Do I
      • automatically put them at the bottom of the list? Nope, because I know I end up with infinite tasks and will never find them?
        • hmm if nearly infinite will they be manageable? Will probably (a) have paginated (by 100) view, with (b) a "push to top" button for each task to jump it to the top...
      • automatically put them at the top of the list?
      • keep them in a 2nd list, sorted by create-date (or mod-date), with easy way to move them to top of priority list? Is it possible to drag an item from un-prioritized list to a slot in the prioritized list? Is that an htmx question?
        • see doc on wrapping the SortableJs with HTMX. See Sortable's "shared lists" example, that seems perfect. When the list is reordered via the Sortable.js drag-and-drop, the end event will be fired. htmx will then post the item ids in the new order to /items, to be persisted by the server. Does that mean I'll be re-writing a long list each time? What about the tasks after priority=100? (Note the HTMX example isn't of the shared-list version... Ah, discussion.
      • Hrm this makes me lean to "default at top of list" model.... how would that work? How would I define 'priority' so that I didn't have to rewrite the whole list each time? Maybe (a) start with a super-high-int (10^10 - 1?) as starting value, (b) always have the min(priority), and (c) set newItem.priority=minPriority-1? But then I have to worry about destination is between n and n+1.... or maybe ok that priority isn't unique, except my list will change... maybe use float/real instead of int, and split the difference?
    • further up I propose a JSON format for people+roles+priorities... do I bother with that now, default to me/assignee? Yeah, I think so, and use users.usename....
    • so node_data would look like {"status": "ToDo", "people": {"BillSeitz":{"role":"assignee", "priority":999999999, "private":0}}}
    • trying to mass-set the value via command-line (mac-postgresql) for the 4 tasks I've created..., using this example: update nodes set node_data =jsonb_set(node_data, '{people}', '{"BillSeitz":{"role":"assignee", "priority":999999999, "private":0}}',true) where node_data is not null; -> cannot set path in scalar
      • this makes it sound even easier, but also doesn't work
      • could it be something specific to Mac/command-line, maybe with single-quotes vs double-quotes?
      • and/or maybe I'll start by wiping out the existing fields, because they don't smell right either....
      • I wiped out the existing field data
      • now the update command above acts like it worked (UPDATE 6), but a select shows no data

Nov10

  • new plan, do some temporary hack in edit-node UI/code to push in the full JSON I want
    • first, display it! - Done, all appear to be empty
  • realize my sample little dict above was short a final }
  • add hard-coded dict to my node_edit() logic
  • load/view a task page, edit, tweak body, save -> page says All fields required, console says
Message: 'form errors'
Arguments: ("{'status': ['Not a valid choice']}",)
  • ah, it's because my edit form has the Status pulldown only on Create not Update, so form-validation fails
  • copy Status-pulldown code to other case in edit-form, view, edit, save -> save is successful, but no data set

Nov13

  • oops I didn't have my hack-set-jsonb value code in the right place, now I do.
  • nope, logger says UPDATE command doesn't include node_data
  • is this the issue? I need to involve sqlalchemy-json? And for jsonb provide a different backing type. This is done by using the utility function mutable_json_type.

Nov21

  • make the couple changes to model.py for mutable
  • also use copy() as a hack
  • -> nope the SqlAlchemy UPDATE still doesn't include the field, gonna have to add the other library
  • install library, change code -> still doesn't work
  • try deepcopy -> UnboundLocalError: local variable 'node_data_dict' referenced before assignment
  • that just confirms that I'm creating the variable from scratch here, so why is all this craziness necessary in the first place? I'm getting that smell that it's not the mutation-detection that's the issue....
  • omg i'm an idiot, need it to be node.node_data=json.dumps(node_data_dict).
    except... -> 'super' object has no attribute 'coerce'

Nov24

  • clarified the above error happens inside sqlalchemy-json, not the json.dumps() part
    • this was an issue in 2018, and still not resolved (as of Sept'2023 - latest 'release' was Aug'2023)?
    • I tried SQL update nodes set node_data='{}' where wiki_name='SetsaveStatusWhenCreatingTask' then tried this again, same issue. (Still not sure whether that SQL is correct since I didn't use jsonb_set()
    • This issue seems too obvious, I suspect I have some other issue that triggers this edge case...
    • Tried SQL again update nodes set node_data='{"status": "ToDo"}' same result upon edit/save... in debugger I can see that node.node_data = sqlalchemy_json.NestedMutableDict({'status': 'ToDo'})
    • Nov26 post query
    • Dec13 no response/action over there. Try a tweet.

Aug12'2024

  • I find this comment-response from back in March: I am seeing this happen when the JSON passed is a string (which is valid json)
  • I have to get my local TeamGarden running again per issues (2024-04-28) Updating my MacBookPro Python
  • Apr'2025 try again, see same linked page. Blocked again. (Rather, the laptop is fine, but confirmed there's no shortcut/route-around for Linode upgrade.

Edited:    |       |    Search Twitter for discussion