Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Update inbox card design #9109

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4d433de
feat: Update inbox card design
iamsivin Mar 12, 2024
28563ca
chore: Minor fix
iamsivin Mar 13, 2024
51e2939
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 14, 2024
3cc1147
refactor: use simple estimation based logic to calculate number of la…
scmmishra Mar 14, 2024
048e1d9
chore: Use resize observer
iamsivin Mar 14, 2024
f419dcc
chore: Adds specs
iamsivin Mar 14, 2024
8b207a9
fix: notification types
iamsivin Mar 14, 2024
3a02156
fix: responsive issues
iamsivin Mar 14, 2024
162efff
chore: Ui fixes
iamsivin Mar 14, 2024
905cb65
chore: clean up
iamsivin Mar 14, 2024
ab2e2b9
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 14, 2024
eb91945
chore: style fix
iamsivin Mar 15, 2024
9848b43
chore: clean up
iamsivin Mar 15, 2024
dd2617c
chore: add sla title
muhsin-k Mar 15, 2024
884433e
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 15, 2024
a87ebb1
Merge branch 'develop' into feat/CW-3082
muhsin-k Mar 15, 2024
dc392da
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 15, 2024
ccca226
chore: Review fix
iamsivin Mar 15, 2024
b581d19
feat: Add sla types
iamsivin Mar 15, 2024
af90e3a
feat: add resize directive
scmmishra Mar 15, 2024
8925cf1
chore: run tailwind format
scmmishra Mar 15, 2024
9563281
refactor: use a custom directive for resize
scmmishra Mar 15, 2024
0b12388
test: resize directive
scmmishra Mar 15, 2024
82dda9b
chore: Review fix
iamsivin Mar 15, 2024
d9dee0c
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 17, 2024
279c11f
fix: snapshot
iamsivin Mar 18, 2024
f4f068a
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 18, 2024
1588db0
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 18, 2024
271b7da
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 21, 2024
64ff91a
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 25, 2024
f37fd87
Merge branch 'develop' into feat/CW-3082
iamsivin Mar 27, 2024
d8108ee
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 1, 2024
59fa792
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 4, 2024
0c868fe
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 8, 2024
a1541a8
Merge branch 'develop' into feat/CW-3082
scmmishra Apr 10, 2024
2086f52
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 12, 2024
801d9b5
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 15, 2024
7c7aebc
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 24, 2024
4f20741
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 29, 2024
bbe4508
Merge branch 'develop' into feat/CW-3082
iamsivin Apr 30, 2024
4fdbaa2
chore: Color fix
iamsivin Apr 30, 2024
d60fe03
Merge branch 'develop' into feat/CW-3082
iamsivin May 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 41 additions & 0 deletions app/javascript/dashboard/helper/directives/resize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { debounce } from '@chatwoot/utils';

const RESIZE_OBSERVER_DEBOUNCE_TIME = 100;

function createResizeObserver(el, binding) {
const { value } = binding;
const observer = new ResizeObserver(
debounce(entries => {
const entry = entries[0];
if (entry && value && typeof value === 'function') {
value(entry);
}
}, RESIZE_OBSERVER_DEBOUNCE_TIME)
);

el.cwResizeObserver = observer;
observer.observe(el);
}

function destroyResizeObserver(el) {
if (el.cwResizeObserver) {
el.cwResizeObserver.unobserve(el);
el.cwResizeObserver.disconnect();
delete el.cwResizeObserver;
}
}

export default {
bind(el, binding) {
createResizeObserver(el, binding);
},
update(el, binding) {
if (binding.oldValue !== binding.value) {
destroyResizeObserver(el);
createResizeObserver(el, binding);
}
},
unbind(el) {
destroyResizeObserver(el);
},
};
26 changes: 26 additions & 0 deletions app/javascript/dashboard/helper/snoozeHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,29 @@ export const snoozedReopenTime = snoozedUntil => {
}
return snoozedUntil ? format(date, 'd MMM, h.mmaaa') : null;
};
export const snoozedReopenTimeToTimestamp = snoozedUntil => {
return snoozedUntil ? getUnixTime(new Date(snoozedUntil)) : null;
};
export const shortenSnoozeTime = snoozedUntil => {
if (!snoozedUntil) {
return null;
}
const unitMap = {
minutes: 'm',
minute: 'm',
hours: 'h',
hour: 'h',
days: 'd',
day: 'd',
months: 'mo',
month: 'mo',
years: 'y',
year: 'y',
};
const shortenTime = snoozedUntil.replace(
/\s(minute|hour|day|month|year)s?\b/gi,
(match, unit) => unitMap[unit.toLowerCase()] || match
);

return shortenTime;
};
78 changes: 78 additions & 0 deletions app/javascript/dashboard/helper/specs/directives/resize.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import resize from '../../directives/resize';

class ResizeObserverMock {
// eslint-disable-next-line class-methods-use-this
observe() {}

// eslint-disable-next-line class-methods-use-this
unobserve() {}

// eslint-disable-next-line class-methods-use-this
disconnect() {}
}

