feat: check if company/person saved (chrome-extension) (#4280)
* add twenty icon * rest api calls for company * check if company exists * refacto * person/company saved call * gql codegen init * type defs * build fix * DB calls with gql codegen and apollo integration
This commit is contained in:
@ -1,10 +1,10 @@
|
||||
import createNewButton from '~/contentScript/createButton';
|
||||
import extractCompanyLinkedinLink from '~/contentScript/utils/extractCompanyLinkedinLink';
|
||||
import extractDomain from '~/contentScript/utils/extractDomain';
|
||||
import handleQueryParams from '~/utils/handleQueryParams';
|
||||
import requestDb from '~/utils/requestDb';
|
||||
import { createCompany, fetchCompany } from '~/db/company.db';
|
||||
import { CompanyInput } from '~/db/types/company.types';
|
||||
|
||||
const insertButtonForCompany = (): void => {
|
||||
const insertButtonForCompany = async (): Promise<void> => {
|
||||
// Select the element in which to create the button.
|
||||
const parentDiv: HTMLDivElement | null = document.querySelector(
|
||||
'.org-top-card-primary-actions__inner',
|
||||
@ -12,94 +12,111 @@ const insertButtonForCompany = (): void => {
|
||||
|
||||
// Create the button with desired callback funciton to execute upon click.
|
||||
if (parentDiv) {
|
||||
const newButtonCompany: HTMLButtonElement = createNewButton(
|
||||
'Add to Twenty',
|
||||
async () => {
|
||||
// Extract company-specific data from the DOM
|
||||
const companyNameElement = document.querySelector(
|
||||
'.org-top-card-summary__title',
|
||||
);
|
||||
const domainNameElement = document.querySelector(
|
||||
'.org-top-card-primary-actions__inner a',
|
||||
);
|
||||
const addressElement = document.querySelectorAll(
|
||||
'.org-top-card-summary-info-list__info-item',
|
||||
)[1];
|
||||
const employeesNumberElement = document.querySelectorAll(
|
||||
'.org-top-card-summary-info-list__info-item',
|
||||
)[3];
|
||||
|
||||
// Get the text content or other necessary data from the DOM elements
|
||||
const companyName = companyNameElement
|
||||
? companyNameElement.getAttribute('title')
|
||||
: '';
|
||||
const domainName = extractDomain(
|
||||
domainNameElement && domainNameElement.getAttribute('href'),
|
||||
);
|
||||
const address = addressElement
|
||||
? addressElement.textContent?.trim().replace(/\s+/g, ' ')
|
||||
: '';
|
||||
const employees = employeesNumberElement
|
||||
? Number(
|
||||
employeesNumberElement.textContent
|
||||
?.trim()
|
||||
.replace(/\s+/g, ' ')
|
||||
.split('-')[0],
|
||||
)
|
||||
: 0;
|
||||
|
||||
// Prepare company data to send to the backend
|
||||
const companyData = {
|
||||
name: companyName,
|
||||
domainName: domainName,
|
||||
address: address,
|
||||
employees: employees,
|
||||
linkedinLink: { url: '', label: '' },
|
||||
};
|
||||
|
||||
// Extract active tab url using chrome API - an event is triggered here and is caught by background script.
|
||||
const { url: activeTabUrl } = await chrome.runtime.sendMessage({
|
||||
action: 'getActiveTabUrl',
|
||||
});
|
||||
|
||||
// Convert URLs like https://www.linkedin.com/company/twenty/about/ to https://www.linkedin.com/company/twenty
|
||||
const companyURL = extractCompanyLinkedinLink(activeTabUrl);
|
||||
companyData.linkedinLink = { url: companyURL, label: companyURL };
|
||||
|
||||
const query = `mutation CreateOneCompany { createCompany(data:{${handleQueryParams(
|
||||
companyData,
|
||||
)}}) {id} }`;
|
||||
|
||||
const response = await requestDb(query);
|
||||
|
||||
if (response.data) {
|
||||
newButtonCompany.textContent = 'Saved';
|
||||
newButtonCompany.setAttribute('disabled', 'true');
|
||||
|
||||
// Button specific styles once the button is unclickable after successfully sending data to server.
|
||||
newButtonCompany.addEventListener('mouseenter', () => {
|
||||
const hoverStyles = {
|
||||
backgroundColor: 'black',
|
||||
borderColor: 'black',
|
||||
cursor: 'default',
|
||||
};
|
||||
Object.assign(newButtonCompany.style, hoverStyles);
|
||||
});
|
||||
} else {
|
||||
newButtonCompany.textContent = 'Try Again';
|
||||
}
|
||||
},
|
||||
// Extract company-specific data from the DOM
|
||||
const companyNameElement = document.querySelector(
|
||||
'.org-top-card-summary__title',
|
||||
);
|
||||
const domainNameElement = document.querySelector(
|
||||
'.org-top-card-primary-actions__inner a',
|
||||
);
|
||||
const addressElement = document.querySelectorAll(
|
||||
'.org-top-card-summary-info-list__info-item',
|
||||
)[1];
|
||||
const employeesNumberElement = document.querySelectorAll(
|
||||
'.org-top-card-summary-info-list__info-item',
|
||||
)[3];
|
||||
|
||||
// Include the button in the DOM.
|
||||
parentDiv.prepend(newButtonCompany);
|
||||
// Get the text content or other necessary data from the DOM elements
|
||||
const companyName = companyNameElement
|
||||
? companyNameElement.getAttribute('title')
|
||||
: '';
|
||||
const domainName = extractDomain(
|
||||
domainNameElement && domainNameElement.getAttribute('href'),
|
||||
);
|
||||
const address = addressElement
|
||||
? addressElement.textContent?.trim().replace(/\s+/g, ' ')
|
||||
: '';
|
||||
const employees = employeesNumberElement
|
||||
? Number(
|
||||
employeesNumberElement.textContent
|
||||
?.trim()
|
||||
.replace(/\s+/g, ' ')
|
||||
.split('-')[0],
|
||||
)
|
||||
: 0;
|
||||
|
||||
// Write button specific styles here - common ones can be found in createButton.ts.
|
||||
const buttonSpecificStyles = {
|
||||
alignSelf: 'end',
|
||||
// Prepare company data to send to the backend
|
||||
const companyInputData: CompanyInput = {
|
||||
name: companyName ?? '',
|
||||
domainName: domainName,
|
||||
address: address ?? '',
|
||||
employees: employees,
|
||||
};
|
||||
|
||||
Object.assign(newButtonCompany.style, buttonSpecificStyles);
|
||||
// Extract active tab url using chrome API - an event is triggered here and is caught by background script.
|
||||
const { url: activeTabUrl } = await chrome.runtime.sendMessage({
|
||||
action: 'getActiveTabUrl',
|
||||
});
|
||||
|
||||
// Convert URLs like https://www.linkedin.com/company/twenty/about/ to https://www.linkedin.com/company/twenty
|
||||
const companyURL = extractCompanyLinkedinLink(activeTabUrl);
|
||||
companyInputData.linkedinLink = { url: companyURL, label: companyURL };
|
||||
|
||||
const company = await fetchCompany({
|
||||
linkedinLink: {
|
||||
url: { eq: companyURL },
|
||||
label: { eq: companyURL },
|
||||
},
|
||||
});
|
||||
if (company) {
|
||||
const savedCompany: HTMLDivElement = createNewButton(
|
||||
'Saved',
|
||||
async () => {},
|
||||
);
|
||||
// Include the button in the DOM.
|
||||
parentDiv.prepend(savedCompany);
|
||||
|
||||
// Write button specific styles here - common ones can be found in createButton.ts.
|
||||
const buttonSpecificStyles = {
|
||||
alignSelf: 'end',
|
||||
};
|
||||
|
||||
Object.assign(savedCompany.style, buttonSpecificStyles);
|
||||
} else {
|
||||
const newButtonCompany: HTMLDivElement = createNewButton(
|
||||
'Add to Twenty',
|
||||
async () => {
|
||||
const response = await createCompany(companyInputData);
|
||||
|
||||
if (response) {
|
||||
newButtonCompany.textContent = 'Saved';
|
||||
newButtonCompany.setAttribute('disabled', 'true');
|
||||
|
||||
// Button specific styles once the button is unclickable after successfully sending data to server.
|
||||
newButtonCompany.addEventListener('mouseenter', () => {
|
||||
const hoverStyles = {
|
||||
backgroundColor: 'black',
|
||||
borderColor: 'black',
|
||||
cursor: 'default',
|
||||
};
|
||||
Object.assign(newButtonCompany.style, hoverStyles);
|
||||
});
|
||||
} else {
|
||||
newButtonCompany.textContent = 'Try Again';
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Include the button in the DOM.
|
||||
parentDiv.prepend(newButtonCompany);
|
||||
|
||||
// Write button specific styles here - common ones can be found in createButton.ts.
|
||||
const buttonSpecificStyles = {
|
||||
alignSelf: 'end',
|
||||
};
|
||||
|
||||
Object.assign(newButtonCompany.style, buttonSpecificStyles);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user