diff --git a/app/pb_kits/playbook/pb_timestamp/_timestamp.html.erb b/app/pb_kits/playbook/pb_timestamp/_timestamp.html.erb index fbb78baa4f..223edeb75c 100644 --- a/app/pb_kits/playbook/pb_timestamp/_timestamp.html.erb +++ b/app/pb_kits/playbook/pb_timestamp/_timestamp.html.erb @@ -2,5 +2,17 @@ id: object.id, data: object.data, class: object.classname) do %> - <%= pb_rails("caption", props: { text: object.text, tag: 'span', size: 'xs' }) %> + + <% case object.variant + when "updated" %> + <%= pb_rails("caption", props: { text: object.format_updated_string, size: 'xs', dark: object.dark }) %> + <% when "elapsed" %> + <%= pb_rails("caption", props: { text: object.format_updated_string, size: 'xs', dark: object.dark }) %> + <% else %> + <% if object.show_date %> + <%= pb_rails("caption", props: { text: object.format_datetime_string, size: 'xs', dark: object.dark }) %> + <% else %> + <%= pb_rails("caption", props: { text: object.format_time_string, size: 'xs', dark: object.dark }) %> + <% end %> + <% end %> <% end %> diff --git a/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx b/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx index 2d25f79920..e7bd55af65 100644 --- a/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx +++ b/app/pb_kits/playbook/pb_timestamp/_timestamp.jsx @@ -2,36 +2,112 @@ import React from 'react' import classnames from 'classnames' - +import DateTime from '../pb_kit/dateTime.js' +import { buildCss } from '../utilities/props' import { Caption } from '../' - -import { buildCss, buildDataProps } from '../utilities/props' - import { globalProps } from '../utilities/globalProps.js' type TimestampProps = { + align?: "left" | "center" | "right", + className?: string | array, + dark?: boolean, + data?: string, + text: string, + timestamp: string, + timezone: string, id?: string, - data?: object, - className?: string, - text?: string, + showDate?: boolean, + showUser?: boolean, + showTimezone?: boolean, + variant?: "default" | "elapsed" | "updated" } const Timestamp = (props: TimestampProps) => { - const { id, className, data = {}, text } = props - const dataProps = buildDataProps(data) - const pbCss = buildCss('pb_timestamp_kit') + const { + align = 'left', + className, + dark = false, + text, + timestamp, + timezone, + showDate = true, + showUser = false, + showTimezone = false, + variant = 'default', + } = props + const classes = classnames( + buildCss('pb_timestamp_kit', align, { + dark: dark, + variant: variant, + }), + globalProps(props), + className + ) + + const currentYear = new Date().getFullYear().toString() + const dateTimestamp = new DateTime({ value: timestamp, zone: timezone }) + const dateDisplay = dateTimestamp.toMonth() + ' ' + dateTimestamp.toDay() + const timeDisplay = dateTimestamp.toHour() + ':' + dateTimestamp.toMinute() + dateTimestamp.toMeridian() + + var fullTimeDisplay = function fullTimeDisplay(dateTimestamp, timeDisplay, timezone, showTimezone) { + if (showTimezone == 'true' && timezone.length > 0) { + timeDisplay = timeDisplay + ' ' + dateTimestamp.toTimezone() + } + return timeDisplay + } + + var fullDateDisplay = function fullDateDisplay(dateTimestamp, currentYear, dateDisplay, timezone, showTimezone) { + var fullDisplay = dateTimestamp.toMonth() + ' ' + dateTimestamp.toDay() + if (dateTimestamp.toYear() > currentYear) { + fullDisplay = fullDisplay + ', ' + dateTimestamp.toYear().toString() + } + return fullDisplay + ' \u00b7 ' + fullTimeDisplay(dateTimestamp, timeDisplay, timezone, showTimezone) + } + + var fullElapsedDisplay = function fullElapsedDisplay(showUser, text, dateTimestamp){ + var userDisplay = (showUser == 'true' && text.length > 0) ? ' by ' + text : '' + return 'Last updated' + userDisplay + ' ' + dateTimestamp.value.fromNow() + } + + var fullUpdatedDisplay = function fullUpdatedDisplay(showUser, text, timeDisplay, timezone, showTimezone){ + var userDisplay = (showUser == 'true' && text.length > 0) ? ' by ' + text : '' + return 'Last updated' + userDisplay + ' at ' + fullTimeDisplay(dateTimestamp, timeDisplay, timezone, showTimezone) + } return ( -
- +
+
+ + + + + + + + + + + + + + +
) } diff --git a/app/pb_kits/playbook/pb_timestamp/_timestamp.scss b/app/pb_kits/playbook/pb_timestamp/_timestamp.scss index f62ba9a75f..67e5522ee3 100644 --- a/app/pb_kits/playbook/pb_timestamp/_timestamp.scss +++ b/app/pb_kits/playbook/pb_timestamp/_timestamp.scss @@ -1,5 +1,16 @@ @import "timestamp-mixins"; +@import "../tokens/colors"; -[class^=pb_timestamp_kit] { +[class^=pb_timestamp_kit]{ @include pb_timestamp; + + &[class*=_center] { + text-align: center; + } + &[class*=_right] { + text-align: right; + } + &[class*=_dark] { + color: $text_dk_default; + } } diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.html.erb new file mode 100644 index 0000000000..52dc03a5ce --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.html.erb @@ -0,0 +1,69 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + align: "left" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + align: "center" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + align: "right" +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.jsx new file mode 100644 index 0000000000..1e236c400a --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_align.jsx @@ -0,0 +1,91 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampAlign = (props) => { + return ( +
+ + +
+ + + +
+ + + +
+
+ + + +
+ + + +
+ + + +
+
+ + + +
+ + + +
+ + +
+ ) +} + +export default TimestampAlign diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.html.erb index 01e8ea7952..1344b4629f 100644 --- a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.html.erb +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.html.erb @@ -1 +1,21 @@ -<%= pb_rails("timestamp", props: { text: "20 seconds ago" }) %> +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + align: "left" +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.jsx index 5be89b837e..d8bd6f9461 100644 --- a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.jsx +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_default.jsx @@ -1,8 +1,35 @@ import React from 'react' -import { Timestamp } from '../../' +import Timestamp from '../_timestamp.jsx' -const TimestampDefault = () => ( - -) +const TimestampDefault = (props) => { + return ( +
+ + +
+ + + +
+ + +
+ ) +} export default TimestampDefault diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.html.erb new file mode 100644 index 0000000000..898d4c6862 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.html.erb @@ -0,0 +1,14 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: true, + text: "Maricris Nonato" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: false +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx new file mode 100644 index 0000000000..bf48fdcaa4 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed.jsx @@ -0,0 +1,27 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampElapsed = (props) => { + return ( +
+ + +
+ + +
+ ) +} + +export default TimestampElapsed diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed_align.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed_align.html.erb new file mode 100644 index 0000000000..464e7307fa --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed_align.html.erb @@ -0,0 +1,54 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: true, + text: "Maricris Nonato", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: false, + align: "left" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: true, + text: "Maricris Nonato", + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: false, + align: "center" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: true, + text: "Maricris Nonato", + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "elapsed", + show_user: false, + align: "right" +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed_align.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed_align.jsx new file mode 100644 index 0000000000..8ad27e89b3 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_elapsed_align.jsx @@ -0,0 +1,73 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampUpdatedAlign = (props) => { + return ( +
+ + +
+ + + +
+
+ + + +
+ + + +
+
+ + + +
+ + +
+ ) +} + +export default TimestampUpdatedAlign diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.html.erb new file mode 100644 index 0000000000..47994208ed --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.html.erb @@ -0,0 +1,59 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "America/New_York", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "left" +}) %> + +
diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.jsx new file mode 100644 index 0000000000..e000930f6d --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones.jsx @@ -0,0 +1,74 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampTimezones = (props) => { + return ( +
+ + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+ ) +} + +export default TimestampTimezones diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones_align.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones_align.html.erb new file mode 100644 index 0000000000..c2518b9f96 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones_align.html.erb @@ -0,0 +1,177 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "America/New_York", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "left" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "left" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "America/New_York", + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "center" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "center" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "America/New_York", + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "America/New_York", + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: false, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "right" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now + 4.years, + show_date: true, + show_timezone: true, + timezone: "Asia/Hong_Kong", + align: "right" +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones_align.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones_align.jsx new file mode 100644 index 0000000000..c3f109772d --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_timezones_align.jsx @@ -0,0 +1,209 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampTimezonesAlign = (props) => { + return ( +
+ + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ ) +} + +export default TimestampTimezonesAlign diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.html.erb new file mode 100644 index 0000000000..e23fa73867 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.html.erb @@ -0,0 +1,35 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + show_user: true, + text: "Maricris Nonato" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + show_user: false +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + show_user: true, + show_timezone: true, + text: "Maricris Nonato", + timezone: "America/New_York" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + show_user: false, + show_timezone: true, + timezone: "America/New_York" +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.jsx new file mode 100644 index 0000000000..888ffe97e8 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated.jsx @@ -0,0 +1,51 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampUpdated = (props) => { + return ( +
+ + +
+ + + +
+
+ + + +
+ + +
+ ) +} + +export default TimestampUpdated diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated_align.html.erb b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated_align.html.erb new file mode 100644 index 0000000000..1713a177f6 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated_align.html.erb @@ -0,0 +1,123 @@ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "left", + show_user: true, + text: "Maricris Nonato" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "left", + show_user: false +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "left", + show_user: true, + show_timezone: true, + text: "Maricris Nonato", + timezone: "America/New_York" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "left", + show_user: false, + show_timezone: true, + timezone: "America/New_York" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "center", + show_user: true, + text: "Maricris Nonato" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "center", + show_user: false +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "center", + show_user: true, + show_timezone: true, + text: "Maricris Nonato", + timezone: "America/New_York" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "center", + show_user: false, + show_timezone: true, + timezone: "America/New_York" +}) %> + +

