Før Oppgaver Steg 2, kobling mot WP
This commit is contained in:
parent
c81310f982
commit
34ee55d362
21 changed files with 976 additions and 211 deletions
187
app/src/main/java/com/kbs/kbsintranett/AddTaskBottomSheet.java
Normal file
187
app/src/main/java/com/kbs/kbsintranett/AddTaskBottomSheet.java
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class AddTaskBottomSheet extends BottomSheetDialogFragment {
|
||||
|
||||
private EditText etTitle, etDesc;
|
||||
private Button btnDate, btnUsers, btnSave;
|
||||
private TextView txtDatePreview, txtUsersPreview;
|
||||
|
||||
private Calendar dueDate = Calendar.getInstance();
|
||||
private List<User> allUsersFromApi = new ArrayList<>();
|
||||
private List<User> filteredUsers = new ArrayList<>();
|
||||
private List<User> selectedUsers = new ArrayList<>();
|
||||
|
||||
public interface OnTaskAddedListener {
|
||||
void onTaskAdded(TaskItem task);
|
||||
}
|
||||
|
||||
private OnTaskAddedListener listener;
|
||||
|
||||
public void setOnTaskAddedListener(OnTaskAddedListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.bottom_sheet_add_task, container, false);
|
||||
|
||||
etTitle = v.findViewById(R.id.et_task_title);
|
||||
etDesc = v.findViewById(R.id.et_task_desc);
|
||||
btnDate = v.findViewById(R.id.btn_task_date);
|
||||
btnUsers = v.findViewById(R.id.btn_task_users);
|
||||
btnSave = v.findViewById(R.id.btn_save_task);
|
||||
txtDatePreview = v.findViewById(R.id.txt_date_preview);
|
||||
txtUsersPreview = v.findViewById(R.id.txt_users_preview);
|
||||
|
||||
dueDate.add(Calendar.DAY_OF_MONTH, 1);
|
||||
updateDatePreview();
|
||||
|
||||
btnDate.setOnClickListener(view -> {
|
||||
new DatePickerDialog(getContext(), (d, y, m, day) -> {
|
||||
dueDate.set(y, m, day);
|
||||
updateDatePreview();
|
||||
}, dueDate.get(Calendar.YEAR), dueDate.get(Calendar.MONTH), dueDate.get(Calendar.DAY_OF_MONTH)).show();
|
||||
});
|
||||
|
||||
btnUsers.setOnClickListener(view -> showUserSelectionDialog());
|
||||
btnSave.setOnClickListener(view -> saveTask());
|
||||
|
||||
fetchUsers();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private void fetchUsers() {
|
||||
RetrofitClient.getApiService().getUsersList().enqueue(new Callback<List<User>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
allUsersFromApi = response.body();
|
||||
filterUsersByHierarchy();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<List<User>> call, Throwable t) {}
|
||||
});
|
||||
}
|
||||
|
||||
private void filterUsersByHierarchy() {
|
||||
filteredUsers.clear();
|
||||
UserManager me = UserManager.getInstance();
|
||||
|
||||
// 1. Hvis Admin/Editor, legg til alle
|
||||
if (me.isEditorOrAbove()) {
|
||||
filteredUsers.addAll(allUsersFromApi);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Finn mine roller/avdelinger
|
||||
List<String> myRoles = new ArrayList<>();
|
||||
for (User u : allUsersFromApi) {
|
||||
if (u.getEmail().equalsIgnoreCase(me.getUserEmail())) {
|
||||
for (String r : u.getRoles()) myRoles.add(r.toLowerCase());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Filtrer logikk (Identisk med CreateEventFragment)
|
||||
for (User u : allUsersFromApi) {
|
||||
// Alltid legg til seg selv
|
||||
if (u.getEmail().equalsIgnoreCase(me.getUserEmail())) {
|
||||
if (!filteredUsers.contains(u)) filteredUsers.add(u);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean hasAccess = false;
|
||||
for (String role : u.getRoles()) {
|
||||
String r = role.toLowerCase();
|
||||
// Sjekk om vi deler en avdelingsrolle
|
||||
if ((r.equals("serviceavdelingen") && myRoles.contains("serviceavdelingen")) ||
|
||||
(r.equals("automasjonsavdelingen") && myRoles.contains("automasjonsavdelingen")) ||
|
||||
(r.equals("prosjektavdelingen") && myRoles.contains("prosjektavdelingen")) ||
|
||||
(r.equals("administrasjonen") && myRoles.contains("administrasjonen")) ||
|
||||
(r.equals("kbs_alle") && myRoles.contains("kbs_alle"))) {
|
||||
hasAccess = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAccess && !filteredUsers.contains(u)) {
|
||||
filteredUsers.add(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showUserSelectionDialog() {
|
||||
if (filteredUsers.isEmpty()) {
|
||||
Toast.makeText(getContext(), "Henter tilgjengelige personer...", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] names = new String[filteredUsers.size()];
|
||||
boolean[] checked = new boolean[filteredUsers.size()];
|
||||
for (int i = 0; i < filteredUsers.size(); i++) {
|
||||
names[i] = filteredUsers.get(i).getName();
|
||||
checked[i] = selectedUsers.contains(filteredUsers.get(i));
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Tildel til...")
|
||||
.setMultiChoiceItems(names, checked, (dialog, which, isChecked) -> {
|
||||
if (isChecked) selectedUsers.add(filteredUsers.get(which));
|
||||
else selectedUsers.remove(filteredUsers.get(which));
|
||||
})
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
if (selectedUsers.isEmpty()) txtUsersPreview.setText("Kun meg");
|
||||
else if (selectedUsers.size() == 1) txtUsersPreview.setText(selectedUsers.get(0).getName());
|
||||
else txtUsersPreview.setText(selectedUsers.size() + " personer valgt");
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void updateDatePreview() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy", Locale.getDefault());
|
||||
txtDatePreview.setText("Frist: " + sdf.format(dueDate.getTime()));
|
||||
}
|
||||
|
||||
private void saveTask() {
|
||||
String title = etTitle.getText().toString().trim();
|
||||
if (title.isEmpty()) {
|
||||
etTitle.setError("Mangler tittel");
|
||||
return;
|
||||
}
|
||||
|
||||
TaskItem task = new TaskItem(title, etDesc.getText().toString(), dueDate.getTimeInMillis());
|
||||
if (selectedUsers.isEmpty()) {
|
||||
task.addAssignee(UserManager.getInstance().getUserEmail());
|
||||
} else {
|
||||
for (User u : selectedUsers) task.addAssignee(u.getEmail());
|
||||
}
|
||||
|
||||
if (listener != null) listener.onTaskAdded(task);
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
|
@ -92,4 +92,15 @@ public class CacheManager {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
private static final String FILE_TASKS = "cache_tasks.json";
|
||||
|
||||
public static void saveTasks(Context context, List<TaskItem> tasks) {
|
||||
saveList(context, FILE_TASKS, tasks);
|
||||
}
|
||||
|
||||
public static List<TaskItem> getTasks(Context context) {
|
||||
Type type = new TypeToken<List<TaskItem>>() {}.getType();
|
||||
List<TaskItem> list = loadList(context, FILE_TASKS, type);
|
||||
return list != null ? list : new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
|
@ -11,73 +11,92 @@ import androidx.annotation.NonNull;
|
|||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.util.List;
|
||||
|
||||
public class CalendarAdapter extends RecyclerView.Adapter<CalendarAdapter.ViewHolder> {
|
||||
public class CalendarAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private List<CalendarEvent> events;
|
||||
public static final int TYPE_EVENT = 0;
|
||||
public static final int TYPE_YEAR_HEADER = 1;
|
||||
|
||||
private List<Object> items;
|
||||
private final OnItemClickListener listener;
|
||||
|
||||
// Farge for individuelle/private hendelser (Deep Purple)
|
||||
private static final String PRIVATE_EVENT_COLOR = "#673AB7";
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(CalendarEvent event);
|
||||
}
|
||||
|
||||
public CalendarAdapter(List<CalendarEvent> events, OnItemClickListener listener) {
|
||||
this.events = events;
|
||||
public CalendarAdapter(List<Object> items, OnItemClickListener listener) {
|
||||
this.items = items;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return (items.get(position) instanceof String) ? TYPE_YEAR_HEADER : TYPE_EVENT;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_calendar, parent, false);
|
||||
return new ViewHolder(view);
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
if (viewType == TYPE_YEAR_HEADER) {
|
||||
return new YearViewHolder(inflater.inflate(R.layout.item_calendar_year_header, parent, false));
|
||||
} else {
|
||||
return new EventViewHolder(inflater.inflate(R.layout.item_calendar, parent, false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
CalendarEvent event = events.get(position);
|
||||
holder.day.setText(event.getDay());
|
||||
holder.month.setText(event.getMonth());
|
||||
holder.time.setText(event.getTime());
|
||||
holder.title.setText(event.getTitle());
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
||||
Object item = items.get(position);
|
||||
|
||||
// NYTT: Sjekk om hendelsen er "privat" (har deltakere)
|
||||
boolean isPrivate = event.getDescription() != null && event.getDescription().contains("#deltakere:");
|
||||
|
||||
try {
|
||||
int color;
|
||||
if (isPrivate) {
|
||||
// Bruk privat farge
|
||||
color = Color.parseColor(PRIVATE_EVENT_COLOR);
|
||||
} else {
|
||||
// Bruk kalenderens standardfarge
|
||||
color = Color.parseColor(event.getCalendarColor());
|
||||
}
|
||||
holder.dateBox.setBackgroundTintList(ColorStateList.valueOf(color));
|
||||
} catch (Exception e) {
|
||||
// Fallback til standard blå hvis fargekoden er ugyldig
|
||||
holder.dateBox.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#0069B3")));
|
||||
if (holder instanceof YearViewHolder) {
|
||||
((YearViewHolder) holder).yearText.setText((String) item);
|
||||
}
|
||||
else if (holder instanceof EventViewHolder) {
|
||||
CalendarEvent event = (CalendarEvent) item;
|
||||
EventViewHolder vh = (EventViewHolder) holder;
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onItemClick(event);
|
||||
vh.day.setText(event.getDay());
|
||||
vh.month.setText(event.getMonth());
|
||||
vh.time.setText(event.getTime());
|
||||
vh.title.setText(event.getTitle());
|
||||
|
||||
// --- ÅRSTALL LOGIKK: BAKGRUNNSFARGE ---
|
||||
// Vi henter årstall fra datoen (yyyy-MM-dd)
|
||||
String year = "2025";
|
||||
if (event.getRawDate() != null && event.getRawDate().length() >= 4) {
|
||||
year = event.getRawDate().substring(0, 4);
|
||||
}
|
||||
});
|
||||
|
||||
// Alternerende bakgrunn basert på år (partall vs oddetall)
|
||||
int yearInt = Integer.parseInt(year);
|
||||
if (yearInt % 2 == 0) {
|
||||
vh.itemView.setBackgroundColor(Color.parseColor("#F5F7FA")); // KBS Very Light Blue
|
||||
} else {
|
||||
vh.itemView.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
|
||||
// Privat-markering og farge på datoboks
|
||||
boolean isPrivate = event.getDescription() != null && event.getDescription().contains("#deltakere:");
|
||||
try {
|
||||
int color = Color.parseColor(isPrivate ? "#673AB7" : event.getCalendarColor());
|
||||
vh.dateBox.setBackgroundTintList(ColorStateList.valueOf(color));
|
||||
} catch (Exception e) {
|
||||
vh.dateBox.setBackgroundTintList(ColorStateList.valueOf(Color.parseColor("#0069B3")));
|
||||
}
|
||||
|
||||
vh.itemView.setOnClickListener(v -> listener.onItemClick(event));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return events.size();
|
||||
return items.size();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
static class EventViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView day, month, title, time;
|
||||
LinearLayout dateBox;
|
||||
|
||||
public ViewHolder(View view) {
|
||||
EventViewHolder(View view) {
|
||||
super(view);
|
||||
day = view.findViewById(R.id.cal_day);
|
||||
month = view.findViewById(R.id.cal_month);
|
||||
|
|
@ -86,4 +105,12 @@ public class CalendarAdapter extends RecyclerView.Adapter<CalendarAdapter.ViewHo
|
|||
dateBox = view.findViewById(R.id.date_box_background);
|
||||
}
|
||||
}
|
||||
|
||||
static class YearViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView yearText;
|
||||
YearViewHolder(View view) {
|
||||
super(view);
|
||||
yearText = view.findViewById(R.id.txt_calendar_year);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import android.os.Looper;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Button;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
|
|
@ -15,11 +15,8 @@ import androidx.fragment.app.Fragment;
|
|||
import androidx.navigation.Navigation;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
|
@ -29,6 +26,7 @@ public class CalendarFullFragment extends Fragment {
|
|||
private RecyclerView recyclerView;
|
||||
private ProgressBar progressBar;
|
||||
private TextView emptyView;
|
||||
private Button btnAddEvent;
|
||||
private LinearLayoutManager layoutManager;
|
||||
|
||||
@Nullable
|
||||
|
|
@ -43,11 +41,17 @@ public class CalendarFullFragment extends Fragment {
|
|||
recyclerView = view.findViewById(R.id.recycler_full_calendar);
|
||||
progressBar = view.findViewById(R.id.loading_full_calendar);
|
||||
emptyView = view.findViewById(R.id.empty_view_calendar);
|
||||
ImageView backBtn = view.findViewById(R.id.btn_back_calendar);
|
||||
btnAddEvent = view.findViewById(R.id.btn_add_calendar_event);
|
||||
|
||||
layoutManager = new LinearLayoutManager(getContext());
|
||||
recyclerView.setLayoutManager(layoutManager);
|
||||
backBtn.setOnClickListener(v -> Navigation.findNavController(view).navigateUp());
|
||||
|
||||
// VIKTIG: Ingen referanse til btn_back_calendar her lenger.
|
||||
|
||||
if (!UserManager.getInstance().getWriteableCalendars().isEmpty() || UserManager.getInstance().isEditorOrAbove()) {
|
||||
btnAddEvent.setVisibility(View.VISIBLE);
|
||||
btnAddEvent.setOnClickListener(v -> Navigation.findNavController(view).navigate(R.id.navigation_create_event));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -58,9 +62,7 @@ public class CalendarFullFragment extends Fragment {
|
|||
|
||||
private void fetchAllEvents() {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
new Thread(() -> {
|
||||
// HER ER ENDRINGEN: isPreview = false (Hent alt)
|
||||
List<CalendarEvent> deviceEvents = CalendarManager.getDeviceEvents(getContext(), false);
|
||||
new Handler(Looper.getMainLooper()).post(() -> fetchApiEvents(deviceEvents));
|
||||
}).start();
|
||||
|
|
@ -76,65 +78,53 @@ public class CalendarFullFragment extends Fragment {
|
|||
List<CalendarEvent> apiEvents = new ArrayList<>();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
apiEvents = response.body();
|
||||
for (CalendarEvent e : apiEvents) {
|
||||
CalendarManager.formatEventForUI(e);
|
||||
}
|
||||
for (CalendarEvent e : apiEvents) CalendarManager.formatEventForUI(e);
|
||||
}
|
||||
|
||||
List<CalendarEvent> allEvents = CalendarManager.mergeAndSort(apiEvents, deviceEvents);
|
||||
|
||||
if (allEvents.isEmpty()) {
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
} else {
|
||||
emptyView.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
|
||||
CalendarAdapter adapter = new CalendarAdapter(allEvents, event -> {
|
||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||
sheet.setOnEventChangeListener(CalendarFullFragment.this::fetchAllEvents);
|
||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
||||
scrollToToday(allEvents);
|
||||
}
|
||||
displaySortedList(allEvents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<List<CalendarEvent>> call, Throwable t) {
|
||||
if (!isAdded()) return;
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if (!deviceEvents.isEmpty()) {
|
||||
CalendarAdapter adapter = new CalendarAdapter(deviceEvents, event -> {
|
||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
scrollToToday(deviceEvents);
|
||||
} else {
|
||||
emptyView.setText("Ingen hendelser funnet.");
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
displaySortedList(deviceEvents);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void scrollToToday(List<CalendarEvent> events) {
|
||||
String today = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
|
||||
int scrollIndex = 0;
|
||||
private void displaySortedList(List<CalendarEvent> events) {
|
||||
if (events.isEmpty()) {
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
String raw = events.get(i).getRawDate();
|
||||
if (raw != null && raw.compareTo(today) >= 0) {
|
||||
scrollIndex = i;
|
||||
break;
|
||||
emptyView.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
|
||||
List<Object> itemsWithHeaders = new ArrayList<>();
|
||||
String currentYear = "";
|
||||
|
||||
for (CalendarEvent e : events) {
|
||||
String year = "Ukjent år";
|
||||
if (e.getRawDate() != null && e.getRawDate().length() >= 4) {
|
||||
year = e.getRawDate().substring(0, 4);
|
||||
}
|
||||
|
||||
if (!year.equals(currentYear)) {
|
||||
itemsWithHeaders.add(year);
|
||||
currentYear = year;
|
||||
}
|
||||
itemsWithHeaders.add(e);
|
||||
}
|
||||
|
||||
if (scrollIndex > 0) {
|
||||
layoutManager.scrollToPositionWithOffset(scrollIndex, 0);
|
||||
}
|
||||
CalendarAdapter adapter = new CalendarAdapter(itemsWithHeaders, event -> {
|
||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||
sheet.setOnEventChangeListener(CalendarFullFragment.this::fetchAllEvents);
|
||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||
});
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
|
|
@ -25,7 +24,6 @@ import java.util.ArrayList;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
|
@ -173,12 +171,7 @@ public class HomeFragment extends Fragment implements HomeAdapter.OnHomeClickLis
|
|||
private void buildAndDisplayList() {
|
||||
List<Object> items = new ArrayList<>();
|
||||
|
||||
// 1. Create Event Knapp (hvis tilgang)
|
||||
if (!UserManager.getInstance().getWriteableCalendars().isEmpty()) {
|
||||
items.add(new HomeAdapter.CreateButtonItem());
|
||||
}
|
||||
|
||||
// 2. Kalender Seksjon (Redusert til 3 hendelser som avtalt)
|
||||
// 1. Kalender Seksjon (Knappen "Ny hendelse" er fjernet herfra)
|
||||
items.add(new HomeAdapter.SectionTitleItem("Kommende hendelser", true));
|
||||
String today = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
|
||||
int count = 0;
|
||||
|
|
@ -190,7 +183,7 @@ public class HomeFragment extends Fragment implements HomeAdapter.OnHomeClickLis
|
|||
if (count >= 3) break;
|
||||
}
|
||||
|
||||
// 3. Nyheter Seksjon
|
||||
// 2. Nyheter Seksjon
|
||||
items.add(new HomeAdapter.SectionTitleItem("Siste nytt", false));
|
||||
items.addAll(currentNews);
|
||||
|
||||
|
|
@ -198,33 +191,24 @@ public class HomeFragment extends Fragment implements HomeAdapter.OnHomeClickLis
|
|||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
// --- KLIKKHÅNDTERING ---
|
||||
|
||||
@Override public void onProfileClick() {
|
||||
Navigation.findNavController(getView()).navigate(R.id.navigation_profile);
|
||||
}
|
||||
|
||||
@Override public void onProfileClick() {}
|
||||
@Override public void onCreateEventClick() {
|
||||
Navigation.findNavController(getView()).navigate(R.id.action_home_to_create_event);
|
||||
Navigation.findNavController(getView()).navigate(R.id.navigation_create_event);
|
||||
}
|
||||
|
||||
@Override public void onViewAllCalendarClick() {
|
||||
Navigation.findNavController(getView()).navigate(R.id.action_home_to_calendarFull);
|
||||
Navigation.findNavController(getView()).navigate(R.id.navigation_calendar_full);
|
||||
}
|
||||
|
||||
@Override public void onViewAllNewsClick() {
|
||||
Navigation.findNavController(getView()).navigate(R.id.action_home_to_newsFull);
|
||||
Navigation.findNavController(getView()).navigate(R.id.navigation_news_full);
|
||||
}
|
||||
|
||||
@Override public void onCalendarItemClick(CalendarEvent event) {
|
||||
CalendarDetailsBottomSheet sheet = new CalendarDetailsBottomSheet(event);
|
||||
sheet.setOnEventChangeListener(this::refreshData);
|
||||
sheet.show(getParentFragmentManager(), "CalendarDetails");
|
||||
}
|
||||
|
||||
@Override public void onNewsItemClick(WpPost post) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable("post_data", post);
|
||||
Navigation.findNavController(getView()).navigate(R.id.action_home_to_newsDetail, bundle);
|
||||
Navigation.findNavController(getView()).navigate(R.id.navigation_news_detail, bundle);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,9 @@ import androidx.navigation.NavController;
|
|||
import androidx.navigation.fragment.NavHostFragment;
|
||||
import androidx.navigation.ui.AppBarConfiguration;
|
||||
import androidx.navigation.ui.NavigationUI;
|
||||
import androidx.work.ExistingPeriodicWorkPolicy;
|
||||
import androidx.work.PeriodicWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||
|
|
@ -33,15 +36,17 @@ import com.google.android.gms.auth.api.signin.GoogleSignInClient;
|
|||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
// Din oppdaterte linje:
|
||||
public static final String GOOGLE_WEB_CLIENT_ID = BuildConfig.WEB_CLIENT_ID;
|
||||
private static final String TAG = "MainActivity";
|
||||
|
||||
private static final String TAG = "MainActivity";
|
||||
private NavController navController;
|
||||
private DrawerLayout drawerLayout;
|
||||
private AppBarConfiguration appBarConfiguration;
|
||||
|
||||
private ActivityResultLauncher<String> requestPermissionLauncher;
|
||||
|
||||
@Override
|
||||
|
|
@ -77,13 +82,17 @@ public class MainActivity extends AppCompatActivity {
|
|||
} else {
|
||||
toolbar.setVisibility(View.VISIBLE);
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
|
||||
// Oppdater navn hver gang vi bytter skjerm for å være sikker
|
||||
updateNavHeader(navigationView);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateNavHeader(navigationView);
|
||||
setupTaskReminders();
|
||||
createNotificationChannel();
|
||||
|
||||
requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {});
|
||||
|
||||
checkNotificationPermission();
|
||||
checkExactAlarmPermission();
|
||||
checkLoginState();
|
||||
|
|
@ -94,13 +103,18 @@ public class MainActivity extends AppCompatActivity {
|
|||
TextView name = headerView.findViewById(R.id.nav_header_name);
|
||||
TextView email = headerView.findViewById(R.id.nav_header_email);
|
||||
|
||||
new android.os.Handler().postDelayed(() -> {
|
||||
UserManager user = UserManager.getInstance();
|
||||
if (user.isLoggedIn()) {
|
||||
name.setText(user.getUserDisplayName());
|
||||
email.setText(user.getUserEmail());
|
||||
}
|
||||
}, 2000);
|
||||
UserManager user = UserManager.getInstance();
|
||||
if (user.isLoggedIn()) {
|
||||
name.setText(user.getUserDisplayName());
|
||||
email.setText(user.getUserEmail());
|
||||
}
|
||||
}
|
||||
|
||||
private void setupTaskReminders() {
|
||||
PeriodicWorkRequest taskCheck = new PeriodicWorkRequest.Builder(
|
||||
TaskReminderWorker.class, 2, TimeUnit.DAYS).build();
|
||||
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
|
||||
"TaskReminder", ExistingPeriodicWorkPolicy.KEEP, taskCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -128,8 +142,8 @@ public class MainActivity extends AppCompatActivity {
|
|||
.requestIdToken(GOOGLE_WEB_CLIENT_ID).requestEmail().build();
|
||||
GoogleSignInClient client = GoogleSignIn.getClient(this, gso);
|
||||
client.silentSignIn().addOnSuccessListener(account -> {
|
||||
AuthRepository.loginToWordPress(account.getIdToken(), account.getDisplayName(), account.getEmail(),
|
||||
(account.getPhotoUrl() != null ? account.getPhotoUrl().toString() : null),
|
||||
String photoUrl = (account.getPhotoUrl() != null) ? account.getPhotoUrl().toString() : null;
|
||||
AuthRepository.loginToWordPress(account.getIdToken(), account.getDisplayName(), account.getEmail(), photoUrl,
|
||||
new AuthRepository.AuthCallback() {
|
||||
@Override public void onSuccess(String role) {
|
||||
if (navController.getCurrentDestination().getId() == R.id.navigation_login) {
|
||||
|
|
@ -142,22 +156,16 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
private void navigateToLogin() {
|
||||
if (navController.getCurrentDestination().getId() != R.id.navigation_login) {
|
||||
if (navController != null && navController.getCurrentDestination() != null &&
|
||||
navController.getCurrentDestination().getId() != R.id.navigation_login) {
|
||||
navController.navigate(R.id.navigation_login);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
CharSequence name = "KBS Kalendervarsler";
|
||||
String description = "Varsler for kalenderhendelser";
|
||||
int importance = NotificationManager.IMPORTANCE_HIGH;
|
||||
NotificationChannel channel = new NotificationChannel("kbs_calendar_channel", name, importance);
|
||||
channel.setDescription(description);
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
if (notificationManager != null) {
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
NotificationChannel channel = new NotificationChannel("kbs_calendar_channel", "Varsler", NotificationManager.IMPORTANCE_HIGH);
|
||||
getSystemService(NotificationManager.class).createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
public class NotificationHelper {
|
||||
|
||||
private static final String CHANNEL_ID = "kbs_calendar_channel";
|
||||
|
||||
/**
|
||||
* En enkel metode for å vise et standard KBS-varsel.
|
||||
*/
|
||||
public static void showNotification(Context context, String title, String message) {
|
||||
// Sjekk tillatelse for Android 13+
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Intent for å åpne appen når man trykker på varselet
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
context,
|
||||
(int) System.currentTimeMillis(),
|
||||
intent,
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_stat_kbs) // Bruker samme ikon som kalender
|
||||
.setColor(ContextCompat.getColor(context, R.color.kbs_logo_blue))
|
||||
.setContentTitle(title)
|
||||
.setContentText(message)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setAutoCancel(true);
|
||||
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
notificationManager.notify((int) System.currentTimeMillis(), builder.build());
|
||||
}
|
||||
}
|
||||
84
app/src/main/java/com/kbs/kbsintranett/TaskAdapter.java
Normal file
84
app/src/main/java/com/kbs/kbsintranett/TaskAdapter.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.ViewHolder> {
|
||||
|
||||
private List<TaskItem> tasks;
|
||||
private OnTaskClickListener listener;
|
||||
private String currentUserEmail;
|
||||
|
||||
public interface OnTaskClickListener {
|
||||
void onTaskClick(TaskItem task);
|
||||
void onStatusChanged(TaskItem task, boolean isDone);
|
||||
}
|
||||
|
||||
public TaskAdapter(List<TaskItem> tasks, OnTaskClickListener listener) {
|
||||
this.tasks = tasks;
|
||||
this.listener = listener;
|
||||
this.currentUserEmail = UserManager.getInstance().getUserEmail();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_task, parent, false);
|
||||
return new ViewHolder(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
TaskItem task = tasks.get(position);
|
||||
holder.title.setText(task.getTitle());
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd. MMM", Locale.getDefault());
|
||||
holder.date.setText("Frist: " + sdf.format(new Date(task.getDueDate())));
|
||||
|
||||
boolean myStatus = task.getParticipantStatus(currentUserEmail);
|
||||
holder.checkBox.setChecked(myStatus);
|
||||
|
||||
if (myStatus || task.isFullyCompleted()) {
|
||||
holder.title.setPaintFlags(holder.title.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
||||
holder.title.setTextColor(Color.GRAY);
|
||||
} else {
|
||||
holder.title.setPaintFlags(holder.title.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
|
||||
holder.title.setTextColor(Color.BLACK);
|
||||
}
|
||||
|
||||
// Vis fremdrift (f.eks 1/3 fullført)
|
||||
int total = task.getAssigneeStatus().size();
|
||||
int done = 0;
|
||||
for (Boolean b : task.getAssigneeStatus().values()) if (b) done++;
|
||||
holder.progress.setText("Fremdrift: " + done + "/" + total);
|
||||
|
||||
holder.checkBox.setOnClickListener(v -> listener.onStatusChanged(task, holder.checkBox.isChecked()));
|
||||
holder.itemView.setOnClickListener(v -> listener.onTaskClick(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() { return tasks.size(); }
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView title, date, progress;
|
||||
CheckBox checkBox;
|
||||
ViewHolder(View v) {
|
||||
super(v);
|
||||
title = v.findViewById(R.id.task_title);
|
||||
date = v.findViewById(R.id.task_date);
|
||||
progress = v.findViewById(R.id.task_progress);
|
||||
checkBox = v.findViewById(R.id.task_checkbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class TaskDetailsBottomSheet extends BottomSheetDialogFragment {
|
||||
|
||||
private TaskItem task;
|
||||
private OnTaskChangeListener listener;
|
||||
|
||||
public interface OnTaskChangeListener {
|
||||
void onTaskChanged();
|
||||
void onTaskDeleted(TaskItem task);
|
||||
}
|
||||
|
||||
public TaskDetailsBottomSheet(TaskItem task, OnTaskChangeListener listener) {
|
||||
this.task = task;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.bottom_sheet_task_details, container, false);
|
||||
|
||||
TextView title = v.findViewById(R.id.detail_task_title);
|
||||
TextView date = v.findViewById(R.id.detail_task_date);
|
||||
TextView desc = v.findViewById(R.id.detail_task_desc);
|
||||
LinearLayout participantsContainer = v.findViewById(R.id.container_participants_status);
|
||||
SwitchMaterial switchNotify = v.findViewById(R.id.switch_notifications);
|
||||
Button btnDelete = v.findViewById(R.id.btn_delete_task);
|
||||
|
||||
title.setText(task.getTitle());
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("EEEE dd. MMMM yyyy", Locale.getDefault());
|
||||
date.setText("Frist: " + sdf.format(new Date(task.getDueDate())));
|
||||
|
||||
if (task.getDescription() != null && !task.getDescription().isEmpty()) {
|
||||
desc.setText(task.getDescription());
|
||||
desc.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
// List opp alle deltakere og deres status
|
||||
for (Map.Entry<String, Boolean> entry : task.getAssigneeStatus().entrySet()) {
|
||||
TextView t = new TextView(getContext());
|
||||
String status = entry.getValue() ? "✅ Fullført" : "⏳ Pågår";
|
||||
t.setText("• " + entry.getKey() + ": " + status);
|
||||
t.setPadding(0, 4, 0, 4);
|
||||
participantsContainer.addView(t);
|
||||
}
|
||||
|
||||
switchNotify.setChecked(task.isNotificationsEnabled());
|
||||
switchNotify.setOnCheckedChangeListener((btn, isChecked) -> {
|
||||
task.setNotificationsEnabled(isChecked);
|
||||
if (listener != null) listener.onTaskChanged();
|
||||
});
|
||||
|
||||
// Kun eier kan slette oppgaven
|
||||
if (task.getCreatedByEmail().equals(UserManager.getInstance().getUserEmail())) {
|
||||
btnDelete.setVisibility(View.VISIBLE);
|
||||
btnDelete.setOnClickListener(view -> {
|
||||
if (listener != null) listener.onTaskDeleted(task);
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TaskItem implements Serializable {
|
||||
|
|
@ -8,26 +10,41 @@ public class TaskItem implements Serializable {
|
|||
private String title;
|
||||
private String description;
|
||||
private long dueDate;
|
||||
private boolean isCompleted;
|
||||
private String assignedToEmail;
|
||||
private String createdByEmail;
|
||||
private String createdByName;
|
||||
|
||||
public TaskItem(String title, String description, long dueDate, String assignedToEmail) {
|
||||
// Key: Bruker-epost, Value: Har fullført (true/false)
|
||||
private Map<String, Boolean> assigneeStatus = new HashMap<>();
|
||||
|
||||
private boolean notificationsEnabled = true;
|
||||
private boolean isFullyCompleted = false; // Satt av eier eller når alle er ferdige
|
||||
|
||||
public TaskItem(String title, String description, long dueDate) {
|
||||
this.id = UUID.randomUUID().toString();
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.dueDate = dueDate;
|
||||
this.assignedToEmail = assignedToEmail;
|
||||
this.createdByEmail = UserManager.getInstance().getUserEmail();
|
||||
this.isCompleted = false;
|
||||
this.createdByName = UserManager.getInstance().getUserDisplayName();
|
||||
}
|
||||
|
||||
// Getters og Setters
|
||||
// Hjelpemetoder
|
||||
public void addAssignee(String email) { assigneeStatus.put(email, false); }
|
||||
public void setParticipantStatus(String email, boolean done) { assigneeStatus.put(email, done); }
|
||||
public boolean getParticipantStatus(String email) { return assigneeStatus.getOrDefault(email, false); }
|
||||
|
||||
public boolean isUserParticipant(String email) { return assigneeStatus.containsKey(email); }
|
||||
public Map<String, Boolean> getAssigneeStatus() { return assigneeStatus; }
|
||||
|
||||
// Getters / Setters
|
||||
public String getId() { return id; }
|
||||
public String getTitle() { return title; }
|
||||
public String getDescription() { return description; }
|
||||
public long getDueDate() { return dueDate; }
|
||||
public boolean isCompleted() { return isCompleted; }
|
||||
public void setCompleted(boolean completed) { isCompleted = completed; }
|
||||
public String getAssignedToEmail() { return assignedToEmail; }
|
||||
public String getCreatedByEmail() { return createdByEmail; }
|
||||
public String getCreatedByName() { return createdByName; }
|
||||
public boolean isNotificationsEnabled() { return notificationsEnabled; }
|
||||
public void setNotificationsEnabled(boolean enabled) { this.notificationsEnabled = enabled; }
|
||||
public boolean isFullyCompleted() { return isFullyCompleted; }
|
||||
public void setFullyCompleted(boolean fullyCompleted) { isFullyCompleted = fullyCompleted; }
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.kbs.kbsintranett;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
import java.util.List;
|
||||
|
||||
public class TaskReminderWorker extends Worker {
|
||||
|
||||
public TaskReminderWorker(@NonNull Context context, @NonNull WorkerParameters params) {
|
||||
super(context, params);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
Context context = getApplicationContext();
|
||||
List<TaskItem> tasks = CacheManager.getTasks(context);
|
||||
String myEmail = UserManager.getInstance().getUserEmail();
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
for (TaskItem task : tasks) {
|
||||
if (!task.isNotificationsEnabled() || task.isFullyCompleted() || task.getParticipantStatus(myEmail)) continue;
|
||||
|
||||
long diff = task.getDueDate() - now;
|
||||
|
||||
// Varsle hvis fristen er i dag (innenfor 24 timer)
|
||||
if (diff > 0 && diff < 86400000L) {
|
||||
NotificationHelper.showNotification(context, "Frist i dag!", "Oppgaven '" + task.getTitle() + "' forfaller snart.");
|
||||
}
|
||||
// Varsle hvis over frist (hver gang worker kjører, f.eks annenhver dag)
|
||||
else if (diff < 0) {
|
||||
NotificationHelper.showNotification(context, "Over frist!", "Oppgaven '" + task.getTitle() + "' er forsinket.");
|
||||
}
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,20 +4,23 @@ import android.os.Bundle;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TasksFragment extends Fragment {
|
||||
public class TasksFragment extends Fragment implements TaskAdapter.OnTaskClickListener {
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
private List<TaskItem> taskList = new ArrayList<>();
|
||||
private TaskAdapter adapter;
|
||||
private TabLayout tabLayout;
|
||||
private List<TaskItem> allTasks = new ArrayList<>();
|
||||
private String myEmail;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
@ -29,21 +32,91 @@ public class TasksFragment extends Fragment {
|
|||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
myEmail = UserManager.getInstance().getUserEmail();
|
||||
tabLayout = view.findViewById(R.id.task_tabs);
|
||||
recyclerView = view.findViewById(R.id.recycler_tasks);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
|
||||
FloatingActionButton fab = view.findViewById(R.id.fab_add_task);
|
||||
fab.setOnClickListener(v -> {
|
||||
Toast.makeText(getContext(), "Ny oppgave-funksjon kommer her", Toast.LENGTH_SHORT).show();
|
||||
AddTaskBottomSheet dialog = new AddTaskBottomSheet();
|
||||
dialog.setOnTaskAddedListener(task -> {
|
||||
allTasks.add(0, task);
|
||||
saveAndRefresh();
|
||||
});
|
||||
dialog.show(getChildFragmentManager(), "AddTask");
|
||||
});
|
||||
|
||||
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||
@Override public void onTabSelected(TabLayout.Tab tab) { filterAndDisplay(); }
|
||||
@Override public void onTabUnselected(TabLayout.Tab tab) {}
|
||||
@Override public void onTabReselected(TabLayout.Tab tab) {}
|
||||
});
|
||||
|
||||
loadTasks();
|
||||
}
|
||||
|
||||
private void loadTasks() {
|
||||
// Dummy data
|
||||
taskList.clear();
|
||||
taskList.add(new TaskItem("Husk å sjekke filter", "Serviceoppdrag hos kunde X", System.currentTimeMillis(), "meg@kbs.no"));
|
||||
// Her vil vi senere koble på en TaskAdapter
|
||||
allTasks = CacheManager.getTasks(getContext());
|
||||
filterAndDisplay();
|
||||
}
|
||||
|
||||
private void filterAndDisplay() {
|
||||
List<TaskItem> filtered = new ArrayList<>();
|
||||
int selectedTab = tabLayout.getSelectedTabPosition();
|
||||
|
||||
for (TaskItem t : allTasks) {
|
||||
if (selectedTab == 0) { // MINE (Oppgaver tildelt meg som ikke er fullført av meg ennå)
|
||||
if (t.isUserParticipant(myEmail) && !t.getParticipantStatus(myEmail) && !t.isFullyCompleted()) {
|
||||
filtered.add(t);
|
||||
}
|
||||
} else if (selectedTab == 1) { // TILDELT ANDRE (Oppgaver jeg har laget, uansett om jeg er med selv)
|
||||
if (t.getCreatedByEmail().equals(myEmail) && !t.isFullyCompleted()) {
|
||||
filtered.add(t);
|
||||
}
|
||||
} else { // FULLFØRTE (Alt som er arkivert som ferdig)
|
||||
if (t.isFullyCompleted() || (t.isUserParticipant(myEmail) && t.getParticipantStatus(myEmail))) {
|
||||
filtered.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adapter = new TaskAdapter(filtered, this);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskClick(TaskItem task) {
|
||||
TaskDetailsBottomSheet sheet = new TaskDetailsBottomSheet(task, new TaskDetailsBottomSheet.OnTaskChangeListener() {
|
||||
@Override
|
||||
public void onTaskChanged() {
|
||||
saveAndRefresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskDeleted(TaskItem taskToDelete) {
|
||||
allTasks.remove(taskToDelete);
|
||||
saveAndRefresh();
|
||||
}
|
||||
});
|
||||
sheet.show(getChildFragmentManager(), "TaskDetails");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(TaskItem task, boolean isDone) {
|
||||
task.setParticipantStatus(myEmail, isDone);
|
||||
|
||||
// Logikk: Hvis den som opprettet oppgaven merker den som ferdig,
|
||||
// regnes hele oppgaven som ferdig for alle (arkiveres).
|
||||
if (task.getCreatedByEmail().equals(myEmail) && isDone) {
|
||||
task.setFullyCompleted(true);
|
||||
}
|
||||
|
||||
saveAndRefresh();
|
||||
}
|
||||
|
||||
private void saveAndRefresh() {
|
||||
CacheManager.saveTasks(getContext(), allTasks);
|
||||
filterAndDisplay();
|
||||
}
|
||||
}
|
||||
84
app/src/main/res/layout/bottom_sheet_add_task.xml
Normal file
84
app/src/main/res/layout/bottom_sheet_add_task.xml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:background="@color/white">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ny Oppgave"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_task_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Hva skal gjøres?"
|
||||
android:inputType="textCapSentences"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_task_desc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Beskrivelse (valgfritt)"
|
||||
android:inputType="textMultiLine"
|
||||
android:minLines="2"
|
||||
android:gravity="top"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="12dp">
|
||||
<Button
|
||||
android:id="@+id/btn_task_date"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Sett frist" />
|
||||
<TextView
|
||||
android:id="@+id/txt_date_preview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Frist: -"
|
||||
android:layout_marginStart="8dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="24dp">
|
||||
<Button
|
||||
android:id="@+id/btn_task_users"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Velg deltakere" />
|
||||
<TextView
|
||||
android:id="@+id/txt_users_preview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Kun meg"
|
||||
android:layout_marginStart="8dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_save_task"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Lagre Oppgave"
|
||||
android:backgroundTint="@color/kbs_logo_blue"
|
||||
android:textColor="@color/white"/>
|
||||
|
||||
</LinearLayout>
|
||||
77
app/src/main/res/layout/bottom_sheet_task_details.xml
Normal file
77
app/src/main/res/layout/bottom_sheet_task_details.xml
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:background="@color/white">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_task_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Oppgavetittel"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_task_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Frist: -"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/kbs_muted_blue_gray"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/detail_task_desc"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Beskrivelse kommer her..."
|
||||
android:textSize="16sp"
|
||||
android:textColor="#333"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#EEE"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Status deltakere:"
|
||||
android:textStyle="bold"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container_participants_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/switch_notifications"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Varsle meg om denne oppgaven"
|
||||
android:checked="true"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_delete_task"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Slett oppgave"
|
||||
android:backgroundTint="@color/kbs_logo_accent_red"
|
||||
android:textColor="@color/white"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -4,32 +4,18 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/kbs_very_light_blue">
|
||||
android:background="@color/white">
|
||||
|
||||
<RelativeLayout
|
||||
<!-- Knappen ligger nå helt øverst i fragmentet (under den globale toolbaren) -->
|
||||
<Button
|
||||
android:id="@+id/btn_add_calendar_event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:background="@color/white"
|
||||
android:elevation="4dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_back_calendar"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:src="@android:drawable/ic_menu_revert"
|
||||
android:layout_centerVertical="true"
|
||||
app:tint="@color/kbs_logo_blue"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="KBS Kalender"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black"
|
||||
android:layout_centerInParent="true"/>
|
||||
</RelativeLayout>
|
||||
android:text="+ Ny Kalenderhendelse"
|
||||
android:backgroundTint="@color/kbs_logo_blue"
|
||||
android:textColor="@color/white"
|
||||
android:layout_margin="16dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
@ -39,8 +25,7 @@
|
|||
android:id="@+id/recycler_full_calendar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="8dp"
|
||||
android:clipToPadding="false"/>
|
||||
android:clipToPadding="false" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_full_calendar"
|
||||
|
|
|
|||
|
|
@ -7,16 +7,6 @@
|
|||
android:padding="16dp"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Skjemaer"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:textColor="#333333"/>
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_refresh"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
|
|
@ -13,19 +14,10 @@
|
|||
android:background="@color/white"
|
||||
android:elevation="4dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Håndbok"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#333333"
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="KBS Klima og Byggservice ønsker å ta vare på miljø og helse, og har derfor utarbeidet en håndbok som omhandler disse temaene. For enkelthets skyld er denne publisert i KBS-appen og på Intranettet.\n\nDet forventes at alle ansatte skal ha lest hele håndboken minst én gang, og at de har lest og forstått bedriftens HMS-målsetting senest 1. april hvert år."
|
||||
android:text="KBS Klima og Byggservice ønsker å ta vare på miljø og helse, og har derfor utarbeidet en håndbok som omhandler disse temaene.\n\nDet forventes at alle ansatte skal ha lest hele håndboken minst én gang, og at de har lest og forstått bedriftens HMS-målsetting senest 1. april hvert år."
|
||||
android:textSize="14sp"
|
||||
android:textColor="#666666"
|
||||
android:lineSpacingExtra="4dp"
|
||||
|
|
|
|||
|
|
@ -1,14 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/kbs_very_light_blue">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/task_tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white"
|
||||
app:tabSelectedTextColor="@color/kbs_logo_blue"
|
||||
app:tabIndicatorColor="@color/kbs_logo_blue">
|
||||
<com.google.android.material.tabs.TabItem android:text="Mine" />
|
||||
<com.google.android.material.tabs.TabItem android:text="Tildelt andre" />
|
||||
<com.google.android.material.tabs.TabItem android:text="Fullførte" />
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_tasks"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:padding="8dp"
|
||||
android:clipToPadding="false" />
|
||||
|
||||
|
|
@ -16,11 +30,10 @@
|
|||
android:id="@+id/fab_add_task"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_gravity="end"
|
||||
android:layout_margin="24dp"
|
||||
android:src="@android:drawable/ic_input_add"
|
||||
app:backgroundTint="@color/kbs_logo_blue"
|
||||
app:tint="@color/white"
|
||||
android:contentDescription="Legg til oppgave" />
|
||||
app:tint="@color/white" />
|
||||
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
12
app/src/main/res/layout/item_calendar_year_header.xml
Normal file
12
app/src/main/res/layout/item_calendar_year_header.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/txt_calendar_year"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#4F5B66"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:text="2026"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
59
app/src/main/res/layout/item_task.xml
Normal file
59
app/src/main/res/layout/item_task.xml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:layout_marginVertical="4dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="12dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/task_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/task_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Oppgavetittel"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/task_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Frist: -"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/kbs_muted_blue_gray" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/task_progress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Fremdrift: 0/0"
|
||||
android:textSize="11sp"
|
||||
android:textStyle="italic"
|
||||
android:textColor="@color/kbs_logo_blue"
|
||||
android:layout_marginTop="2dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
@ -41,18 +41,18 @@
|
|||
app:destination="@id/navigation_tasks" />
|
||||
</fragment>
|
||||
|
||||
<!-- OPPGAVER (NYTT) -->
|
||||
<!-- OPPGAVER (Navn endret for Toolbar) -->
|
||||
<fragment
|
||||
android:id="@+id/navigation_tasks"
|
||||
android:name="com.kbs.kbsintranett.TasksFragment"
|
||||
android:label="Oppgaver"
|
||||
android:label="KBS Oppgaver"
|
||||
tools:layout="@layout/fragment_tasks" />
|
||||
|
||||
<!-- KALENDER -->
|
||||
<!-- KALENDER (Navn endret for Toolbar) -->
|
||||
<fragment
|
||||
android:id="@+id/navigation_calendar_full"
|
||||
android:name="com.kbs.kbsintranett.CalendarFullFragment"
|
||||
android:label="Kalender"
|
||||
android:label="KBS Kalender"
|
||||
tools:layout="@layout/fragment_calendar_full" />
|
||||
|
||||
<fragment
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
<fragment
|
||||
android:id="@+id/navigation_news_full"
|
||||
android:name="com.kbs.kbsintranett.NewsFullFragment"
|
||||
android:label="Nyheter"
|
||||
android:label="Siste nytt"
|
||||
tools:layout="@layout/fragment_news_full">
|
||||
<action
|
||||
android:id="@+id/action_newsFull_to_newsDetail"
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
<fragment
|
||||
android:id="@+id/navigation_forms"
|
||||
android:name="com.kbs.kbsintranett.FormsListFragment"
|
||||
android:label="Skjemaer"
|
||||
android:label="KBS Skjemaer"
|
||||
tools:layout="@layout/fragment_forms_list">
|
||||
<action
|
||||
android:id="@+id/action_formsListFragment_to_formsDetailFragment"
|
||||
|
|
@ -104,7 +104,7 @@
|
|||
<fragment
|
||||
android:id="@+id/navigation_handbook"
|
||||
android:name="com.kbs.kbsintranett.HandbookFragment"
|
||||
android:label="Håndbok"
|
||||
android:label="KBS Håndbok"
|
||||
tools:layout="@layout/fragment_handbook">
|
||||
<action
|
||||
android:id="@+id/action_handbook_to_detail"
|
||||
|
|
|
|||
Loading…
Reference in a new issue