Skip to content

Commit

Permalink
Draft permissions UI (#255)
Browse files Browse the repository at this point in the history
* WIP sidebar tweaks

* Prototype success animation

* Improved animations and icon-display logic

* Prep for loading state

* Update index.ts

* Create index.hbs

* Move folders

* Popover tweak, type fixes

* Cleanup, style tweaks

* WIP Tooltip states

* Improve most UX bugs

* Add isSelected check

* Copy and design tweaks

* WIP: Tooltip delay

* Add delay to tooltip

* Reduce default delay

* Cleanup and documentation

* Cleanup and documentation

* Add open animation

* WIP tile styles

* Update thumbnail.hbs

* Badge style tweaks

* Add default animation

* Update tooltip.ts

* Update sidebar.scss

* Update sidebar.hbs

* Basic wiring up

* Update copyable URL (draft)

* Add documentation to CopyURL

* Revert out-of-scope changes

* Revert drastic design changes

* Rename a prop

* Improve UI reactivity

* Remove unused property

* Remove unused import

* Rename didInsert

* Documentation and dasherize test

* Remove old code, unused color variables

* CSS tweak

* Add CopyURLButton tests

* Additional tests and cleanup

* Fix failing tests
  • Loading branch information
jeffdaley authored Jul 20, 2023
1 parent 295e045 commit aa9d809
Show file tree
Hide file tree
Showing 14 changed files with 822 additions and 93 deletions.
10 changes: 6 additions & 4 deletions web/app/components/copy-u-r-l-button.hbs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
{{! @glint-nocheck: not typesafe yet }}
<Action
data-test-copy-url-button
data-test-url={{@url}}
data-test-icon={{this.icon}}
{{tooltip
(if this.urlWasRecentlyCopied "Copied!" "Copy URL")
placement=(or @tooltipPlacement "top")
this.tooltipText
placement=@tooltipPlacement
isForcedOpen=this.tooltipIsForcedOpen
stayOpenOnClick=true
}}
{{did-insert this.didInsertButton}}
{{on "click" (perform this.copyURL)}}
...attributes
>
<FlightIcon @name={{if this.urlWasRecentlyCopied "check" "link"}} />
<FlightIcon @name={{this.icon}} />
</Action>
50 changes: 47 additions & 3 deletions web/app/components/copy-u-r-l-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ interface CopyURLButtonComponentSignature {
Args: {
url: string;
tooltipPlacement?: Placement;
tooltipIsForcedOpen?: boolean;
tooltipText?: string;
icon?: string;
};
}

Expand All @@ -21,20 +24,55 @@ export default class CopyURLButtonComponent extends Component<CopyURLButtonCompo

/**
* Whether the URL was recently copied to the clipboard.
* Used to determine if the tooltip should say "Copy URL" or "Copied."
* Used to determine if the tooltip should say "Copy link" or "Copied."
* Temporarily set true when the URL is successfully copied.
*/
@tracked protected urlWasRecentlyCopied = false;

/**
* The button element.
* The button element, captured on render.
* Used to get the tooltip's ID by way of the `aria-describedby` attribute.
*/
@tracked private button: HTMLElement | null = null;

/**
* Whether the tooltip is forced open regardless of hover state.
* True when the parent has provided text for the tooltip,
* such as "Creating link..." and "Link created!"
*/
protected get tooltipIsForcedOpen() {
return this.args.tooltipIsForcedOpen ?? false;
}

/**
* The icon to show in the button.
* If the parent has provided an icon, e.g., "loading," use that.
* Otherwise use use "link" or, if a URL was recently copied, "check."
*/
protected get icon() {
if (this.args.icon) {
return this.args.icon;
} else {
return this.urlWasRecentlyCopied ? "check" : "link";
}
}

/**
* The text to show in the tooltip.
* If the parent has provided text, e.g., "Loading," use that.
* Otherwise use "Copy link" or, if a URL was recently copied, "Link copied!"
*/
get tooltipText(): string {
if (this.args.tooltipText) {
return this.args.tooltipText;
} else {
return this.urlWasRecentlyCopied ? "Link copied!" : "Copy link";
}
}

/**
* The action called when the button is clicked.
* Registers the button element locally.
* Registers the button locally for its `aria-describedby` attribute.
*/
@action protected didInsertButton(e: HTMLElement) {
this.button = e;
Expand Down Expand Up @@ -83,3 +121,9 @@ export default class CopyURLButtonComponent extends Component<CopyURLButtonCompo
}
});
}

declare module "@glint/environment-ember-loose/registry" {
export default interface Registry {
CopyURLButton: typeof CopyURLButtonComponent;
}
}
159 changes: 111 additions & 48 deletions web/app/components/document/sidebar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
@isCollapsed={{@isCollapsed}}
@toggleCollapsed={{@toggleCollapsed}}
@userHasScrolled={{this.userHasScrolled}}
@shareButtonIsShown={{this.shareButtonIsShown}}
@shareButtonTooltipText={{this.temporaryShareButtonTooltipText}}
@shareButtonIcon={{this.temporaryShareButtonIcon}}
/>

