Guilherme Silberfarb Costa commited on
Commit
97e9b7f
·
1 Parent(s): 0ad99f2

alteracoes na pesquisa

Browse files
backend/app/services/serializers.py CHANGED
@@ -66,7 +66,6 @@ def sanitize_value(value: Any) -> Any:
66
  def dataframe_to_payload(
67
  df: pd.DataFrame | None,
68
  decimals: int | None = None,
69
- exclude_round_columns: list[str] | None = None,
70
  max_rows: int | None = None,
71
  ) -> dict[str, Any] | None:
72
  if df is None:
@@ -75,12 +74,10 @@ def dataframe_to_payload(
75
  # Evita cópia quando não há transformação necessária.
76
  df_work = df if decimals is None else df.copy()
77
  if decimals is not None:
78
- excluded_cols = {str(col) for col in (exclude_round_columns or [])}
79
  numeric_cols = [
80
  col
81
  for col in df_work.select_dtypes(include=[np.number]).columns
82
  if not _is_coordinate_column(col)
83
- and str(col) not in excluded_cols
84
  ]
85
  if numeric_cols:
86
  df_work.loc[:, numeric_cols] = df_work.loc[:, numeric_cols].round(decimals)
 
66
  def dataframe_to_payload(
67
  df: pd.DataFrame | None,
68
  decimals: int | None = None,
 
69
  max_rows: int | None = None,
70
  ) -> dict[str, Any] | None:
71
  if df is None:
 
74
  # Evita cópia quando não há transformação necessária.
75
  df_work = df if decimals is None else df.copy()
76
  if decimals is not None:
 
77
  numeric_cols = [
78
  col
79
  for col in df_work.select_dtypes(include=[np.number]).columns
80
  if not _is_coordinate_column(col)
 
81
  ]
82
  if numeric_cols:
83
  df_work.loc[:, numeric_cols] = df_work.loc[:, numeric_cols].round(decimals)
frontend/src/components/PesquisaTab.jsx CHANGED
@@ -9,7 +9,7 @@ import PesquisaAdminConfigPanel from './PesquisaAdminConfigPanel'
9
  import SectionBlock from './SectionBlock'
10
 
11
  const EMPTY_FILTERS = {
12
- contemApp: '',
13
  tipoModelo: '',
14
  negociacaoModelo: '',
15
  dataMin: '',
@@ -152,7 +152,7 @@ function formatTipoImovel(modelo) {
152
  function buildApiFilters(filters) {
153
  return {
154
  otica: 'avaliando',
155
- contem_app: filters.contemApp,
156
  tipo_modelo: filters.tipoModelo,
157
  negociacao_modelo: filters.negociacaoModelo,
158
  aval_finalidade: filters.avalFinalidade,
@@ -841,7 +841,7 @@ export default function PesquisaTab({ sessionId, onUsarModeloEmAvaliacao = null
841
  <SectionBlock
842
  step="1"
843
  title="Filtros de Pesquisa"
844
- subtitle="Informe os dados do avaliando. Todos os filtros sao cumulativos."
845
  aside={(
846
  <button
847
  type="button"
@@ -859,21 +859,32 @@ export default function PesquisaTab({ sessionId, onUsarModeloEmAvaliacao = null
859
 
860
  <div className="pesquisa-fields-grid pesquisa-top-four-grid">
861
  <label className="pesquisa-field">
862
- Contem variavel APP (% APP)
 
 
 
 
 
 
 
 
 
 
 
863
  <select
864
- data-field="contemApp"
865
- name={toInputName('contemApp')}
866
- value={filters.contemApp}
867
  onChange={onFieldChange}
868
  autoComplete="off"
869
  >
870
  <option value="">Indiferente</option>
871
- <option value="sim">Sim</option>
872
- <option value="nao">Nao</option>
873
  </select>
874
  </label>
875
  <label className="pesquisa-field">
876
- Finalidade Generica
877
  <select
878
  data-field="tipoModelo"
879
  name={toInputName('tipoModelo')}
@@ -888,7 +899,7 @@ export default function PesquisaTab({ sessionId, onUsarModeloEmAvaliacao = null
888
  </select>
889
  </label>
890
  <label className="pesquisa-field">
891
- Finalidade Cadastral
892
  <ChipAutocompleteInput
893
  field="avalFinalidade"
894
  value={filters.avalFinalidade}
@@ -898,74 +909,58 @@ export default function PesquisaTab({ sessionId, onUsarModeloEmAvaliacao = null
898
  panelTitle="Finalidades sugeridas"
899
  />
900
  </label>
901
-
902
- <label className="pesquisa-field">
903
- Tipo do Modelo
904
- <select
905
- data-field="negociacaoModelo"
906
- name={toInputName('negociacaoModelo')}
907
- value={filters.negociacaoModelo}
908
- onChange={onFieldChange}
909
- autoComplete="off"
910
- >
911
- <option value="">Indiferente</option>
912
- <option value="aluguel">Aluguel</option>
913
- <option value="venda">Venda</option>
914
- </select>
915
- </label>
916
  </div>
917
 
918
- <div className="pesquisa-avaliando-bottom-grid">
919
- <div className="pesquisa-field-pair pesquisa-field-pair-inline pesquisa-avaliando-periodo-pair">
920
- <span className="pesquisa-field-pair-title">Período de referência do imóvel (deve estar contido no período de dados de mercado do modelo)</span>
921
  <label className="pesquisa-field">
922
- Data inicial
923
- <DateFieldInput field="dataMin" value={filters.dataMin} onChange={onFieldChange} />
924
  </label>
925
  <label className="pesquisa-field">
926
- Data final
927
- <DateFieldInput field="dataMax" value={filters.dataMax} onChange={onFieldChange} />
928
  </label>
929
  </div>
930
 
931
- <div className="pesquisa-avaliando-stack pesquisa-avaliando-bottom-stack">
932
- <div className="pesquisa-area-rh-grid">
933
- <label className="pesquisa-field">
934
- Area do imovel
935
- <NumberFieldInput field="avalArea" value={filters.avalArea} onChange={onFieldChange} placeholder="0" />
936
- </label>
937
- <label className="pesquisa-field">
938
- RH do imovel
939
- <NumberFieldInput field="avalRh" value={filters.avalRh} onChange={onFieldChange} placeholder="0" />
940
- </label>
941
- </div>
942
- <div className="pesquisa-bairro-zona-grid">
943
- <label className="pesquisa-field">
944
- Zona de avaliacao
945
- <ChipAutocompleteInput
946
- field="avalZona"
947
- value={filters.avalZona}
948
- onChange={onFieldChange}
949
- placeholder="Selecione uma ou mais zonas"
950
- suggestions={sugestoes.zonas_avaliacao || []}
951
- panelTitle="Zonas sugeridas"
952
- />
953
- </label>
954
- <label className="pesquisa-field pesquisa-bairro-bottom-field">
955
- Bairro do imovel
956
- <ChipAutocompleteInput
957
- field="avalBairro"
958
- value={filters.avalBairro}
959
- onChange={onFieldChange}
960
- placeholder="Digite e pressione Enter"
961
- suggestions={sugestoes.bairros || []}
962
- panelTitle="Bairros sugeridos"
963
- />
964
- </label>
965
- </div>
966
  </div>
967
  </div>
968
 
 
 
 
 
 
 
 
 
 
 
 
 
969
  <div className="row pesquisa-actions pesquisa-actions-primary">
970
  <button type="button" onClick={() => void buscarModelos()} disabled={loading}>
971
  {loading ? 'Pesquisando...' : 'Pesquisar'}
@@ -1017,7 +1012,7 @@ export default function PesquisaTab({ sessionId, onUsarModeloEmAvaliacao = null
1017
  className={`btn-pesquisa-map-toggle${selecionado ? ' is-selected' : ''}`}
1018
  onClick={() => onToggleSelecionado(modelo.id)}
1019
  >
1020
- {selecionado ? 'Desmarcar para mapa' : 'Marcar para mapa'}
1021
  </button>
1022
  <button type="button" className="btn-pesquisa-open" onClick={() => void onAbrirModelo(modelo)}>
1023
  Abrir modelo
 
9
  import SectionBlock from './SectionBlock'
10
 
11
  const EMPTY_FILTERS = {
12
+ nomeModelo: '',
13
  tipoModelo: '',
14
  negociacaoModelo: '',
15
  dataMin: '',
 
152
  function buildApiFilters(filters) {
153
  return {
154
  otica: 'avaliando',
155
+ nome: filters.nomeModelo,
156
  tipo_modelo: filters.tipoModelo,
157
  negociacao_modelo: filters.negociacaoModelo,
158
  aval_finalidade: filters.avalFinalidade,
 
841
  <SectionBlock
842
  step="1"
843
  title="Filtros de Pesquisa"
844
+ subtitle="Informe os dados do avaliando. Todos os filtros são cumulativos."
845
  aside={(
846
  <button
847
  type="button"
 
859
 
860
  <div className="pesquisa-fields-grid pesquisa-top-four-grid">
861
  <label className="pesquisa-field">
862
+ Nome do modelo
863
+ <ChipAutocompleteInput
864
+ field="nomeModelo"
865
+ value={filters.nomeModelo}
866
+ onChange={onFieldChange}
867
+ placeholder="Digite e pressione Enter"
868
+ suggestions={sugestoes.nomes_modelo || []}
869
+ panelTitle="Modelos sugeridos"
870
+ />
871
+ </label>
872
+ <label className="pesquisa-field">
873
+ Tipo do modelo
874
  <select
875
+ data-field="negociacaoModelo"
876
+ name={toInputName('negociacaoModelo')}
877
+ value={filters.negociacaoModelo}
878
  onChange={onFieldChange}
879
  autoComplete="off"
880
  >
881
  <option value="">Indiferente</option>
882
+ <option value="aluguel">Aluguel</option>
883
+ <option value="venda">Venda</option>
884
  </select>
885
  </label>
886
  <label className="pesquisa-field">
887
+ Finalidade genérica
888
  <select
889
  data-field="tipoModelo"
890
  name={toInputName('tipoModelo')}
 
899
  </select>
900
  </label>
901
  <label className="pesquisa-field">
902
+ Finalidades cadastrais que devem estar contidas no modelo
903
  <ChipAutocompleteInput
904
  field="avalFinalidade"
905
  value={filters.avalFinalidade}
 
909
  panelTitle="Finalidades sugeridas"
910
  />
911
  </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
912
  </div>
913
 
914
+ <div className="pesquisa-avaliando-grid-v2">
915
+ <div className="pesquisa-area-rh-grid">
 
916
  <label className="pesquisa-field">
917
+ Área do imóvel
918
+ <NumberFieldInput field="avalArea" value={filters.avalArea} onChange={onFieldChange} placeholder="0" />
919
  </label>
920
  <label className="pesquisa-field">
921
+ RH do imóvel
922
+ <NumberFieldInput field="avalRh" value={filters.avalRh} onChange={onFieldChange} placeholder="0" />
923
  </label>
924
  </div>
925
 
926
+ <div className="pesquisa-bairro-zona-grid">
927
+ <label className="pesquisa-field">
928
+ Zonas de avaliação
929
+ <ChipAutocompleteInput
930
+ field="avalZona"
931
+ value={filters.avalZona}
932
+ onChange={onFieldChange}
933
+ placeholder="Selecione uma ou mais zonas"
934
+ suggestions={sugestoes.zonas_avaliacao || []}
935
+ panelTitle="Zonas sugeridas"
936
+ />
937
+ </label>
938
+ <label className="pesquisa-field pesquisa-bairro-bottom-field">
939
+ Bairros
940
+ <ChipAutocompleteInput
941
+ field="avalBairro"
942
+ value={filters.avalBairro}
943
+ onChange={onFieldChange}
944
+ placeholder="Digite e pressione Enter"
945
+ suggestions={sugestoes.bairros || []}
946
+ panelTitle="Bairros sugeridos"
947
+ />
948
+ </label>
 
 
 
 
 
 
 
 
 
 
 
 
949
  </div>
950
  </div>
951
 
952
+ <div className="pesquisa-field-pair pesquisa-avaliando-periodo-pair">
953
+ <span className="pesquisa-field-pair-title">Período mínimo desejado</span>
954
+ <label className="pesquisa-field">
955
+ Data inicial
956
+ <DateFieldInput field="dataMin" value={filters.dataMin} onChange={onFieldChange} />
957
+ </label>
958
+ <label className="pesquisa-field">
959
+ Data final
960
+ <DateFieldInput field="dataMax" value={filters.dataMax} onChange={onFieldChange} />
961
+ </label>
962
+ </div>
963
+
964
  <div className="row pesquisa-actions pesquisa-actions-primary">
965
  <button type="button" onClick={() => void buscarModelos()} disabled={loading}>
966
  {loading ? 'Pesquisando...' : 'Pesquisar'}
 
1012
  className={`btn-pesquisa-map-toggle${selecionado ? ' is-selected' : ''}`}
1013
  onClick={() => onToggleSelecionado(modelo.id)}
1014
  >
1015
+ {selecionado ? 'Desmarcar' : 'Marcar para mapa'}
1016
  </button>
1017
  <button type="button" className="btn-pesquisa-open" onClick={() => void onAbrirModelo(modelo)}>
1018
  Abrir modelo
frontend/src/styles.css CHANGED
@@ -1379,7 +1379,7 @@ button.pesquisa-otica-btn.active:hover {
1379
 
1380
  .pesquisa-field {
1381
  display: grid;
1382
- gap: 7px;
1383
  font-size: 0.84rem;
1384
  align-content: start;
1385
  }
@@ -1507,12 +1507,12 @@ button.pesquisa-otica-btn.active:hover {
1507
  }
1508
 
1509
  .workflow-section[data-section-step="1"] .chip-autocomplete.is-open .chip-autocomplete-panel {
1510
- position: static;
1511
- top: auto;
1512
- left: auto;
1513
- right: auto;
1514
- margin-top: 6px;
1515
- z-index: auto;
1516
  }
1517
 
1518
  .chip-autocomplete-panel-head {
@@ -1567,8 +1567,8 @@ button.pesquisa-otica-btn.active:hover {
1567
  .pesquisa-fields-grid {
1568
  display: grid;
1569
  grid-template-columns: repeat(2, minmax(0, 1fr));
1570
- gap: 12px 14px;
1571
- margin-bottom: 14px;
1572
  align-items: start;
1573
  }
1574
 
@@ -1585,7 +1585,7 @@ button.pesquisa-otica-btn.active:hover {
1585
  grid-column: 1 / -1;
1586
  display: grid;
1587
  grid-template-columns: repeat(2, minmax(0, 1fr));
1588
- gap: 10px 12px;
1589
  padding: 11px 12px;
1590
  border: 1px solid #d2deea;
1591
  border-radius: 12px;
@@ -1626,8 +1626,16 @@ button.pesquisa-otica-btn.active:hover {
1626
  }
1627
 
1628
  .pesquisa-top-four-grid {
1629
- grid-template-columns: repeat(4, minmax(0, 1fr));
1630
- align-items: end;
 
 
 
 
 
 
 
 
1631
  }
1632
 
1633
  .pesquisa-avaliando-bottom-grid {
@@ -1648,7 +1656,7 @@ button.pesquisa-otica-btn.active:hover {
1648
  .pesquisa-area-rh-grid {
1649
  display: grid;
1650
  grid-template-columns: repeat(2, minmax(0, 1fr));
1651
- gap: 12px 14px;
1652
  align-items: start;
1653
  }
1654
 
@@ -1665,7 +1673,7 @@ button.pesquisa-otica-btn.active:hover {
1665
  .pesquisa-bairro-zona-grid {
1666
  display: grid;
1667
  grid-template-columns: repeat(2, minmax(0, 1fr));
1668
- gap: 12px 14px;
1669
  align-items: start;
1670
  }
1671
 
@@ -1812,8 +1820,9 @@ button.pesquisa-coluna-remove:hover {
1812
  }
1813
 
1814
  .pesquisa-actions-primary {
1815
- margin-top: 22px;
1816
  margin-bottom: 14px;
 
1817
  }
1818
 
1819
  .pesquisa-status {
@@ -1961,17 +1970,19 @@ button.pesquisa-coluna-remove:hover {
1961
 
1962
  .pesquisa-card-actions {
1963
  display: grid;
1964
- grid-template-columns: repeat(3, minmax(0, 1fr));
1965
  gap: 8px;
1966
  min-width: 0;
1967
  }
1968
 
1969
  .pesquisa-card-actions button {
1970
  width: 100%;
1971
- min-height: 32px;
1972
- padding: 6px 10px;
1973
- font-size: 0.78rem;
1974
- letter-spacing: 0.02em;
 
 
1975
  }
1976
 
1977
  .btn-pesquisa-map-toggle {
@@ -4854,6 +4865,7 @@ button.btn-download-subtle {
4854
 
4855
  .pesquisa-filtros-groups,
4856
  .pesquisa-filtros-grid,
 
4857
  .pesquisa-fields-grid,
4858
  .pesquisa-card-grid,
4859
  .pesquisa-compare-grid,
 
1379
 
1380
  .pesquisa-field {
1381
  display: grid;
1382
+ gap: 9px;
1383
  font-size: 0.84rem;
1384
  align-content: start;
1385
  }
 
1507
  }
1508
 
1509
  .workflow-section[data-section-step="1"] .chip-autocomplete.is-open .chip-autocomplete-panel {
1510
+ position: absolute;
1511
+ top: calc(100% + 6px);
1512
+ left: 0;
1513
+ right: 0;
1514
+ margin-top: 0;
1515
+ z-index: 45;
1516
  }
1517
 
1518
  .chip-autocomplete-panel-head {
 
1567
  .pesquisa-fields-grid {
1568
  display: grid;
1569
  grid-template-columns: repeat(2, minmax(0, 1fr));
1570
+ gap: 16px 14px;
1571
+ margin-bottom: 12px;
1572
  align-items: start;
1573
  }
1574
 
 
1585
  grid-column: 1 / -1;
1586
  display: grid;
1587
  grid-template-columns: repeat(2, minmax(0, 1fr));
1588
+ gap: 14px 12px;
1589
  padding: 11px 12px;
1590
  border: 1px solid #d2deea;
1591
  border-radius: 12px;
 
1626
  }
1627
 
1628
  .pesquisa-top-four-grid {
1629
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1630
+ align-items: start;
1631
+ }
1632
+
1633
+ .pesquisa-avaliando-grid-v2 {
1634
+ display: grid;
1635
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1636
+ gap: 16px 14px;
1637
+ align-items: start;
1638
+ margin-bottom: 12px;
1639
  }
1640
 
1641
  .pesquisa-avaliando-bottom-grid {
 
1656
  .pesquisa-area-rh-grid {
1657
  display: grid;
1658
  grid-template-columns: repeat(2, minmax(0, 1fr));
1659
+ gap: 16px 14px;
1660
  align-items: start;
1661
  }
1662
 
 
1673
  .pesquisa-bairro-zona-grid {
1674
  display: grid;
1675
  grid-template-columns: repeat(2, minmax(0, 1fr));
1676
+ gap: 16px 14px;
1677
  align-items: start;
1678
  }
1679
 
 
1820
  }
1821
 
1822
  .pesquisa-actions-primary {
1823
+ margin-top: 14px;
1824
  margin-bottom: 14px;
1825
+ justify-content: flex-end;
1826
  }
1827
 
1828
  .pesquisa-status {
 
1970
 
1971
  .pesquisa-card-actions {
1972
  display: grid;
1973
+ grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr) minmax(0, 1.1fr);
1974
  gap: 8px;
1975
  min-width: 0;
1976
  }
1977
 
1978
  .pesquisa-card-actions button {
1979
  width: 100%;
1980
+ min-height: 30px;
1981
+ padding: 5px 6px;
1982
+ font-size: 0.72rem;
1983
+ line-height: 1.05;
1984
+ letter-spacing: 0.01em;
1985
+ white-space: nowrap;
1986
  }
1987
 
1988
  .btn-pesquisa-map-toggle {
 
4865
 
4866
  .pesquisa-filtros-groups,
4867
  .pesquisa-filtros-grid,
4868
+ .pesquisa-avaliando-grid-v2,
4869
  .pesquisa-fields-grid,
4870
  .pesquisa-card-grid,
4871
  .pesquisa-compare-grid,