Skip to content

Commit

Permalink
Update admins input UI (#533)
Browse files Browse the repository at this point in the history
* updated admins input UI

* added mention support

* suggestive changes added

* prettier update

* added openLinkInNewTab prop
  • Loading branch information
Megha-Dev-19 authored Dec 7, 2023
1 parent ebf452f commit 7ba0b71
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/devhub/components/molecule/AccountAutocomplete.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
if (!context.accountId || !props.term) return <></>;

let results = [];
const filterAccounts = props.filterAccounts ?? []; // hide certain accounts from the list
const profilesData = Social.get("*/profile/name", "final") || {};
const followingData = Social.get(
`${context.accountId}/graph/follow/**`,
Expand Down Expand Up @@ -43,6 +44,9 @@ for (let i = 0; i < profiles.length; i++) {

results.sort((a, b) => b.score - a.score);
results = results.slice(0, limit);
if (filterAccounts?.length > 0) {
results = results.filter((item) => !filterAccounts?.includes(item.accountId));
}

function onResultClick(id) {
props.onSelect && props.onSelect(id);
Expand Down
3 changes: 3 additions & 0 deletions src/devhub/components/molecule/ProfileCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const ProfileCard = (props) => {
// const hideName = props.hideName;
const hideImage = props.hideImage;
const iconOnly = props.iconOnly;
const openLinkInNewTab = props.openLinkInNewTab ?? false;

const profile = props.profile ?? Social.getr(`${accountId}/profile`);

Expand Down Expand Up @@ -66,6 +67,8 @@ const ProfileCard = (props) => {
? link
: `/${REPL_MOB}/widget/ProfilePage?accountId=${accountId}`
}
target={openLinkInNewTab ? "_blank" : ""}
rel="noopener noreferrer"
className="link-dark text-truncate d-inline-flex"
>
{inner}
Expand Down
2 changes: 1 addition & 1 deletion src/devhub/entity/community/Teams.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ return (
style={{ minHeight: 30 }}
>
<h5 className="h5 d-inline-flex gap-2 m-0">
<span>Admins</span>
<span>Community Admins</span>
</h5>
</div>
<UserList name="Admin" users={communityData.admins} />
Expand Down
173 changes: 158 additions & 15 deletions src/devhub/entity/community/configuration/AccessControlConfigurator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,168 @@ const CommunityAccessControlSchema = {
},
};

const { data, onSubmit, onCancel, setIsActive, isActive } = props;
const Struct = VM.require("${REPL_DEVHUB}/widget/core.lib.struct");

if (!Struct) {
return <p>Loading modules...</p>;
}

const AutoComplete = styled.div`
z-index: 5;
> div > div {
padding: calc(var(--padding) / 2);
}
`;

const Wrapper = styled.div`
.container {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.5em;
}
.admins-item {
display: inline-block;
padding: 0.6em 0.8em;
border-radius: 10px;
border: 1px solid lightgray;
position: relative;
}
.admins-item .remove {
position: absolute;
right: 5px;
top: 0;
font-size: 18px;
color: grey;
cursor: pointer;
}
.admins-input {
flex-grow: 1;
border: none;
outline: none;
}
function handleOnSubmit(v) {
if (v.admins) {
v.admins = v.admins.split(",").map((admin) => admin.trim());
input[type="text"]:disabled {
all: inherit;
}
onSubmit(v);
input::placeholder {
font-size: 16px;
}
`;

const { data, onSubmit, onCancel, setIsActive, isActive } = props;
const initialValues = Struct.typeMatch(CommunityAccessControlSchema)
? Struct.pick(data ?? {}, Object.keys(CommunityAccessControlSchema))
: {};

const [admins, setAdmins] = useState(initialValues?.admins ?? []);
const [text, setText] = useState("");
const [showAccountAutocomplete, setShowAutoAutocomplete] = useState(false);

function handleKeyDown(e) {
if (e.key !== "Enter") return;
const value = e.target.value;
if (!value.trim()) return;
// Add the value to the admins array
setAdmins([...admins, value]);
setText("");
}

const onCancelClick = () => {
setAdmins(initialValues?.admins ?? []);
setIsActive(false);
};

const onSubmitClick = () => {
onSubmit({ admins: admins.map((admin) => admin.trim()) });
setIsActive(false);
};

function autoCompleteAccountId(id) {
setAdmins([...admins, id]);
setText("");
setShowAutoAutocomplete(false);
}

return (
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.organism.Configurator"}
props={{
externalState: data,
schema: CommunityAccessControlSchema,
onSubmit: handleOnSubmit,
isActive,
onCancel: onCancel,
}}
/>
<Wrapper className="flex-grow-1 d-flex flex-column gap-4">
<div className="container">
{admins.map((admin, index) => (
<div className="admins-item" key={index}>
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.ProfileCard"}
props={{
accountId: admin,
nearDevGovGigsWidgetsAccountId: "${REPL_DEVHUB}",
openLinkInNewTab: true,
}}
/>
{/* don't allow removal if only 1 admin is added */}
{admins.length > 1 && isActive && (
<span
className="remove"
onClick={() => setAdmins(admins.filter((item) => item !== admin))}
>
&times;
</span>
)}
</div>
))}
<input
disabled={!isActive}
value={text}
onChange={(v) => {
setShowAutoAutocomplete(true);
setText(v.target.value);
}}
onKeyDown={handleKeyDown}
type="text"
className="admins-input"
placeholder={isActive && "Add Admins here..."}
/>
</div>
{showAccountAutocomplete && (
<AutoComplete>
<Widget
src="${REPL_DEVHUB}/widget/devhub.components.molecule.AccountAutocomplete"
props={{
term: text,
onSelect: autoCompleteAccountId,
onClose: () => setShowAutoAutocomplete(false),
filterAccounts: admins,
}}
/>
</AutoComplete>
)}
{isActive && (
<div className="d-flex align-items-center justify-content-end gap-3 mt-auto">
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Button"}
props={{
classNames: { root: "btn-outline-danger shadow-none border-0" },
label: cancelLabel || "Cancel",
onClick: onCancelClick,
}}
/>
<Widget
src={"${REPL_DEVHUB}/widget/devhub.components.molecule.Button"}
props={{
classNames: { root: "btn-success" },
disabled: Struct.isEqual(admins, initialValues?.admins ?? []),
icon: {
type: "bootstrap_icon",
variant: "bi-check-circle-fill",
},
label: "Submit",
onClick: onSubmitClick,
}}
/>
</div>
)}
</Wrapper>
);
2 changes: 1 addition & 1 deletion src/devhub/page/community/configuration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ return (
"${REPL_DEVHUB}/widget/devhub.entity.community.configuration.ConfigurationSection"
}
props={{
title: "Access Control",
title: "Community Admins",
hasConfigurePermissions,
Configurator: (p) => (
<Widget
Expand Down

0 comments on commit 7ba0b71

Please sign in to comment.