from dotenv import load_dotenv load_dotenv() import streamlit as st import pandas as pd from sqlalchemy import create_engine, MetaData, Table, delete from sqlalchemy.orm import sessionmaker from utils.filter import filter_dataframe import os import time # Dados de login USERNAME = os.getenv('username') PASSWORD = os.getenv('password') # Configurações da página st.set_page_config( page_title="Banco de Dados - GeoCosmos", page_icon="⛰️", layout="wide" ) # Função para autenticação do usuário def authenticate_user(username: str, password: str) -> bool: return username == USERNAME and password == PASSWORD # Tela de login def login_screen(): st.subheader('⛰️ Banco de Dados - GeoCosmos') with st.form(key='login_form'): username = st.text_input("Nome de usuário") password = st.text_input("Senha", type='password') # Botão para submeter o formulário submit_button = st.form_submit_button('Entrar') if submit_button: if authenticate_user(username, password): st.session_state['logged_in'] = True st.rerun() else: st.error('Nome de usuário ou senha inválidos') # Função para ler dados da tabela SQL a partir de um arquivo def load_data() -> pd.DataFrame: connection_url = os.getenv("DATABASE_URL") engine = create_engine(connection_url) df = pd.read_sql_table(table_name=os.getenv("TABLE_NAME"), con=engine) return df, engine # Removido o retorno da sessão # Função para deletar linhas selecionadas def delete_selected_rows(selected_ids, engine, table): meta = MetaData() table = Table(table, meta, autoload_with=engine, schema="public") Session = sessionmaker(bind=engine) session = Session() try: with session.begin(): for id_value in selected_ids: stmt = delete(table).where(table.c.id == id_value) session.execute(stmt) finally: session.close() # Garante o fechamento da sessão # Verificar o estado de login if 'logged_in' not in st.session_state: st.session_state['logged_in'] = False # Se o usuário não está logado, exibe a tela de login if not st.session_state['logged_in']: login_screen() else: st.header('⛰️ Banco de Dados - GeoCosmos') placeholder = st.empty() with st.spinner("Carregando dados..."): # Carrega os dados apenas uma vez if 'df' not in st.session_state: df, engine = load_data() st.session_state.df = df st.session_state.engine = engine else: df = st.session_state.df engine = st.session_state.engine # Aplica o filtro ao dataframe filtered_df = filter_dataframe(df) all_columns = filtered_df.columns.tolist() selected_columns = st.multiselect( 'Escolha as colunas para exibir:', options=[col for col in all_columns if col not in ['id', 'Seleção']], placeholder="Selecione uma ou mais colunas", default=[], key="column_selector" ) if selected_columns: displayed_columns = selected_columns + ['id'] if 'Nome do documento' not in displayed_columns: displayed_columns.insert(1, 'Nome do documento') # Remove duplicatas e garante a ordem displayed_columns = list(dict.fromkeys(displayed_columns)) displayed_df = filtered_df[displayed_columns] else: displayed_df = filtered_df if st.button("🔄", type="tertiary"): del st.session_state["df"] st.rerun() # Exibe o editor com ordem fixa e key estável selected_df = st.dataframe( displayed_df, column_order=[col for col in displayed_df.columns if col != 'Seleção'], hide_index=False, key="stable_data_editor", on_select="rerun", selection_mode="multi-row" ) selected_rows = selected_df['selection']['rows'] selected_ids = displayed_df.iloc[selected_rows]["id"].tolist() # Pega os nomes dos documentos selecionados selected_docs = displayed_df.iloc[selected_rows]["Nome do documento"].tolist() if selected_ids: with st.popover("APAGAR"): st.warning("Você está prestes a apagar dados. Esta ação não pode ser desfeita.") confirmation = st.text_input("Digite 'APAGAR' e pressione ENTER para confirmar a deleção:") if confirmation == "APAGAR": if st.button("CONFIRMAR"): with st.spinner('Deletando arquivos...'): delete_selected_rows(selected_ids, engine, os.getenv("TABLE_NAME")) st.success(f'Os seguintes documentos foram apagados: {selected_docs}') del st.session_state["df"] st.rerun()