{{#unless @isCollapsed}}
<div
class="sidebar-body"
{{on "scroll" this.onScroll}}
{{did-insert this.registerBody}}
{{did-insert this.didInsertBody}}
>
{{#let (get-product-id this.product) as |productIcon|}}
{{#if productIcon}}
Expand All @@ -24,62 +27,119 @@
{{/let}}

<div class="sidebar-body-container">
<div class="flex flex-col items-start space-y-2">
{{#if (is-empty @document.docNumber)}}
<small class="hds-typography-body-100 hds-foreground-faint">{{#unless
(is-empty @document.docType)
}}{{@document.docType}}{{/unless}}
</small>
{{else}}
<small class="hds-typography-body-100 hds-foreground-faint">{{#unless
(is-empty @document.docType)
}}{{@document.docType}}{{/unless}}
&bullet;
<span data-test-sidebar-doc-number>
{{@document.docNumber}}
</span>
</small>
{{/if}}
<div>
{{! div to break the parent's space-y styles }}
<div
class="flex items-center space-x-1.5
{{if this.isDraft 'mb-4 -mt-2' 'mb-2'}}"
>
<Hds::Badge
data-test-sidebar-title-badge
@text={{if this.isDraft "Draft" @document.docNumber}}
class="uppercase !rounded-[3px]
{{if
@document.isDraft
'!bg-color-palette-neutral-500 !text-white'
'!bg-transparent pl-0 !text-color-foreground-faint'
}}
"
/>
{{#if this.isDraft}}
<X::DropdownList
data-test-draft-visibility-dropdown
@items={{this.draftVisibilityOptions}}
@selected={{this.draftVisibility}}
@renderOut={{true}}
@offset={{hash mainAxis=0 crossAxis=-7}}
class="w-[350px]"
>
<:anchor as |dd|>
<dd.ToggleAction
data-test-draft-visibility-toggle
data-test-icon={{this.draftVisibilityIcon}}
data-test-chevron-direction={{if
dd.contentIsShown
"up"
"down"
}}
class="flex items-center text-color-foreground-faint sidebar-header-button draft-visibility-button"
{{tooltip
this.toggleDraftVisibilityTooltipText
placement="bottom"
}}
>
<FlightIcon @name={{this.draftVisibilityIcon}} />
<FlightIcon
@name={{if dd.contentIsShown "chevron-up" "chevron-down"}}
/>
</dd.ToggleAction>
</:anchor>
<:item as |dd|>
<dd.Action
data-test-draft-visibility-option
data-test-is-checked={{dd.isSelected}}
data-test-value={{dd.value}}
class="flex items-start gap-3 py-2.5 pl-4 pr-6"
{{on "click" (perform this.setDraftVisibility dd.value)}}
>
<FlightIcon @name={{dd.attrs.icon}} class="shrink-0 mt-0.5" />
<div class="w-full">
<h4>{{dd.attrs.title}}</h4>
<p>{{dd.attrs.description}}</p>
</div>
<FlightIcon
@name="check"
class="check shrink-0 mt-0.5
{{if dd.isSelected 'visible' 'invisible'}}"
/>
</dd.Action>
</:item>
</X::DropdownList>
{{/if}}
</div>
{{#if this.editingIsDisabled}}
<h1
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-strong"
>{{this.title}}</h1>
{{else}}
<EditableField
@value={{this.title}}
@onChange={{perform this.save "title"}}
@loading={{this.save.isRunning}}
@disabled={{this.editingIsDisabled}}
>
<:default>
{{#unless (is-empty this.title)}}
<h1
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-strong"
>{{this.title}}</h1>
{{else}}
<h1
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-faint"
>Enter a title here.</h1>
{{/unless}}
</:default>
<:editing as |F|>
<Hds::Form::Textarea::Field
{{auto-height-textarea}}
@value={{F.value}}
class="primary-textarea"
name="title"
{{on "blur" F.update}}
as |F|
/>
</:editing>
</EditableField>
<div class="mb-8">
<EditableField
@value={{this.title}}
@onChange={{perform this.save "title"}}
@loading={{this.save.isRunning}}
@disabled={{this.editingIsDisabled}}
>
<:default>
{{#unless (is-empty this.title)}}
<h1
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-strong"
>{{this.title}}</h1>
{{else}}
<h1
class="hds-typography-display-300 hds-font-weight-semibold hds-foreground-faint"
>Enter a title here.</h1>
{{/unless}}
</:default>
<:editing as |F|>
<Hds::Form::Textarea::Field
{{auto-height-textarea}}
@value={{F.value}}
class="primary-textarea"
name="title"
{{on "blur" F.update}}
as |F|
/>
</:editing>
</EditableField>
</div>
{{/if}}
</div>

<hr class="border-0 border-b hds-border-faint" />

<div class="flex flex-col items-start space-y-2">
<Document::Sidebar::SectionHeader @title="Summary" />
{{! Summary }}
<div class="mb-5">
<Document::Sidebar::SectionHeader @title="Summary" class="mb-2" />
{{#if this.editingIsDisabled}}
<p
class="hds-typography-body-200 hds-font-weight-medium hds-foreground-primary"
Expand Down Expand Up @@ -120,7 +180,10 @@

<div class="flex flex-col items-start space-y-2">
<Document::Sidebar::SectionHeader @title="Status" />
<Doc::State @state={{@document.status}} @hideProgress={{true}} />
<div class="flex space-x-1">
<Doc::State @state={{@document.status}} @hideProgress={{true}} />
<Hds::Badge @text={{@document.docType}} />
</div>
</div>

<div class="flex flex-col items-start space-y-2">
Expand Down
Loading

0 comments on commit aa9d809

Please sign in to comment.