+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "right", + show_user: true, + text: "Maricris Nonato" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "right", + show_user: false +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "right", + show_user: true, + show_timezone: true, + text: "Maricris Nonato", + timezone: "America/New_York" +}) %> + +
+ +<%= pb_rails("timestamp", props: { + timestamp: DateTime.now, + variant: "updated", + align: "right", + show_user: false, + show_timezone: true, + timezone: "America/New_York" +}) %> diff --git a/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated_align.jsx b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated_align.jsx new file mode 100644 index 0000000000..391c90d8c6 --- /dev/null +++ b/app/pb_kits/playbook/pb_timestamp/docs/_timestamp_updated_align.jsx @@ -0,0 +1,146 @@ +import React from 'react' +import Timestamp from '../_timestamp.jsx' + +const TimestampUpdatedAlign = (props) => { + return ( +
+ + +
+ + + +
+ + + +
+ + + +
+
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + +
+ + + +
+ + + +
+ + +
+ ) +} + +export default TimestampUpdatedAlign diff --git a/app/pb_kits/playbook/pb_timestamp/docs/example.yml b/app/pb_kits/playbook/pb_timestamp/docs/example.yml index 4f1aea4e8a..424638d8ea 100644 --- a/app/pb_kits/playbook/pb_timestamp/docs/example.yml +++ b/app/pb_kits/playbook/pb_timestamp/docs/example.yml @@ -2,6 +2,20 @@ examples: rails: - timestamp_default: Default + - timestamp_align: Alignments + - timestamp_timezones: Timezones + - timestamp_timezones_align: Timezones - Alignments + - timestamp_updated: Last Updated by + - timestamp_updated_align: Last Updated by - Alignments + - timestamp_elapsed: Time Ago + - timestamp_elapsed_align: Time Ago - Alignments react: - timestamp_default: Default + - timestamp_align: Alignments + - timestamp_timezones: Timezones + - timestamp_timezones_align: Timezones - Alignments + - timestamp_updated: Last Updated by + - timestamp_updated_align: Last Updated by - Alignments + - timestamp_elapsed: Time Ago + - timestamp_elapsed_align: Time Ago - Alignments diff --git a/app/pb_kits/playbook/pb_timestamp/docs/index.js b/app/pb_kits/playbook/pb_timestamp/docs/index.js index ffefbad614..94e7153fab 100644 --- a/app/pb_kits/playbook/pb_timestamp/docs/index.js +++ b/app/pb_kits/playbook/pb_timestamp/docs/index.js @@ -1 +1,8 @@ export { default as TimestampDefault } from './_timestamp_default.jsx' +export { default as TimestampAlign } from './_timestamp_align.jsx' +export { default as TimestampTimezones } from './_timestamp_timezones.jsx' +export { default as TimestampTimezonesAlign } from './_timestamp_timezones_align.jsx' +export { default as TimestampUpdated } from './_timestamp_updated.jsx' +export { default as TimestampUpdatedAlign } from './_timestamp_updated_align.jsx' +export { default as TimestampElapsed } from './_timestamp_elapsed.jsx' +export { default as TimestampElapsedAlign } from './_timestamp_elapsed_align.jsx' diff --git a/app/pb_kits/playbook/pb_timestamp/timestamp.rb b/app/pb_kits/playbook/pb_timestamp/timestamp.rb index f2cf186181..32e2c20a1c 100644 --- a/app/pb_kits/playbook/pb_timestamp/timestamp.rb +++ b/app/pb_kits/playbook/pb_timestamp/timestamp.rb @@ -3,14 +3,80 @@ module Playbook module PbTimestamp class Timestamp + include ActionView::Helpers::DateHelper include Playbook::Props partial "pb_timestamp/timestamp" prop :text + prop :timestamp, required: true + + prop :dark, type: Playbook::Props::Boolean, + default: false + prop :align, type: Playbook::Props::Enum, + values: %w[left center right], + default: "left" + prop :show_date, type: Playbook::Props::Boolean, + default: true + prop :show_timezone, type: Playbook::Props::Boolean, + default: false + prop :show_user, type: Playbook::Props::Boolean, + default: false + prop :timezone, default: "America/New_York" + prop :variant, type: Playbook::Props::Enum, + values: %w[default elapsed updated], + default: "default" def classname - generate_classname("pb_timestamp_kit") + generate_classname("pb_timestamp_kit", variant_class, align) + end + + def format_year_string + pb_date_time.to_year != DateTime.now.year.to_s ? ", #{pb_date_time.to_year}" : "" + end + + def format_time_string + "#{pb_date_time.to_hour}:#{pb_date_time.to_minutes}#{pb_date_time.to_meridian} #{format_timezone_string}".strip + end + + def format_timezone_string + timezone && show_timezone ? pb_date_time.to_timezone.to_s : "" + end + + def format_date_string + "#{pb_date_time.to_month_downcase} #{pb_date_time.to_unpadded_day}#{format_year_string}" + end + + def format_datetime_string + "#{format_date_string} · #{format_time_string}".html_safe + end + + def format_updated_string + user_string = show_user ? " by #{text}" : "" + + case variant + when "updated" + datetime_string = " on #{format_date_string} at #{format_time_string}" + when "elapsed" + datetime_string = " #{time_ago_in_words(pb_date_time.convert_to_timestamp)} ago" + end + + "Last updated#{user_string}#{datetime_string}" + end + + private + + def pb_date_time + Playbook::PbKit::PbDateTime.new(timestamp, timezone) + end + + def variant_class + case variant + when "updated" + "updated" + when "elapsed" + "elapsed" + end end end end diff --git a/spec/pb_kits/playbook/kits/timestamp_spec.rb b/spec/pb_kits/playbook/kits/timestamp_spec.rb index ace3fac71b..33919dc36d 100644 --- a/spec/pb_kits/playbook/kits/timestamp_spec.rb +++ b/spec/pb_kits/playbook/kits/timestamp_spec.rb @@ -1,18 +1,164 @@ # frozen_string_literal: true require_relative "../../../../app/pb_kits/playbook/pb_timestamp/timestamp" +include ActionView::Helpers::DateHelper RSpec.describe Playbook::PbTimestamp::Timestamp do subject { Playbook::PbTimestamp::Timestamp } + let(:timestamp) { DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze } + let(:future_timestamp) { DateTime.new(2024, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze } it { is_expected.to define_partial } - it { is_expected.to define_prop(:text) } + it { is_expected.to define_enum_prop(:align) + .with_values("left", "center", "right") } + it { is_expected.to define_prop(:dark) + .of_type(Playbook::Props::Boolean) } + it { is_expected.to define_prop(:show_date) + .of_type(Playbook::Props::Boolean) } + it { is_expected.to define_prop(:show_timezone) + .of_type(Playbook::Props::Boolean) } + it { is_expected.to define_prop(:show_user) + .of_type(Playbook::Props::Boolean) } + it { is_expected.to define_string_prop(:text) } + it { is_expected.to define_string_prop(:timezone) } + it { is_expected.to define_prop(:timestamp) + .that_is_required } + it { is_expected.to define_enum_prop(:variant) + .with_values("default", "elapsed", "updated") } describe "#classname" do it "returns namespaced class name", :aggregate_failures do - expect(subject.new({}).classname).to eq "pb_timestamp_kit" - expect(subject.new(classname: "additional_class").classname).to eq "pb_timestamp_kit additional_class" + timestamp = DateTime.current + align = "left" + dark = "dark" + + expect(subject.new(timestamp: timestamp).classname).to eq "pb_timestamp_kit_#{align}" + expect(subject.new(variant: "updated", timestamp: timestamp).classname).to eq "pb_timestamp_kit_updated_#{align}" + expect(subject.new(variant: "updated", dark: true, timestamp: timestamp).classname).to eq "pb_timestamp_kit_updated_left dark" + expect(subject.new(variant: "elapsed", timestamp: timestamp).classname).to eq "pb_timestamp_kit_elapsed_#{align}" + expect(subject.new(variant: "elapsed", dark: true, timestamp: timestamp).classname).to eq "pb_timestamp_kit_elapsed_#{align} dark" + expect(subject.new(timestamp: timestamp, classname: "additional_class").classname).to eq "pb_timestamp_kit_left additional_class" + end + end + + describe "#format_year_string" do + it "returns the year if timestamp not current year" do + expect(subject.new(timestamp: DateTime.current + 4.years).format_year_string).to eq(", #{(DateTime.current + 4.years).year}") + end + + it "returns nothing if timestamp is in year" do + expect(subject.new(timestamp: DateTime.current).format_year_string).to eq("") + end + end + + describe "#format_time_string" do + it "returns HH:MM with meridian" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + expect(subject.new(timestamp: timestamp).format_time_string).to eq("4:30p") + end + + context "timezone" do + it "returns timezone if present && show_timezone" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + expect(subject.new(timestamp: timestamp, timezone: "America/New_York", show_timezone: true).format_time_string).to eq("4:30p EDT") + end + + it "doesn't returns timezone if present && show_timezone is false" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + expect(subject.new(timestamp: timestamp, timezone: "America/New_York", show_timezone: false).format_time_string).to eq("4:30p") + end + end + end + + describe "#format_date_string" do + it "returns date in specific format without year" do + expect(subject.new(timestamp: timestamp).format_date_string).to eq("#{timestamp.strftime('%b %-d')}") + end + + it "returns date in specific format with year" do + expect(subject.new(timestamp: future_timestamp).format_date_string).to eq("#{future_timestamp.strftime('%b %-d, %Y')}") + end + end + + describe "#format_datetime_string" do + it "returns date with time separated by middot" do + expect(subject.new(timestamp: timestamp).format_datetime_string).to eq("Oct 10 · 4:30p") + end + + it "returns full date and time separated by middot" do + expect(subject.new(timestamp: future_timestamp).format_datetime_string).to eq("Oct 10, 2024 · 4:30p") + end + end + + describe "#format_updated_string" do + let(:name) { "Maricris Nonato" } + + context "for variant updated" do + let(:variant) { "updated" } + + context "if show_user is true" do + let(:show_user) { true } + it "returns last updated string including user's name" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + date = "Oct 10" + time = " 4:30p" + + expect(subject.new(timestamp: timestamp, variant: variant, show_user: show_user, text: name).format_updated_string).to eq("Last updated by #{name} on #{date} at#{time}") + end + + it "returns last updated with year including user's name" do + timestamp = DateTime.new(2024, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + date = "Oct 10, 2024" + time = " 4:30p" + + expect(subject.new(timestamp: timestamp, variant: variant, show_user: show_user, text: name).format_updated_string).to eq("Last updated by #{name} on #{date} at#{time}") + end + end + + context "if show_user is false" do + let(:show_user) { false } + it "returns last updated without user's name" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + date = "Oct 10" + time = " 4:30p" + + expect(subject.new(timestamp: timestamp, variant: variant, show_user: show_user).format_updated_string).to eq("Last updated on #{date} at#{time}") + end + + it "returns last updated with year without user's name" do + timestamp = DateTime.new(2024, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + date = "Oct 10, 2024" + time = " 4:30p" + + expect(subject.new(timestamp: timestamp, variant: variant, show_user: show_user).format_updated_string).to eq("Last updated on #{date} at#{time}") + end + end + end + + context "for variant elapsed" do + let(:variant) { "elapsed" } + context "if show_user is true" do + let(:show_user) { true } + it "returns time elaspsed string including user's name" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + date = "Oct 10" + time = " 4:30p" + + expect(subject.new(timestamp: timestamp, variant: variant, show_user: show_user, text: name).format_updated_string).to eq("Last updated by #{name} #{time_ago_in_words(timestamp)} ago") + end + end + + context "if show_user is false" do + let(:show_user) { false } + it "returns time elaspsed string sans user's name" do + timestamp = DateTime.new(2020, 10, 10, 20, 30, 00).in_time_zone("America/New_York").freeze + date = "Oct 10" + time = " 4:30p" + + expect(subject.new(timestamp: timestamp, variant: variant, show_user: show_user).format_updated_string).to eq("Last updated #{time_ago_in_words(timestamp)} ago") + end + end end end end diff --git a/yarn.lock b/yarn.lock index f565b1b8bf..2204247588 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3399,7 +3399,7 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -5230,7 +5230,7 @@ import-local@2.0.0, import-local@^2.0.0: pkg-dir "^3.0.0" resolve-cwd "^2.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -6238,11 +6238,6 @@ lockfile@^1.0.4: dependencies: signal-exit "^3.0.2" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -6251,33 +6246,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -6313,11 +6286,6 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.template@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"