-
Notifications
You must be signed in to change notification settings - Fork 48
Implement IndexedDB for flow definitions and add revision handling logic #3380
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
dc9f067
0b8f976
9b06d85
a92d4b8
3b818b9
14f4b43
4c6734b
c0e60d7
ad9317c
ce7138f
2020d7b
581aebf
8417fb8
7e3fe1b
cfdd620
cdb2729
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,9 +4,115 @@ | |
|
|
||
| import Tooltip from 'components/UI/Tooltip/Tooltip'; | ||
| import styles from './FlowEditor.module.css'; | ||
| import { getAuthSession } from 'services/AuthService'; | ||
|
|
||
| const glificBase = FLOW_EDITOR_API; | ||
|
|
||
| const DB_NAME = 'FlowDefinitionDB'; | ||
| const VERSION = 1; | ||
| const STORE_NAME = 'flowDefinitions'; | ||
| let dbInstance: IDBDatabase | null = null; | ||
|
|
||
| async function initDB(): Promise<IDBDatabase> { | ||
| if (dbInstance) { | ||
| return dbInstance; | ||
| } | ||
|
|
||
| return new Promise((resolve, reject) => { | ||
| const request = indexedDB.open(DB_NAME, VERSION); | ||
|
|
||
| request.onerror = () => { | ||
| reject(new Error('Failed to open IndexedDB')); | ||
| }; | ||
|
|
||
| request.onsuccess = () => { | ||
| dbInstance = request.result; | ||
| resolve(dbInstance); | ||
| }; | ||
|
|
||
| request.onupgradeneeded = (event) => { | ||
| const db = (event.target as IDBOpenDBRequest).result; | ||
|
|
||
| if (!db.objectStoreNames.contains(STORE_NAME)) { | ||
| const store = db.createObjectStore(STORE_NAME, { keyPath: 'uuid' }); | ||
| store.createIndex('timestamp', 'timestamp', { unique: false }); | ||
| } | ||
| }; | ||
| }); | ||
| } | ||
|
|
||
| export const getFlowDefinition = async (uuid: string): Promise<any | null> => { | ||
| const db = dbInstance || (await initDB()); | ||
| if (!db) { | ||
| console.warn('Database not initialized. Call initDB() first.'); | ||
| return null; | ||
| } | ||
|
|
||
| return new Promise((resolve, reject) => { | ||
| const transaction = db.transaction([STORE_NAME], 'readonly'); | ||
| const store = transaction.objectStore(STORE_NAME); | ||
| const request = store.get(uuid); | ||
|
|
||
| request.onsuccess = () => { | ||
| const result = request.result; | ||
| resolve(result ? result : null); | ||
| }; | ||
|
|
||
| request.onerror = () => { | ||
| reject(new Error('Failed to get flow definition')); | ||
| }; | ||
| }); | ||
| }; | ||
|
|
||
| export const fetchLatestRevision = async (uuid: string) => { | ||
| try { | ||
| let latestRevision = null; | ||
| const token = getAuthSession('access_token'); | ||
|
|
||
| const response = await fetch(`${glificBase}revisions/${uuid}?version=13.2`, { | ||
| headers: { | ||
| authorization: token, | ||
| }, | ||
| }); | ||
| const data = await response.json(); | ||
|
|
||
| if (data.results.length > 0) { | ||
| latestRevision = data.results.reduce((latest: any, current: any) => { | ||
| return new Date(latest.created_on) > new Date(current.created_on) ? latest : current; | ||
| }); | ||
| } | ||
|
|
||
| return latestRevision; | ||
| } catch (error) { | ||
| console.error('Error fetching latest revision:', error); | ||
| return null; | ||
| } | ||
| }; | ||
|
|
||
| export const postLatestRevision = async (uuid: string, definition: any) => { | ||
| const url = `${glificBase}revisions/${uuid}`; | ||
| const token = getAuthSession('access_token'); | ||
|
|
||
| try { | ||
| const response = await fetch(url, { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| authorization: token, | ||
| }, | ||
| body: JSON.stringify(definition), | ||
| }); | ||
|
|
||
| if (response.ok) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } catch (error) { | ||
| console.error('Error posting latest revision:', error); | ||
| return false; | ||
| } | ||
| }; | ||
|
|
||
| export const setConfig = (uuid: any, isTemplate: boolean, skipValidation: boolean) => { | ||
| const services = JSON.parse(localStorage.getItem('organizationServices') || '{}'); | ||
|
|
||
|
|
@@ -109,7 +215,7 @@ | |
| return config; | ||
| }; | ||
|
|
||
| export const loadfiles = (startFlowEditor: any) => { | ||
| export const loadfiles = async (startFlowEditor: any) => { | ||
|
||
| const files: Array<HTMLScriptElement | HTMLLinkElement> = []; | ||
| const filesToLoad: any = Manifest.files; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include
Bearerprefix on Authorization headerThe flow-editor API expects standard bearer auth. Here we send the raw token (
authorization: token), which the backend treats as missing credentials, returning 401. This regresses publishing after idle periods—the exact bug reported in PR comments. Prefix the header withBearer(and bail early iftokenis falsy) so the request reuses our auth session correctly.📝 Committable suggestion
🤖 Prompt for AI Agents