describe('resize directive', () => {
let el;
let binding;
let observer;

beforeEach(() => {
el = document.createElement('div');
binding = {
value: jest.fn(),
};
observer = {
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
};
window.ResizeObserver = ResizeObserverMock;
jest.spyOn(window, 'ResizeObserver').mockImplementation(() => observer);
});

afterEach(() => {
jest.clearAllMocks();
});

it('should create ResizeObserver on bind', () => {
resize.bind(el, binding);

expect(ResizeObserver).toHaveBeenCalled();
expect(observer.observe).toHaveBeenCalledWith(el);
});

it('should call callback on observer callback', () => {
el = document.createElement('div');
binding = {
value: jest.fn(),
};

resize.bind(el, binding);

const entries = [{ contentRect: { width: 100, height: 100 } }];
const callback = binding.value;
callback(entries[0]);

expect(binding.value).toHaveBeenCalledWith(entries[0]);
});

it('should destroy and recreate observer on update', () => {
resize.bind(el, binding);

resize.update(el, { ...binding, oldValue: 'old' });

expect(observer.unobserve).toHaveBeenCalledWith(el);
expect(observer.disconnect).toHaveBeenCalled();
expect(ResizeObserver).toHaveBeenCalledTimes(2);
expect(observer.observe).toHaveBeenCalledTimes(2);
});

it('should destroy observer on unbind', () => {
resize.bind(el, binding);

resize.unbind(el);

expect(observer.unobserve).toHaveBeenCalledWith(el);
expect(observer.disconnect).toHaveBeenCalled();
});
});
39 changes: 39 additions & 0 deletions app/javascript/dashboard/helper/specs/snoozeHelpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
findStartOfNextMonth,
findNextDay,
setHoursToNine,
snoozedReopenTimeToTimestamp,
shortenSnoozeTime,
} from '../snoozeHelpers';

describe('#Snooze Helpers', () => {
Expand Down Expand Up @@ -107,4 +109,41 @@ describe('#Snooze Helpers', () => {
expect(findNextDay(today)).toEqual(nextDay);
});
});

describe('snoozedReopenTimeToTimestamp', () => {
it('should return timestamp if snoozedUntil is not nil', () => {
expect(snoozedReopenTimeToTimestamp('2023-06-07T09:00:00.000Z')).toEqual(
1686128400
);
});
it('should return nil if snoozedUntil is nil', () => {
expect(snoozedReopenTimeToTimestamp(null)).toEqual(null);
});
});

describe('shortenSnoozeTime', () => {
it('should return shortened time if snoozedUntil is not nil and day is passed', () => {
expect(shortenSnoozeTime('1 day')).toEqual('1d');
});

it('should return shortened time if snoozedUntil is not nil and month is passed', () => {
expect(shortenSnoozeTime('1 month')).toEqual('1mo');
});

it('should return shortened time if snoozedUntil is not nil and year is passed', () => {
expect(shortenSnoozeTime('1 year')).toEqual('1y');
});

it('should return shortened time if snoozedUntil is not nil and hour is passed', () => {
expect(shortenSnoozeTime('1 hour')).toEqual('1h');
});

it('should return shortened time if snoozedUntil is not nil and minutes is passed', () => {
expect(shortenSnoozeTime('1 minutes')).toEqual('1m');
});

it('should return nil if snoozedUntil is nil', () => {
expect(shortenSnoozeTime(null)).toEqual(null);
});
});
});
18 changes: 7 additions & 11 deletions app/javascript/dashboard/i18n/locale/en/inbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@
"NO_NOTIFICATIONS": "No notifications",
"NOTE": "Notifications from all subscribed inboxes",
"NO_MESSAGES_AVAILABLE": "Oops! Not able to fetch messages",
"SNOOZED_UNTIL": "Snoozed until",
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week"
"SNOOZED_UNTIL": "We’ll remind you after {time}",
"SNOOZED_ENDS": "We won’t notify you again"
},
"ACTION_HEADER": {
"SNOOZE": "Snooze notification",
"DELETE": "Delete notification",
"BACK": "Back"
},
"TYPES": {
"CONVERSATION_MENTION": "You have been mentioned in a conversation",
"CONVERSATION_CREATION": "New conversation created",
"CONVERSATION_ASSIGNMENT": "A conversation has been assigned to you",
"ASSIGNED_CONVERSATION_NEW_MESSAGE": "New message in an assigned conversation",
"PARTICIPATING_CONVERSATION_NEW_MESSAGE": "New message in a conversation you are participating in",
"SLA_MISSED_FIRST_RESPONSE": "SLA target first response missed for conversation",
"SLA_MISSED_NEXT_RESPONSE": "SLA target next response missed for conversation",
"SLA_MISSED_RESOLUTION": "SLA target resolution missed for conversation"
"CONVERSATION_MENTION": "Mention",
"CONVERSATION_ASSIGNMENT": "Assigned to you",
"SLA_MISSED_FIRST_RESPONSE": "SLA breach",
"SLA_MISSED_NEXT_RESPONSE": "SLA breach",
"SLA_MISSED_RESOLUTION": "SLA breach"
},
"MENU_ITEM": {
"MARK_AS_READ": "Mark as read",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="h-full w-full md:w-[calc(100%-360px)]">
<div class="h-full flex-1 min-w-0">
<div v-if="showEmptyState" class="flex w-full h-full">
<inbox-empty-state
:empty-state-message="$t('INBOX.LIST.NO_MESSAGES_AVAILABLE')"
Expand Down