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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -99
app.py CHANGED
@@ -1,136 +1,125 @@
1
  import gradio as gr
2
  import pandas as pd
3
 
4
- # In-memory data
5
  df = pd.DataFrame(columns=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"])
6
- users_df = pd.DataFrame([{"USERNAME": "admin", "PASSWORD": "admin"}])
7
 
 
8
  def to_upper(df):
9
  return df.applymap(lambda x: str(x).upper() if pd.notnull(x) else x)
10
 
11
- def get_active_data_with_select():
12
- active = df[df["REMARK"] != "DELETE"].copy()
13
- active["SELECT"] = False
14
- return active.reset_index()
15
-
16
- def show_users():
17
- return users_df.copy()
18
 
19
  def login(username, password):
20
  username = username.strip()
21
  password = password.strip()
22
- matched = users_df[(users_df["USERNAME"] == username) & (users_df["PASSWORD"] == password)]
23
- if not matched.empty:
24
- return "", gr.update(visible=False), gr.update(visible=True), True, get_active_data_with_select(), show_users()
25
  else:
26
- return "Invalid credentials", gr.update(visible=True), gr.update(visible=False), False, pd.DataFrame(), pd.DataFrame()
 
 
 
27
 
28
- def bulk_create_or_update(bulk_df):
 
29
  global df
30
- bulk_df = pd.DataFrame(bulk_df).dropna(how='all')
31
- if bulk_df.empty:
32
- return get_active_data_with_select()
33
-
34
- bulk_df = to_upper(bulk_df)
35
- required_cols = ["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"]
36
- bulk_df = bulk_df[required_cols].dropna()
37
- pk_cols = required_cols
38
- bulk_df = bulk_df.drop_duplicates(subset=pk_cols)
39
-
40
- temp_df = pd.concat([df, bulk_df], ignore_index=True)
41
- df = temp_df.drop_duplicates(subset=pk_cols, keep=False)
42
- df = pd.concat([df, bulk_df], ignore_index=True)
43
- return get_active_data_with_select()
44
-
45
- def delete_selected_rows(table_with_select):
 
 
 
 
 
46
  global df
47
- df_view = pd.DataFrame(table_with_select)
48
- if "SELECT" not in df_view.columns:
49
- return "No SELECT column found.", get_active_data_with_select()
50
-
51
- selected_indexes = df_view[df_view["SELECT"] == True].index.tolist()
52
- if not selected_indexes:
53
- return "No rows selected.", get_active_data_with_select()
54
-
55
- for idx in selected_indexes:
56
- row = df_view.loc[idx]
57
- mask = (
58
- (df["USERNAME"] == row["USERNAME"]) &
59
- (df["COUNTRYCODE"] == row["COUNTRYCODE"]) &
60
- (df["SBUCODE"] == row["SBUCODE"]) &
61
- (df["BRANDCODE"] == row["BRANDCODE"]) &
62
- (df["CONCEPTCODE"] == row["CONCEPTCODE"]) &
63
- (df["CHANNEL"] == row["CHANNEL"]) &
64
- (df["REMARK"] != "DELETE")
65
- )
66
- df.loc[mask, "REMARK"] = "DELETE"
67
-
68
- return "Marked selected as DELETE.", get_active_data_with_select()
69
-
70
- def add_user(new_username, new_password):
71
  global users_df
72
- new_username = new_username.strip().upper()
73
- new_password = new_password.strip()
74
- if not new_username or not new_password:
75
  return "Username/password tidak boleh kosong.", show_users()
76
- if new_username in users_df["USERNAME"].values:
77
  return "Username sudah ada.", show_users()
78
- users_df = pd.concat([users_df, pd.DataFrame([{"USERNAME": new_username, "PASSWORD": new_password}])], ignore_index=True)
79
- return f"User {new_username} ditambahkan.", show_users()
80
 
81
- def delete_user(del_username):
82
  global users_df
83
- del_username = del_username.strip().upper()
84
- if del_username == "ADMIN":
85
  return "User ADMIN tidak bisa dihapus.", show_users()
86
- users_df = users_df[users_df["USERNAME"] != del_username].reset_index(drop=True)
87
- return f"User {del_username} dihapus.", show_users()
88
 
 
89
  with gr.Blocks() as app:
90
- logged_in = gr.State(False)
91
-
92
- with gr.Column(visible=True) as login_section:
93
  gr.Markdown("## Login")
94
  login_user = gr.Textbox(label="Username")
95
  login_pass = gr.Textbox(label="Password", type="password")
96
  login_btn = gr.Button("Login")
97
- login_error = gr.Textbox(visible=False, interactive=False, show_label=False)
98
-
99
- with gr.Column(visible=False) as main_section:
100
- gr.Markdown("## Input & View Data")
101
 
102
- with gr.Row():
103
- bulk_df = gr.Dataframe(
 
 
104
  headers=["USERNAME", "COUNTRYCODE", "SBUCODE", "BRANDCODE", "CONCEPTCODE", "CHANNEL", "REMARK"],
105
  row_count=5,
106
  col_count=(7, "fixed"),
107
- label="Input Data"
108
  )
109
- bulk_btn = gr.Button("Submit Data")
110
-
111
- result_table = gr.Dataframe(label="Data with Select", interactive=True)
112
- delete_btn = gr.Button("Delete Selected Rows")
113
- delete_status = gr.Textbox(visible=True, interactive=False, show_label=False)
114
-
115
- gr.Markdown("---")
116
-
117
- gr.Markdown("## User Management (Login Access Only)")
118
- with gr.Row():
119
- new_username = gr.Textbox(label="New Username")
120
- new_password = gr.Textbox(label="New Password")
121
- add_user_btn = gr.Button("Add User")
122
- with gr.Row():
123
- del_user = gr.Textbox(label="Username to Delete")
124
- del_user_btn = gr.Button("Delete User")
 
 
 
125
 
126
- user_status = gr.Textbox(visible=True, interactive=False, show_label=False)
127
- user_table = gr.Dataframe(label="User List", interactive=False)
128
 
129
- login_btn.click(fn=login, inputs=[login_user, login_pass],
130
- outputs=[login_error, login_section, main_section, logged_in, result_table, user_table])
131
- bulk_btn.click(fn=bulk_create_or_update, inputs=bulk_df, outputs=result_table)
132
- delete_btn.click(fn=delete_selected_rows, inputs=result_table, outputs=[delete_status, result_table])
133
- add_user_btn.click(fn=add_user, inputs=[new_username, new_password], outputs=[user_status, user_table])
134
- del_user_btn.click(fn=delete_user, inputs=del_user, outputs=[user_status, user_table])
135
 
136
  app.launch()
 
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()