Bayhaqy commited on
Commit
1cef742
·
verified ·
1 Parent(s): 66c18e8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -59
app.py CHANGED
@@ -1,125 +1,119 @@
1
  import gradio as gr
2
  import pandas as pd
3
 
4
- # ===== In-memory Datastore =====
5
  df = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
6
- users_df = pd.DataFrame([{"USERNAME": "admin", "PASSWORD": "admin"}]) # Default admin user
7
 
8
- # ===== Utility Functions =====
9
- def to_upper(df):
10
- return df.applymap(lambda x: str(x).upper() if pd.notnull(x) else x)
11
 
12
  def get_active_data():
13
- return df[df["REMARK"] != "DELETE"].reset_index(drop=True)
14
 
15
  def login(username, password):
16
- username = username.strip()
17
  password = password.strip()
18
- if not users_df[(users_df["USERNAME"] == username) & (users_df["PASSWORD"] == password)].empty:
 
19
  return "", gr.update(visible=False), gr.update(visible=True), get_active_data(), show_users()
20
- else:
21
- return "Invalid credentials", gr.update(visible=True), gr.update(visible=False), pd.DataFrame(), pd.DataFrame()
22
 
23
- def show_users():
24
- return users_df.copy()
25
-
26
- # ===== Bulk Create/Update =====
27
  def bulk_submit(dataframe):
28
  global df
29
  new_df = pd.DataFrame(dataframe).dropna(how="all")
30
  if new_df.empty:
31
  return get_active_data()
32
-
33
  new_df = to_upper(new_df)
34
-
35
  required = ["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"]
36
  new_df = new_df[required].dropna()
37
 
38
  pk_cols = required
39
- existing = df[pk_cols]
40
- combined = pd.concat([existing, new_df])
41
- dedup = combined.duplicated(keep=False)
42
-
43
- df_new = new_df[~dedup[len(existing):]].copy()
44
- df = pd.concat([df, df_new], ignore_index=True)
45
 
 
46
  return get_active_data()
47
 
48
- # ===== Delete Selected Entries =====
49
- def delete_selected(selected_indices):
50
  global df
51
  try:
52
- selected_indices = [int(i) for i in selected_indices]
53
  active_df = get_active_data()
54
- for idx in selected_indices:
55
- actual_idx = active_df.index[idx]
56
- df.loc[actual_idx, "REMARK"] = "DELETE"
57
- return "Data ditandai DELETE.", get_active_data()
58
  except Exception as e:
59
- return f"Gagal menghapus: {e}", get_active_data()
60
 
61
- # ===== User Management =====
62
  def add_user(username, password):
63
  global users_df
64
  username = username.strip().upper()
65
  password = password.strip()
66
  if not username or not password:
67
- return "Username/password tidak boleh kosong.", show_users()
68
  if username in users_df["USERNAME"].values:
69
- return "Username sudah ada.", show_users()
70
  users_df = pd.concat([users_df, pd.DataFrame([{"USERNAME": username, "PASSWORD": password}])], ignore_index=True)
71
- return f"User {username} ditambahkan.", show_users()
72
 
73
  def delete_user(username):
74
  global users_df
75
  username = username.strip().upper()
76
  if username == "ADMIN":
77
- return "User ADMIN tidak bisa dihapus.", show_users()
78
  users_df = users_df[users_df["USERNAME"] != username].reset_index(drop=True)
79
- return f"User {username} dihapus.", show_users()
 
 
 
80
 
81
- # ===== UI =====
82
  with gr.Blocks() as app:
83
- with gr.State() as login_state:
84
- gr.Markdown("## Login")
85
- login_user = gr.Textbox(label="Username")
86
- login_pass = gr.Textbox(label="Password", type="password")
87
- login_btn = gr.Button("Login")
88
- login_msg = gr.Textbox(visible=False, interactive=False, show_label=False)
89
-
90
- with gr.Tabs(visible=False) as main_tabs:
 
 
91
  with gr.Tab("Input Data"):
92
  gr.Markdown("### Input dan Monitoring Data")
93
- bulk_input = gr.Dataframe(
94
  headers=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"],
95
  row_count=5,
96
  col_count=(7, "fixed"),
97
- label="Masukkan Data Baru"
98
  )
99
- submit_btn = gr.Button("Submit Data")
100
  gr.Markdown("### Data Aktif")
101
- data_table = gr.Dataframe(label="List Data", interactive=False, row_selectable=True)
102
- delete_btn = gr.Button("Delete Selected")
103
  delete_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
104
 
105
  with gr.Tab("User Management"):
106
  gr.Markdown("### Manajemen User Login")
107
  new_user = gr.Textbox(label="New Username")
108
  new_pass = gr.Textbox(label="New Password")
109
- add_btn = gr.Button("Add User")
110
  del_user = gr.Textbox(label="Delete Username")
111
- del_btn = gr.Button("Delete User")
112
  user_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
113
  user_table = gr.Dataframe(label="User List", interactive=False)
114
 
115
- # === Event Binding ===
116
- login_btn.click(fn=login, inputs=[login_user, login_pass],
117
- outputs=[login_msg, login_state, main_tabs, data_table, user_table])
118
 
119
- submit_btn.click(fn=bulk_submit, inputs=[bulk_input], outputs=[data_table])
120
- delete_btn.click(fn=delete_selected, inputs=[data_table.selected], outputs=[delete_msg, data_table])
121
 
122
- add_btn.click(fn=add_user, inputs=[new_user, new_pass], outputs=[user_msg, user_table])
123
- del_btn.click(fn=delete_user, inputs=[del_user], outputs=[user_msg, user_table])
124
 
