diff --git a/docs-android/app/app.iml b/docs-android/app/app.iml index 0c8f28f8..7c02049b 100644 --- a/docs-android/app/app.iml +++ b/docs-android/app/app.iml @@ -77,6 +77,7 @@ + diff --git a/docs-android/app/src/main/AndroidManifest.xml b/docs-android/app/src/main/AndroidManifest.xml index ff234698..701027c1 100644 --- a/docs-android/app/src/main/AndroidManifest.xml +++ b/docs-android/app/src/main/AndroidManifest.xml @@ -47,6 +47,10 @@ android:name=".activity.DocumentEditActivity" android:label="@string/new_document"> + + diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/AuditLogActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/AuditLogActivity.java new file mode 100644 index 00000000..71651d4c --- /dev/null +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/AuditLogActivity.java @@ -0,0 +1,105 @@ +package com.sismics.docs.activity; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; +import android.support.v7.app.AppCompatActivity; +import android.view.MenuItem; +import android.view.View; +import android.widget.ListView; +import android.widget.ProgressBar; + +import com.sismics.docs.R; +import com.sismics.docs.adapter.AuditLogListAdapter; +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.model.application.ApplicationContext; +import com.sismics.docs.resource.AuditLogResource; + +import org.json.JSONObject; + +/** + * Audit log activity. + * + * @author bgamard. + */ +public class AuditLogActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Check if logged in + if (!ApplicationContext.getInstance().isLoggedIn()) { + startActivity(new Intent(this, LoginActivity.class)); + finish(); + return; + } + + // Handle activity context + if (getIntent() == null) { + finish(); + return; + } + + // Input document ID (optional) + final String documentId = getIntent().getStringExtra("documentId"); + + // Setup the activity + setContentView(R.layout.auditlog_activity); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); + } + + // Configure the swipe refresh layout + SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout); + swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_bright, + android.R.color.holo_green_light, + android.R.color.holo_orange_light, + android.R.color.holo_red_light); + swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + refreshView(documentId); + } + }); + + // Get audit log list + refreshView(documentId); + } + + /** + * Refresh the view. + */ + private void refreshView(String documentId) { + final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout); + final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar); + final ListView auditLogListView = (ListView) findViewById(R.id.auditLogListView); + progressBar.setVisibility(View.VISIBLE); + auditLogListView.setVisibility(View.GONE); + AuditLogResource.list(this, documentId, new HttpCallback() { + @Override + public void onSuccess(JSONObject response) { + auditLogListView.setAdapter(new AuditLogListAdapter(response.optJSONArray("logs"))); + } + + @Override + public void onFinish() { + progressBar.setVisibility(View.GONE); + auditLogListView.setVisibility(View.VISIBLE); + swipeRefreshLayout.setRefreshing(false); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + } + + return super.onOptionsItemSelected(item); + } +} diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java index c5e8d12a..4107feb5 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/DocumentViewActivity.java @@ -154,7 +154,7 @@ public class DocumentViewActivity extends AppCompatActivity { * * @param document Document in JSON format */ - private void refreshDocument(JSONObject document) { + private void refreshDocument(final JSONObject document) { this.document = document; String title = document.optString("title"); @@ -249,7 +249,7 @@ public class DocumentViewActivity extends AppCompatActivity { @Override public void onClick(View view) { DialogFragment dialog = DocExportPdfFragment.newInstance( - DocumentViewActivity.this.document.optString("id"), DocumentViewActivity.this.document.optString("title")); + document.optString("id"), document.optString("title")); dialog.show(getSupportFragmentManager(), "DocExportPdfFragment"); } }); @@ -259,11 +259,22 @@ public class DocumentViewActivity extends AppCompatActivity { button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - DialogFragment dialog = DocShareFragment.newInstance(DocumentViewActivity.this.document.optString("id")); + DialogFragment dialog = DocShareFragment.newInstance(document.optString("id")); dialog.show(getSupportFragmentManager(), "DocShareFragment"); } }); + // Action audit log + button = (Button) findViewById(R.id.actionAuditLog); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(DocumentViewActivity.this, AuditLogActivity.class); + intent.putExtra("documentId", document.optString("id")); + startActivity(intent); + } + }); + // Button add a comment ImageButton imageButton = (ImageButton) findViewById(R.id.addCommentBtn); imageButton.setOnClickListener(new View.OnClickListener() { diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java index 6732e7f3..04c0add0 100644 --- a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java +++ b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java @@ -72,7 +72,7 @@ public class MainActivity extends AppCompatActivity { // between the sliding drawer and the action bar app icon drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.drawer_open, R.string.drawer_close); - drawerLayout.setDrawerListener(drawerToggle); + drawerLayout.addDrawerListener(drawerToggle); // Fill the drawer user info JSONObject userInfo = ApplicationContext.getInstance().getUserInfo(); @@ -137,6 +137,15 @@ public class MainActivity extends AppCompatActivity { } }); + // Click on Latest activity + View auditLogLayout = findViewById(R.id.auditLogLayout); + auditLogLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(MainActivity.this, AuditLogActivity.class)); + } + }); + handleIntent(getIntent()); EventBus.getDefault().register(this); diff --git a/docs-android/app/src/main/java/com/sismics/docs/adapter/AuditLogListAdapter.java b/docs-android/app/src/main/java/com/sismics/docs/adapter/AuditLogListAdapter.java new file mode 100644 index 00000000..b529bccd --- /dev/null +++ b/docs-android/app/src/main/java/com/sismics/docs/adapter/AuditLogListAdapter.java @@ -0,0 +1,92 @@ +package com.sismics.docs.adapter; + +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import com.sismics.docs.R; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +/** + * Audit log list adapter. + * + * @author bgamard. + */ +public class AuditLogListAdapter extends BaseAdapter { + /** + * Shares. + */ + private List logList; + + /** + * Audit log list adapter. + * + * @param logs Logs + */ + public AuditLogListAdapter(JSONArray logs) { + this.logList = new ArrayList<>(); + + for (int i = 0; i < logs.length(); i++) { + logList.add(logs.optJSONObject(i)); + } + } + + @Override + public int getCount() { + return logList.size(); + } + + @Override + public JSONObject getItem(int position) { + return logList.get(position); + } + + @Override + public long getItemId(int position) { + return getItem(position).hashCode(); + } + + @Override + public View getView(int position, View view, final ViewGroup parent) { + if (view == null) { + LayoutInflater vi = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = vi.inflate(R.layout.auditlog_list_item, parent, false); + } + + // Build message + final JSONObject log = getItem(position); + StringBuilder message = new StringBuilder(log.optString("class")); + switch (log.optString("type")) { + case "CREATE": message.append(" created"); break; + case "UPDATE": message.append(" updated"); break; + case "DELETE": message.append(" deleted"); break; + } + switch (log.optString("class")) { + case "Document": + case "Acl": + case "Tag": + case "User": + message.append(" : "); + message.append(log.optString("message")); + break; + } + + // Fill the view + TextView usernameTextView = (TextView) view.findViewById(R.id.usernameTextView); + TextView messageTextView = (TextView) view.findViewById(R.id.messageTextView); + usernameTextView.setText(log.optString("username")); + messageTextView.setText(message); + + return view; + } +} diff --git a/docs-android/app/src/main/java/com/sismics/docs/resource/AuditLogResource.java b/docs-android/app/src/main/java/com/sismics/docs/resource/AuditLogResource.java new file mode 100644 index 00000000..bd909200 --- /dev/null +++ b/docs-android/app/src/main/java/com/sismics/docs/resource/AuditLogResource.java @@ -0,0 +1,38 @@ +package com.sismics.docs.resource; + +import android.content.Context; + +import com.sismics.docs.listener.HttpCallback; +import com.sismics.docs.util.OkHttpUtil; + +import okhttp3.HttpUrl; +import okhttp3.Request; + +/** + * Access to /auditlog API. + * + * @author bgamard + */ +public class AuditLogResource extends BaseResource { + /** + * GET /auditlog. + * + * @param context Context + * @param documentId Document ID + * @param callback Callback + */ + public static void list(Context context, String documentId, HttpCallback callback) { + HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(getApiUrl(context) + "/auditlog") + .newBuilder(); + if (documentId != null) { + httpUrlBuilder.addQueryParameter("document", documentId); + } + Request request = new Request.Builder() + .url(httpUrlBuilder.build()) + .get() + .build(); + OkHttpUtil.buildClient(context) + .newCall(request) + .enqueue(HttpCallback.buildOkHttpCallback(callback)); + } +} diff --git a/docs-android/app/src/main/res/drawable-xhdpi/ic_assignment_grey600_24dp.png b/docs-android/app/src/main/res/drawable-xhdpi/ic_assignment_grey600_24dp.png new file mode 100644 index 00000000..1d59bcf2 Binary files /dev/null and b/docs-android/app/src/main/res/drawable-xhdpi/ic_assignment_grey600_24dp.png differ diff --git a/docs-android/app/src/main/res/drawable-xhdpi/ic_assignment_grey600_48dp.png b/docs-android/app/src/main/res/drawable-xhdpi/ic_assignment_grey600_48dp.png new file mode 100644 index 00000000..9a050c74 Binary files /dev/null and b/docs-android/app/src/main/res/drawable-xhdpi/ic_assignment_grey600_48dp.png differ diff --git a/docs-android/app/src/main/res/drawable-xhdpi/ic_comment_black_24dp.png b/docs-android/app/src/main/res/drawable-xhdpi/ic_comment_black_24dp.png deleted file mode 100644 index 412de9b0..00000000 Binary files a/docs-android/app/src/main/res/drawable-xhdpi/ic_comment_black_24dp.png and /dev/null differ diff --git a/docs-android/app/src/main/res/drawable-xhdpi/ic_comment_grey600_24dp.png b/docs-android/app/src/main/res/drawable-xhdpi/ic_comment_grey600_24dp.png new file mode 100644 index 00000000..a8ba0fdc Binary files /dev/null and b/docs-android/app/src/main/res/drawable-xhdpi/ic_comment_grey600_24dp.png differ diff --git a/docs-android/app/src/main/res/drawable-xxhdpi/ic_assignment_grey600_24dp.png b/docs-android/app/src/main/res/drawable-xxhdpi/ic_assignment_grey600_24dp.png new file mode 100644 index 00000000..96caad84 Binary files /dev/null and b/docs-android/app/src/main/res/drawable-xxhdpi/ic_assignment_grey600_24dp.png differ diff --git a/docs-android/app/src/main/res/drawable-xxhdpi/ic_assignment_grey600_48dp.png b/docs-android/app/src/main/res/drawable-xxhdpi/ic_assignment_grey600_48dp.png new file mode 100644 index 00000000..0bd4b924 Binary files /dev/null and b/docs-android/app/src/main/res/drawable-xxhdpi/ic_assignment_grey600_48dp.png differ diff --git a/docs-android/app/src/main/res/drawable-xxhdpi/ic_comment_black_24dp.png b/docs-android/app/src/main/res/drawable-xxhdpi/ic_comment_black_24dp.png deleted file mode 100644 index 382ee7a1..00000000 Binary files a/docs-android/app/src/main/res/drawable-xxhdpi/ic_comment_black_24dp.png and /dev/null differ diff --git a/docs-android/app/src/main/res/drawable-xxhdpi/ic_comment_grey600_24dp.png b/docs-android/app/src/main/res/drawable-xxhdpi/ic_comment_grey600_24dp.png new file mode 100644 index 00000000..5af80651 Binary files /dev/null and b/docs-android/app/src/main/res/drawable-xxhdpi/ic_comment_grey600_24dp.png differ diff --git a/docs-android/app/src/main/res/layout/auditlog_activity.xml b/docs-android/app/src/main/res/layout/auditlog_activity.xml new file mode 100644 index 00000000..524d2eb1 --- /dev/null +++ b/docs-android/app/src/main/res/layout/auditlog_activity.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/docs-android/app/src/main/res/layout/auditlog_list_item.xml b/docs-android/app/src/main/res/layout/auditlog_list_item.xml new file mode 100644 index 00000000..c24cff2a --- /dev/null +++ b/docs-android/app/src/main/res/layout/auditlog_list_item.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/docs-android/app/src/main/res/layout/doc_list_item.xml b/docs-android/app/src/main/res/layout/doc_list_item.xml index 43b56de0..0aae61da 100644 --- a/docs-android/app/src/main/res/layout/doc_list_item.xml +++ b/docs-android/app/src/main/res/layout/doc_list_item.xml @@ -13,6 +13,7 @@ android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_marginRight="12dp" + android:layout_marginEnd="12dp" android:id="@+id/folderImageView" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -22,7 +23,9 @@ android:id="@+id/titleTextView" android:layout_alignParentTop="true" android:layout_toRightOf="@+id/folderImageView" + android:layout_toEndOf="@+id/folderImageView" android:layout_toLeftOf="@+id/dateTextView" + android:layout_toStartOf="@+id/dateTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="sans-serif-light" diff --git a/docs-android/app/src/main/res/layout/document_view_activity.xml b/docs-android/app/src/main/res/layout/document_view_activity.xml index e13fd81b..0716a8df 100644 --- a/docs-android/app/src/main/res/layout/document_view_activity.xml +++ b/docs-android/app/src/main/res/layout/document_view_activity.xml @@ -52,14 +52,14 @@ @@ -173,7 +173,7 @@ android:drawableTop="@drawable/ic_create_grey600_24dp" style="?android:buttonBarButtonStyle" android:text="@string/edit_document" - android:textColor="@color/button_material_dark" + android:textColor="#ff5a595b" android:textAllCaps="false" android:layout_margin="8dp"/> @@ -184,7 +184,7 @@ android:drawableTop="@drawable/ic_file_upload_grey600_24dp" style="?android:buttonBarButtonStyle" android:text="@string/upload_file" - android:textColor="@color/button_material_dark" + android:textColor="#ff5a595b" android:textAllCaps="false" android:layout_margin="8dp"/> @@ -195,7 +195,7 @@ android:drawableTop="@drawable/ic_file_download_grey600_24dp" style="?android:buttonBarButtonStyle" android:text="@string/download_document" - android:textColor="@color/button_material_dark" + android:textColor="#ff5a595b" android:textAllCaps="false" android:layout_margin="8dp"/> @@ -214,9 +214,9 @@ android:drawableTop="@drawable/ic_description_grey600_24dp" style="?android:buttonBarButtonStyle" android:text="@string/export_pdf" - android:textColor="@color/button_material_dark" + android:textColor="#ff5a595b" android:textAllCaps="false" - android:layout_margin="8dp"/> + android:layout_margin="0dp"/>