Spaces:
Sleeping
Sleeping
| const TAB_LABEL_BY_SLUG = { | |
| modelos: 'Modelos Estatísticos', | |
| elaboracao: 'Elaboração/Edição', | |
| avaliacao: 'Avaliação', | |
| trabalhos: 'Trabalhos Técnicos', | |
| } | |
| const TAB_SLUG_BY_LABEL = Object.fromEntries( | |
| Object.entries(TAB_LABEL_BY_SLUG).map(([slug, label]) => [label, slug]), | |
| ) | |
| const MODELOS_SUBTAB_LABEL_BY_SLUG = { | |
| pesquisa: 'Pesquisar Modelos', | |
| repositorio: 'Repositório de Modelos', | |
| 'visao-geral': 'Visão Geral', | |
| } | |
| const MODELOS_SUBTAB_SLUG_BY_LABEL = Object.fromEntries( | |
| Object.entries(MODELOS_SUBTAB_LABEL_BY_SLUG).map(([slug, label]) => [label, slug]), | |
| ) | |
| const TRABALHOS_SUBTAB_LABEL_BY_SLUG = { | |
| repositorio: 'repositorio', | |
| mapa: 'mapa', | |
| } | |
| const TRABALHOS_SUBTAB_SLUG_BY_LABEL = Object.fromEntries( | |
| Object.entries(TRABALHOS_SUBTAB_LABEL_BY_SLUG).map(([slug, label]) => [label, slug]), | |
| ) | |
| const MODEL_TAB_SET = new Set([ | |
| 'mapa', | |
| 'trabalhos-tecnicos', | |
| 'dados-mercado', | |
| 'metricas', | |
| 'transformacoes', | |
| 'resumo', | |
| 'coeficientes', | |
| 'obs-calc', | |
| 'graficos', | |
| ]) | |
| const PESQUISA_FILTER_KEYS = [ | |
| 'nomeModelo', | |
| 'tipoModelo', | |
| 'negociacaoModelo', | |
| 'dataMin', | |
| 'dataMax', | |
| 'versionamentoModelos', | |
| 'avalFinalidade', | |
| 'avalZona', | |
| 'avalBairro', | |
| 'avalArea', | |
| 'avalRh', | |
| ] | |
| const PESQUISA_FILTER_DEFAULTS = { | |
| nomeModelo: '', | |
| tipoModelo: '', | |
| negociacaoModelo: '', | |
| dataMin: '', | |
| dataMax: '', | |
| versionamentoModelos: 'incluir_antigos', | |
| avalFinalidade: '', | |
| avalZona: '', | |
| avalBairro: '', | |
| avalArea: '', | |
| avalRh: '', | |
| } | |
| function normalizeSlug(value) { | |
| return String(value || '').trim().toLowerCase() | |
| } | |
| function trimValue(value) { | |
| return String(value || '').trim() | |
| } | |
| function parseFiniteNumber(value) { | |
| const text = trimValue(value).replace(',', '.') | |
| if (!text) return null | |
| const parsed = Number(text) | |
| return Number.isFinite(parsed) ? parsed : null | |
| } | |
| function sanitizePesquisaFilters(rawFilters = {}) { | |
| const next = { ...PESQUISA_FILTER_DEFAULTS } | |
| PESQUISA_FILTER_KEYS.forEach((key) => { | |
| if (!Object.prototype.hasOwnProperty.call(rawFilters, key)) return | |
| const value = trimValue(rawFilters[key]) | |
| if (key === 'versionamentoModelos') { | |
| next[key] = value === 'atuais' ? 'atuais' : 'incluir_antigos' | |
| return | |
| } | |
| next[key] = value | |
| }) | |
| return next | |
| } | |
| function hasPesquisaFilters(filters = {}) { | |
| return PESQUISA_FILTER_KEYS.some((key) => { | |
| const value = key === 'versionamentoModelos' | |
| ? trimValue(filters[key] || PESQUISA_FILTER_DEFAULTS[key]) | |
| : trimValue(filters[key]) | |
| if (key === 'versionamentoModelos') return value === 'atuais' | |
| return Boolean(value) | |
| }) | |
| } | |
| export function getAppTabKeyFromSlug(slug) { | |
| return TAB_LABEL_BY_SLUG[normalizeSlug(slug)] || '' | |
| } | |
| export function getAppTabSlugFromKey(label) { | |
| return TAB_SLUG_BY_LABEL[String(label || '').trim()] || '' | |
| } | |
| export function getModelosSubtabKeyFromSlug(slug) { | |
| return MODELOS_SUBTAB_LABEL_BY_SLUG[normalizeSlug(slug)] || MODELOS_SUBTAB_LABEL_BY_SLUG.pesquisa | |
| } | |
| export function getModelosSubtabSlugFromKey(label) { | |
| return MODELOS_SUBTAB_SLUG_BY_LABEL[String(label || '').trim()] || 'pesquisa' | |
| } | |
| export function getTrabalhosSubtabKeyFromSlug(slug) { | |
| return TRABALHOS_SUBTAB_LABEL_BY_SLUG[normalizeSlug(slug)] || TRABALHOS_SUBTAB_LABEL_BY_SLUG.repositorio | |
| } | |
| export function getTrabalhosSubtabSlugFromKey(label) { | |
| return TRABALHOS_SUBTAB_SLUG_BY_LABEL[String(label || '').trim()] || 'repositorio' | |
| } | |
| export function getModelTabSlug(value) { | |
| const slug = normalizeSlug(value) | |
| return MODEL_TAB_SET.has(slug) ? slug : 'mapa' | |
| } | |
| export function hasMesaDeepLink(intent) { | |
| if (!intent || typeof intent !== 'object') return false | |
| return Boolean( | |
| trimValue(intent.tab) | |
| || trimValue(intent.modeloId) | |
| || trimValue(intent.trabalhoId) | |
| || trimValue(intent.subtab) | |
| || hasPesquisaFilters(intent.filters) | |
| || (intent.avaliando && parseFiniteNumber(intent.avaliando.lat) !== null && parseFiniteNumber(intent.avaliando.lon) !== null), | |
| ) | |
| } | |
| export function normalizeMesaDeepLink(intent = {}) { | |
| const safeIntent = intent && typeof intent === 'object' ? intent : {} | |
| const rawTab = normalizeSlug(safeIntent.tab) | |
| const modeloId = trimValue(safeIntent.modeloId) | |
| const trabalhoId = trimValue(safeIntent.trabalhoId) | |
| let tab = TAB_LABEL_BY_SLUG[rawTab] ? rawTab : '' | |
| if (!tab) { | |
| if (modeloId) tab = 'modelos' | |
| if (!tab && trabalhoId) tab = 'trabalhos' | |
| } | |
| let subtab = normalizeSlug(safeIntent.subtab) | |
| if (tab === 'modelos') { | |
| if (modeloId) { | |
| subtab = 'repositorio' | |
| } else if (!MODELOS_SUBTAB_LABEL_BY_SLUG[subtab]) { | |
| subtab = 'pesquisa' | |
| } | |
| } else if (tab === 'trabalhos') { | |
| if (!TRABALHOS_SUBTAB_LABEL_BY_SLUG[subtab]) subtab = 'repositorio' | |
| } else { | |
| subtab = '' | |
| } | |
| const filters = sanitizePesquisaFilters(safeIntent.filters) | |
| const lat = parseFiniteNumber(safeIntent.avaliando?.lat) | |
| const lon = parseFiniteNumber(safeIntent.avaliando?.lon) | |
| const avaliando = lat !== null && lon !== null ? { lat, lon } : null | |
| const modelTab = tab === 'modelos' && subtab === 'repositorio' && modeloId | |
| ? getModelTabSlug(safeIntent.modelTab) | |
| : '' | |
| return { | |
| tab, | |
| subtab, | |
| modelTab, | |
| modeloId, | |
| trabalhoId, | |
| filters, | |
| avaliando, | |
| } | |
| } | |
| export function parseMesaDeepLink(search = '') { | |
| const params = new URLSearchParams(String(search || '').replace(/^\?/, '')) | |
| const filters = {} | |
| PESQUISA_FILTER_KEYS.forEach((key) => { | |
| if (!params.has(key)) return | |
| filters[key] = params.get(key) | |
| }) | |
| return normalizeMesaDeepLink({ | |
| tab: params.get('tab'), | |
| subtab: params.get('subtab'), | |
| modelTab: params.get('modelTab'), | |
| modeloId: params.get('modeloId'), | |
| trabalhoId: params.get('trabalhoId'), | |
| filters, | |
| avaliando: { | |
| lat: params.get('avalLat'), | |
| lon: params.get('avalLon'), | |
| }, | |
| }) | |
| } | |
| export function serializeMesaDeepLink(intent = {}) { | |
| const normalized = normalizeMesaDeepLink(intent) | |
| const params = new URLSearchParams() | |
| if (normalized.tab) params.set('tab', normalized.tab) | |
| if (normalized.tab === 'modelos' && normalized.subtab) { | |
| params.set('subtab', normalized.subtab) | |
| } | |
| if (normalized.tab === 'trabalhos' && normalized.subtab && !normalized.trabalhoId) { | |
| params.set('subtab', normalized.subtab) | |
| } | |
| if (normalized.modeloId) params.set('modeloId', normalized.modeloId) | |
| if (normalized.trabalhoId) params.set('trabalhoId', normalized.trabalhoId) | |
| if (normalized.modelTab) params.set('modelTab', normalized.modelTab) | |
| if (normalized.tab === 'modelos' && normalized.subtab === 'pesquisa') { | |
| PESQUISA_FILTER_KEYS.forEach((key) => { | |
| const value = key === 'versionamentoModelos' | |
| ? trimValue(normalized.filters[key] || PESQUISA_FILTER_DEFAULTS[key]) | |
| : trimValue(normalized.filters[key]) | |
| if (key === 'versionamentoModelos') { | |
| if (value === 'atuais') params.set(key, value) | |
| return | |
| } | |
| if (value) params.set(key, value) | |
| }) | |
| if (normalized.avaliando) { | |
| params.set('avalLat', String(normalized.avaliando.lat)) | |
| params.set('avalLon', String(normalized.avaliando.lon)) | |
| } | |
| } | |
| const query = params.toString() | |
| return query ? `?${query}` : '' | |
| } | |
| export function buildMesaUrl(intent = {}) { | |
| if (typeof window === 'undefined') return serializeMesaDeepLink(intent) | |
| const url = new URL(window.location.href) | |
| url.search = serializeMesaDeepLink(intent) | |
| url.hash = '' | |
| return url.toString() | |
| } | |
| function syncHuggingFaceParentUrl(queryString = '', hash = '') { | |
| if (typeof window === 'undefined') return | |
| if (!window.parent || window.parent === window) return | |
| try { | |
| window.parent.postMessage( | |
| { | |
| queryString, | |
| hash, | |
| }, | |
| 'https://huggingface.co', | |
| ) | |
| } catch { | |
| // Ignora falhas cross-origin e mantém o sync local no iframe. | |
| } | |
| } | |
| export function replaceMesaDeepLink(intent = {}) { | |
| if (typeof window === 'undefined') return | |
| const queryString = serializeMesaDeepLink(intent) | |
| window.history.replaceState(null, '', buildMesaUrl(intent)) | |
| syncHuggingFaceParentUrl(queryString, '') | |
| } | |
| export function pushMesaDeepLink(intent = {}) { | |
| if (typeof window === 'undefined') return | |
| const queryString = serializeMesaDeepLink(intent) | |
| window.history.pushState(null, '', buildMesaUrl(intent)) | |
| syncHuggingFaceParentUrl(queryString, '') | |
| } | |
| export function buildRepositorioModeloLink(modeloId, modelTab = 'mapa') { | |
| return buildMesaUrl({ | |
| tab: 'modelos', | |
| subtab: 'repositorio', | |
| modeloId, | |
| modelTab, | |
| }) | |
| } | |
| export function buildAvaliacaoModeloLink(modeloId) { | |
| return buildMesaUrl({ | |
| tab: 'avaliacao', | |
| modeloId, | |
| }) | |
| } | |
| export function buildElaboracaoModeloLink(modeloId) { | |
| return buildMesaUrl({ | |
| tab: 'elaboracao', | |
| modeloId, | |
| }) | |
| } | |
| export function buildTrabalhoTecnicoLink(trabalhoId) { | |
| return buildMesaUrl({ | |
| tab: 'trabalhos', | |
| trabalhoId, | |
| }) | |
| } | |
| export function buildPesquisaLink(filters = {}, avaliando = null) { | |
| return buildMesaUrl({ | |
| tab: 'modelos', | |
| subtab: 'pesquisa', | |
| filters, | |
| avaliando, | |
| }) | |
| } | |
| export function buildPesquisaRoutePayload(filters = {}, avaliando = null) { | |
| return normalizeMesaDeepLink({ | |
| tab: 'modelos', | |
| subtab: 'pesquisa', | |
| filters, | |
| avaliando, | |
| }) | |
| } | |
| export function getPesquisaFilterDefaults() { | |
| return { ...PESQUISA_FILTER_DEFAULTS } | |
| } | |
| export function hasPesquisaRoutePayload(filters = {}, avaliando = null) { | |
| return hasPesquisaFilters(filters) || Boolean(avaliando) | |
| } | |