Skip to content

Commit

Permalink
Adding choice list in timeline widget
Browse files Browse the repository at this point in the history
  • Loading branch information
berhalak committed Jan 7, 2025
1 parent ae6160b commit 9a03944
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 70 deletions.
37 changes: 24 additions & 13 deletions timeline/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {buildCursor} from './cursor';
import {headerMonitor, rewriteHeader} from './header';
import {
Command,
DATA,
dateDesc,
fetchSchema,
hasChanged,
Expand Down Expand Up @@ -203,7 +204,7 @@ const options: TimelineOptions = {
async onAdd(item, callback) {
let id: number = 0;
try {
const group = idToName.get(item.group).split('|').map(stringToValue);
const group = idToCols.get(item.group);
const start = moment(item.start).format('YYYY-MM-DD');

if (!(item.start instanceof Date)) {
Expand All @@ -217,8 +218,8 @@ const options: TimelineOptions = {
const columns = [...mappings.get().Columns, mappings.get().From, mappings.get().To];
const rawFields = Object.fromEntries(zip(columns, values));

const fields = await liftFields(rawFields);
{id = (await grist.selectedTable.create({fields})).id;}
const fields = await gristfyFields(rawFields);
id = (await grist.selectedTable.create({fields})).id;

await grist.setCursorPos({rowId: id});

Expand Down Expand Up @@ -252,8 +253,10 @@ const options: TimelineOptions = {
} else if (typeof value === 'number') {
div.innerText = formatCurrency.format(value);
} else if (typeof value === 'boolean') {
div.innerHTML = `<input type="checkbox" ${value ? 'checked' : ''
} disabled>`;
div.innerHTML = `<input type="checkbox" ${value ? 'checked' : '' } disabled>`;
} else if (Array.isArray(value)) {
// We only expect here to be array of strings.
div.innerText = value.join(', ');
}
div.classList.add('group-part');
div.style.padding = '5px';
Expand Down Expand Up @@ -347,7 +350,6 @@ Object.assign((window as any), {

const newMappings = hasChanged();

let schema: Schema;

// This is async iterator
grist.onRecords(async (recs: any[], maps: any) => {
Expand All @@ -359,8 +361,8 @@ grist.onRecords(async (recs: any[], maps: any) => {
}, 80);

const areMappingsNew = newMappings(maps);
if (areMappingsNew || !schema) {
schema = await fetchSchema();
if (areMappingsNew || !DATA.schema) {
DATA.schema = await fetchSchema();
}

try {
Expand Down Expand Up @@ -821,9 +823,9 @@ function openCard() {
/**
* When creating a row in Grist we need to change values for Ref columns to row ids.
*/
async function liftFields(fields: Record<string, any>) {
const allColumns = schema.allColumns;
const myColumns = schema.columns;
async function gristfyFields(fields: Record<string, any>) {
const allColumns = DATA.schema!.allColumns;
const myColumns = DATA.schema!.columns;
let clone = null as any;

const fetchTable = memo(async (tableId: string) => await grist.docApi.fetchTable(tableId));
Expand Down Expand Up @@ -851,6 +853,15 @@ async function liftFields(fields: Record<string, any>) {
const rowId = table.id[rowIndex];
clone ??= {...fields};
clone[colId] = rowId;
} else if (type === 'ChoiceList') {
const value = fields[colId];
if (typeof value === 'string') {
clone ??= {...fields};
clone[colId] = ['L', value];
} else if (Array.isArray(value)) {
clone ??= {...fields};
clone[colId] = ['L', ...value];
}
}
}

Expand Down Expand Up @@ -938,7 +949,7 @@ function openItemDrawer(itemId: number) {

cmdAddBlank.handle(addBlank);
async function addBlank() {
const fields = await liftFields({
const fields = await gristfyFields({
[mappings.get().From]: moment().startOf('day').toDate(),
[mappings.get().To]: moment().endOf('isoWeek').toDate(),
});
Expand Down Expand Up @@ -987,7 +998,7 @@ async function duplicateSelected(ev: MouseEvent) {
)!;

await withElementSpinner(element, async () => {
const fields = await liftFields(row);
const fields = await gristfyFields(row);
await grist.selectedTable.create({fields});
});
}
Expand Down
40 changes: 11 additions & 29 deletions timeline/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export interface Schema {
columns: Column[];
}

export const DATA = {
schema: null as Schema | null,
}

export async function fetchSchema(): Promise<Schema> {
const [allColumns, tables, tableId] = await Promise.all([
fetchColumnsFromGrist(),
Expand Down Expand Up @@ -140,28 +144,6 @@ export class Command<T = any> implements Subscribable<T> {
}
}

type Infer<T> = T extends Some<infer U> ? U : T;

/**
* Identity Monad.
*/
export class Some<T> {
constructor(private _value: T) {}
public map<U>(fn: (value: T) => U): Some<Infer<U>> {
const result = fn(this._value);
if (result instanceof Some) {
return result;
}
return new Some(result) as any;
}
public valueOf() {
return this._value;
}
public static of<T>(value: T) {
return new Some(value);
}
}

export function stringToValue(value: any) {
if (['true', 'false'].includes(value)) {
return value === 'true';
Expand Down Expand Up @@ -200,15 +182,15 @@ export function valueToString(value: any) {


// Machinery to create observable for column labels.
export const MY_COLUMNS = observable([] as Column[]);
let __columnLabelCache = new Map<string, any>();
export function buildColLabel(colId: string) {
if (__columnLabelCache.has(colId)) {
return __columnLabelCache.get(colId);
if (!DATA.schema) {
return colId;;
}
if (!DATA.schema.columns || !DATA.schema.columns.length) {
return colId;
}
const obs = computed(use => use(MY_COLUMNS).find(c => c.colId === colId)?.label || colId);
__columnLabelCache.set(colId, obs);
return obs;
const column = DATA.schema.columns.find(c => c.colId === colId);
return (column ? column.label : colId) || colId;
}

/**
Expand Down
62 changes: 37 additions & 25 deletions timeline/out/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9828,6 +9828,9 @@ ${nestedRules}`.replace(/&/g, className);
async function fetchTables() {
return toRecords(await grist.docApi.fetchTable("_grist_Tables"));
}
var DATA = {
schema: null
};
async function fetchSchema() {
const [allColumns, tables, tableId] = await Promise.all([
fetchColumnsFromGrist(),
Expand Down Expand Up @@ -9927,15 +9930,16 @@ ${nestedRules}`.replace(/&/g, className);
}
return String(value);
}
var MY_COLUMNS = observable([]);
var __columnLabelCache = /* @__PURE__ */ new Map();
function buildColLabel(colId) {
if (__columnLabelCache.has(colId)) {
return __columnLabelCache.get(colId);
if (!DATA.schema) {
return colId;
;
}
if (!DATA.schema.columns || !DATA.schema.columns.length) {
return colId;
}
const obs = computed((use) => use(MY_COLUMNS).find((c6) => c6.colId === colId)?.label || colId);
__columnLabelCache.set(colId, obs);
return obs;
const column = DATA.schema.columns.find((c6) => c6.colId === colId);
return (column ? column.label : colId) || colId;
}
function memo(fn, salt) {
let prevKey = Symbol();
Expand Down Expand Up @@ -52698,7 +52702,7 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
async onAdd(item, callback) {
let id2 = 0;
try {
const group = idToName.get(item.group).split("|").map(stringToValue);
const group = idToCols.get(item.group);
const start = (0, import_moment_timezone2.default)(item.start).format("YYYY-MM-DD");
if (!(item.start instanceof Date)) {
console.error("Invalid date");
Expand All @@ -52708,10 +52712,8 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
const values3 = [...group, start, end];
const columns = [...mappings.get().Columns, mappings.get().From, mappings.get().To];
const rawFields = Object.fromEntries(zip(columns, values3));
const fields = await liftFields(rawFields);
{
id2 = (await grist.selectedTable.create({ fields })).id;
}
const fields = await gristfyFields(rawFields);
id2 = (await grist.selectedTable.create({ fields })).id;
await grist.setCursorPos({ rowId: id2 });
callback(null);
openCard();
Expand All @@ -52737,6 +52739,8 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
div.innerText = formatCurrency.format(value);
} else if (typeof value === "boolean") {
div.innerHTML = `<input type="checkbox" ${value ? "checked" : ""} disabled>`;
} else if (Array.isArray(value)) {
div.innerText = value.join(", ");
}
div.classList.add("group-part");
div.style.padding = "5px";
Expand Down Expand Up @@ -52813,14 +52817,13 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
timeline
});
var newMappings = hasChanged();
var schema;
grist.onRecords(async (recs, maps) => {
setTimeout(() => {
document.body.classList.add("slow");
}, 80);
const areMappingsNew = newMappings(maps);
if (areMappingsNew || !schema) {
schema = await fetchSchema();
if (areMappingsNew || !DATA.schema) {
DATA.schema = await fetchSchema();
}
try {
headerMonitor.pause();
Expand Down Expand Up @@ -53046,9 +53049,9 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
return;
}
const formatedValue = stringToValue(value);
const schema2 = elementId.split(":")[0];
const schema = elementId.split(":")[0];
const [parent2, child] = elementId.split(":")[1].split(".");
if (child && schema2 === "timeline") {
if (child && schema === "timeline") {
if (child === "scale") {
currentScale.set(formatedValue);
timeline.setOptions({
Expand All @@ -53063,7 +53066,7 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
}
});
}
} else if (schema2 === "timeline") {
} else if (schema === "timeline") {
timeline.setOptions({
[parent2]: formatedValue
});
Expand All @@ -53074,14 +53077,14 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
timeline.setGroups(groupSet);
timeline.redraw();
}
} else if (schema2 === "local") {
} else if (schema === "local") {
if (!(parent2 in window)) {
console.error(`Local variable ${parent2} not found in window`);
return;
}
window[parent2].set(formatedValue);
} else {
console.error(`Unknown schema ${schema2}`);
console.error(`Unknown schema ${schema}`);
}
}
timeline.setGroups(groupSet);
Expand Down Expand Up @@ -53180,9 +53183,9 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
function openCard() {
return grist.commandApi.run("viewAsCard");
}
async function liftFields(fields) {
const allColumns = schema.allColumns;
const myColumns = schema.columns;
async function gristfyFields(fields) {
const allColumns = DATA.schema.allColumns;
const myColumns = DATA.schema.columns;
let clone2 = null;
const fetchTable = memo(async (tableId) => await grist.docApi.fetchTable(tableId));
for (const colId in fields) {
Expand All @@ -53207,6 +53210,15 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
const rowId = table.id[rowIndex];
clone2 ??= { ...fields };
clone2[colId] = rowId;
} else if (type === "ChoiceList") {
const value = fields[colId];
if (typeof value === "string") {
clone2 ??= { ...fields };
clone2[colId] = ["L", value];
} else if (Array.isArray(value)) {
clone2 ??= { ...fields };
clone2[colId] = ["L", ...value];
}
}
}
return clone2 ?? fields;
Expand Down Expand Up @@ -53278,7 +53290,7 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
}
cmdAddBlank.handle(addBlank);
async function addBlank() {
const fields = await liftFields({
const fields = await gristfyFields({
[mappings.get().From]: (0, import_moment_timezone2.default)().startOf("day").toDate(),
[mappings.get().To]: (0, import_moment_timezone2.default)().endOf("isoWeek").toDate()
});
Expand Down Expand Up @@ -53320,7 +53332,7 @@ input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
)
);
await withElementSpinner(element, async () => {
const fields = await liftFields(row);
const fields = await gristfyFields(row);
await grist.selectedTable.create({ fields });
});
}
Expand Down
6 changes: 3 additions & 3 deletions timeline/out/index.js.map

Large diffs are not rendered by default.

0 comments on commit 9a03944

Please sign in to comment.