125
  app.launch()
 
1
  import gradio as gr
2
  import pandas as pd
3
 
4
+ # ===== Global Storage =====
5
  df = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
6
+ users_df = pd.DataFrame([{"USERNAME": "ADMIN", "PASSWORD": "ADMIN"}])
7
 
8
+ # ===== Helper Functions =====
9
+ def to_upper(df_input):
10
+ return df_input.applymap(lambda x: str(x).upper().strip() if pd.notnull(x) else x)
11
 
12
  def get_active_data():
13
+ return df[df["REMARK"].str.upper() != "DELETE"].reset_index(drop=True)
14
 
15
  def login(username, password):
16
+ username = username.strip().upper()
17
  password = password.strip()
18
+ is_valid = not users_df[(users_df["USERNAME"] == username) & (users_df["PASSWORD"] == password)].empty
19
+ if is_valid:
20
  return "", gr.update(visible=False), gr.update(visible=True), get_active_data(), show_users()
21
+ return "Invalid login", gr.update(visible=True), gr.update(visible=False), pd.DataFrame(), pd.DataFrame()
 
22
 
 
 
 
 
23
  def bulk_submit(dataframe):
24
  global df
25
  new_df = pd.DataFrame(dataframe).dropna(how="all")
26
  if new_df.empty:
27
  return get_active_data()
 
28
  new_df = to_upper(new_df)
 
29
  required = ["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"]
30
  new_df = new_df[required].dropna()
31
 
32
  pk_cols = required
33
+ # Filter out duplicates based on all PK cols
34
+ merged = pd.merge(new_df, df[pk_cols], on=pk_cols, how="left", indicator=True)
35
+ df_filtered = new_df[merged["_merge"] == "left_only"]
 
 
 
36
 
37
+ df = pd.concat([df, df_filtered], ignore_index=True)
38
  return get_active_data()
39
 
40
+ def delete_selected(selected_idxs):
 
41
  global df
42
  try:
 
43
  active_df = get_active_data()
44
+ for i in selected_idxs:
45
+ idx = active_df.index[i]
46
+ df.loc[idx, "REMARK"] = "DELETE"
47
+ return "Berhasil dihapus (soft delete).", get_active_data()
48
  except Exception as e:
49
+ return f"Error: {e}", get_active_data()
50
 
 
51
  def add_user(username, password):
52
  global users_df
53
  username = username.strip().upper()
54
  password = password.strip()
55
  if not username or not password:
56
+ return "Username/password tidak boleh kosong", show_users()
57
  if username in users_df["USERNAME"].values:
58
+ return "Username sudah ada", show_users()
59
  users_df = pd.concat([users_df, pd.DataFrame([{"USERNAME": username, "PASSWORD": password}])], ignore_index=True)
60
+ return f"User {username} ditambahkan", show_users()
61
 
62
  def delete_user(username):
63
  global users_df
64
  username = username.strip().upper()
65
  if username == "ADMIN":
66
+ return "ADMIN tidak boleh dihapus", show_users()
67
  users_df = users_df[users_df["USERNAME"] != username].reset_index(drop=True)
68
+ return f"User {username} dihapus", show_users()
69
+
70
+ def show_users():
71
+ return users_df.copy()
72
 
73
+ # ===== Gradio UI =====
74
  with gr.Blocks() as app:
75
+ gr.Markdown("## Login")
76
+ login_box = gr.Column(visible=True)
77
+ with login_box:
78
+ user = gr.Textbox(label="Username")
79
+ pw = gr.Textbox(label="Password", type="password")
80
+ btn_login = gr.Button("Login")
81
+ login_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
82
+
83
+ tab_section = gr.Tabs(visible=False)
84
+ with tab_section:
85
  with gr.Tab("Input Data"):
86
  gr.Markdown("### Input dan Monitoring Data")
87
+ df_input = gr.Dataframe(
88
  headers=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"],
89
  row_count=5,
90
  col_count=(7, "fixed"),
91
+ label="Input Data Baru"
92
  )
93
+ btn_submit = gr.Button("Submit Data")
94
  gr.Markdown("### Data Aktif")
95
+ df_list = gr.Dataframe(label="List Data Aktif", interactive=False, row_selectable=True)
96
+ btn_delete = gr.Button("Delete Selected")
97
  delete_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
98
 
99
  with gr.Tab("User Management"):
100
  gr.Markdown("### Manajemen User Login")
101
  new_user = gr.Textbox(label="New Username")
102
  new_pass = gr.Textbox(label="New Password")
103
+ btn_add = gr.Button("Add User")
104
  del_user = gr.Textbox(label="Delete Username")
105
+ btn_del = gr.Button("Delete User")
106
  user_msg = gr.Textbox(visible=True, interactive=False, show_label=False)
107
  user_table = gr.Dataframe(label="User List", interactive=False)
108
 
109
+ # ==== Events ====
110
+ btn_login.click(fn=login, inputs=[user, pw],
111
+ outputs=[login_msg, login_box, tab_section, df_list, user_table])
112
 
113
+ btn_submit.click(fn=bulk_submit, inputs=[df_input], outputs=[df_list])
114
+ btn_delete.click(fn=delete_selected, inputs=[df_list.selected], outputs=[delete_msg, df_list])
115
 
116
+ btn_add.click(fn=add_user, inputs=[new_user, new_pass], outputs=[user_msg, user_table])
117
+ btn_del.click(fn=delete_user, inputs=[del_user], outputs=[user_msg, user_table])
118
 
119
  app.launch()