Skip to content

Commit

Permalink
Merge branch 'package'
Browse files Browse the repository at this point in the history
  • Loading branch information
shridhar-tl committed Dec 31, 2024
2 parents cd444fd + facc3de commit 15588fa
Show file tree
Hide file tree
Showing 24 changed files with 822 additions and 276 deletions.
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@
"jquery": "3.7.1",
"js-sql-parser": "1.6.0",
"jspdf": "github:shridhar-tl/jsPDF",
"jspdf-autotable": "3.8.2",
"jspdf-autotable": "3.8.4",
"moment": "2.30.1",
"moment-timezone": "0.5.45",
"moment-timezone": "0.5.46",
"papaparse": "5.4.1",
"patternomaly": "1.3.2",
"primeflex": "3.3.1",
Expand All @@ -88,7 +88,7 @@
"react-dnd": "16.0.1",
"react-dnd-html5-backend": "16.0.1",
"react-dom": "18.3.1",
"react-router-dom": "7.1.0",
"react-router-dom": "7.1.1",
"react-scripts": "github:shridhar-tl/react-scripts",
"static-eval": "2.1.1",
"zustand": "5.0.2"
Expand All @@ -98,7 +98,7 @@
"cross-env": "^7.0.3",
"eslint": "^9.17.0",
"eslint-plugin-react-hooks": "^5.1.0",
"gh-pages": "^6.1.1",
"gh-pages": "^6.2.0",
"react-app-alias": "^2.2.2",
"sass": "^1.83.0",
"webpack-bundle-analyzer": "^4.10.2"
Expand Down Expand Up @@ -136,6 +136,7 @@
"as-needed"
],
"no-unused-vars": "off",
"no-undef": "error",
"no-unreachable": "error",
"eqeqeq": "error",
"semi": "error",
Expand Down
5 changes: 4 additions & 1 deletion src/common/FeedbackPromise.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ class FeedbackPromise extends Promise {
};

try {
executor(resolve, reject, progress);
const result = executor(resolve, reject, progress);
if (typeof result?.then === 'function') {
result.then(resolve, reject);
}
} catch (err) {
reject(err);
}
Expand Down
73 changes: 73 additions & 0 deletions src/common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,77 @@ export function viewIssueUrl(root, key) {
export function stop(e) {
e.stopPropagation();
e.preventDefault();
}

export function replaceRepeatedWords(names) {
const total = names.length;
if (total === 0) { return []; }

// Separate first two and last one characters, and middle part
const separated = names.map(name => {
if (name.length <= 3) {
// If the name is too short, no replacement
return { start: name, middle: '', end: '' };
}
return {
start: name.slice(0, 2),
middle: name.slice(2, -1),
end: name.slice(-1)
};
});

// Split the middle parts into tokens
const middleTokens = separated.map(parts => parts.middle.split(' '));

// Find the maximum number of tokens in the middle parts
const maxTokens = middleTokens.reduce((max, tokens) => Math.max(max, tokens.length), 0);

// Initialize an array to hold token counts for each position
const tokenCounts = Array.from({ length: maxTokens }, () => ({}));

// Count occurrences of each token in each position
for (let i = 0; i < maxTokens; i++) {
for (let j = 0; j < total; j++) {
const tokens = middleTokens[j];
if (i < tokens.length) {
const token = tokens[i];
// Ignore tokens with numbers and those with length <= 3
if (!/\d/.test(token) && token.length > 3) {
tokenCounts[i][token] = (tokenCounts[i][token] || 0) + 1;
}
}
}
}

// Determine which token positions should be replaced
const positionsToReplace = new Set();
for (let i = 0; i < maxTokens; i++) {
for (const [token, count] of Object.entries(tokenCounts[i])) {
if (count / total >= 0.5) {
positionsToReplace.add(i);
break; // Replace if any token in this position meets the criteria
}
}
}

// Replace the tokens in the middle parts
const processedMiddle = middleTokens.map(tokens => tokens.map((token, idx) => {
if (positionsToReplace.has(idx) && token.length > 3 && !/\d/.test(token)) {
return '...';
}
return token;
}).join(' ')
);

// Reconstruct the full strings ensuring first two and last one characters are intact
const replacedNames = separated.map((parts, idx) => {
const middle = processedMiddle[idx];
// Handle cases where middle is empty
if (middle === '') {
return parts.start + parts.end;
}
return (parts.start + middle + parts.end).replace(/([.]+\s*){3,}/g, '...').replace(/([.]+\s*){2}/g, '...');
});

return replacedNames;
}
1 change: 1 addition & 0 deletions src/constants/api-urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const ApiUrls = {
bulkImportIssue: "~/rest/api/2/issue/bulk",
getProjectImportMetadata: "~/rest/api/2/issue/createmeta?expand=projects.issuetypes.fields&projectKeys=",
getProjectStatuses: "~/rest/api/2/project/{0}/statuses",
getJiraStatuses: "~/rest/api/2/status",
getIssueMetadata: "~/rest/api/2/issue/{0}/editmeta",
individualIssue: "~/rest/api/2/issue/{0}",
getAllIssueTypes: "~/rest/api/2/issuetype",
Expand Down
2 changes: 1 addition & 1 deletion src/controls/TextBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TextBox extends PureComponent {
if (multiline) {
return (
<InputTextarea rows={rows} value={value} autoResize={autoResize} keyfilter={keyfilter} style={style} maxLength={maxLength} disabled={disabled}
className={`w-p-100 ${className || ''}`} placeholder={placeholder} onChange={this.onChange} onKeyPress={this.keyPress}
className={`w-100 ${className || ''}`} placeholder={placeholder} onChange={this.onChange} onKeyPress={this.keyPress}
onBlur={this.props.onBlur} />
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/dialogs/AddWorklog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class AddWorklog extends BaseDialog {
<strong>Ticket no</strong>
</div>
<div className="col-sm-9">
<IssuePicker value={log.ticketNo} useDisplay={true} className="w-p-100" tabIndex="3"
<IssuePicker value={log.ticketNo} useDisplay={true} className="w-100" tabIndex="3"
placeholder="Enter the ticket number or start typing the summary to get suggestion"
disabled={log.isUploaded} maxLength={20} onPick={(val) => this.setValue("ticketNo", val, true)} />
<span className={`help-block ${vald.ticketNo ? '' : 'msg-error'}`}>Provide the ticket no on which you had to log your work</span>
Expand Down
6 changes: 6 additions & 0 deletions src/gadgets/Calendar/Calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,12 @@ class Calendar extends BaseGadget {

this.addEvent({ previousTime: oldDate, edited: entry });
//this.updateAllDayEvent(event);
}).finally(() => {
const icon = e.el.querySelector('i.fa-refresh');
if (icon) {
icon.classList.replace('fa-refresh', 'fa-ellipsis-v');
icon.classList.remove('fa-spin');
}
});
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/gadgets/WorklogReport/TicketEstimate.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import './TicketEstimate.scss';

function TicketEstimate({ est, rem, logged, variance }) {
const estTitle = `Original Estimate: ${est || 0}\nRemaining: ${rem || 0}\nTotal Logged: ${logged}\nEstimate Variance: ${variance}`;

return (
<div className="ticket-estimate" title={estTitle}>
<span className="ticket-item est">
<span className="fas fa-clock" /> Est: {est}
</span>
<span className="ticket-item rem">
<span className="fas fa-clipboard" /> Rem: {rem}
</span>
<span className="ticket-item log">
<span className="fas fa-hourglass-half" /> Log: {logged}
</span>
<span className="ticket-item var">
<span className="fas fa-exclamation-triangle" /> Var: {variance}
</span>
</div>
);
}

export default TicketEstimate;
50 changes: 50 additions & 0 deletions src/gadgets/WorklogReport/TicketEstimate.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
div.ticket-estimate {
display: flex;
align-items: center;
max-width: 500px;
height: 22px;
overflow: hidden;

.ticket-item {
display: flex;
align-items: center;
clip-path: polygon(10% 0%, 90% 0%, 77% 50%, 90% 100%, 10% 100%, 0% 50%);
padding: 0 25px 2px 8px;
margin: 0;
font-size: 12px;
color: #fff;
white-space: nowrap;
height: 21px;
transition: transform 0.2s;
cursor: pointer;

.fas {
margin-right: 4px;
font-size: 10px;
}

&:hover {
transform: scale(1.08);
}

&.est {
background: linear-gradient(135deg, #d1e7dd, #98e2d6);
color: #0f5132;
}

&.rem {
background: linear-gradient(135deg, #cff4fc, #89dffd);
color: #055160;
}

&.log {
background: linear-gradient(135deg, #fff3cd, #ffe066);
color: #664d03;
}

&.var {
background: linear-gradient(135deg, #f8d7da, #f8d7da);
color: #842029;
}
}
}
5 changes: 3 additions & 2 deletions src/gadgets/WorklogReport/userdaywise/Common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ div.scroll-table-container .scroll-table {

td {
div.wl-ticket-detail {
width: 360px;
height: 25px;
width: 100%;
max-width: 500px;
height: 22px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
Expand Down
4 changes: 2 additions & 2 deletions src/gadgets/WorklogReport/userdaywise/shared.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Image, Link } from '../../../controls';
import { connect } from "../datastore";
import TicketEstimate from '../TicketEstimate';

export const WeeksList = connect(function ({ weeks }) {
return weeks.map((day, i) => <th key={i} className="week-head" colSpan={day.days}>{day.display}</th>);
Expand Down Expand Up @@ -59,8 +60,7 @@ export function IssueInfo({ issue: t, showParentSummary, hideEstimate, convertSe
<Link href={t.url} className="link">{t.ticketNo}</Link> -
<span>{t.summary}</span>
</div>
{!hideEstimate && !!(oe || re) && <span className="estimate" title={estTitle}>
(est: {oe || 0} / rem: {re || 0} / log: {logged} / var: {variance})</span>}
{!hideEstimate && !!(oe || re) && <TicketEstimate est={oe} rem={re} logged={logged} variance={variance} />}
</td>);
}

Expand Down
6 changes: 1 addition & 5 deletions src/scss/_custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,14 @@ body {

/* #region Width related styles */

.w-p-100 {
width: 100%;
}

.w-80 {
width: 80px;
}

/* #endregion */

/* #region Padding related styles */
.no-pad {
.no-padding {
padding: 0 !important;
}

Expand Down
4 changes: 2 additions & 2 deletions src/scss/prime.scss
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ a.p-menuitem-link {
}

.p-tabview-nav-content {
overflow-y: auto;
overflow-x: auto;
height: 34px;

Expand Down Expand Up @@ -192,7 +191,8 @@ a.p-menuitem-link {

ul.p-dropdown-items,
ul.p-autocomplete-items,
ul.p-multiselect-items {
ul.p-multiselect-items,
ul.p-contextmenu-root-list {
padding: 0;
}

Expand Down
16 changes: 14 additions & 2 deletions src/services/jira-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ export default class JiraService {

const result = await Promise.all(projects.map(async p => {
const cacheKey = `projectStatuses_${p}`;
let project = this.$jaCache.session.get();
let project = this.$jaCache.session.get(cacheKey);

if (!project) {
project = await this.$ajax.get(ApiUrls.getProjectStatuses, p);
Expand All @@ -281,6 +281,18 @@ export default class JiraService {
return onlyOne ? result[0] : result;
}

async getJiraStatuses() {
const cacheKey = `jiraStatuses`;
let statuses = this.$jaCache.session.get(cacheKey);

if (!statuses) {
statuses = await this.$ajax.get(ApiUrls.getJiraStatuses);
this.$jaCache.session.set(cacheKey, statuses);
}

return statuses;
}

async getIssueMetadata(issuekey) {
let value = await this.$jaCache.session.getPromise(`issueMetadata_${issuekey}`);
if (value) {
Expand Down Expand Up @@ -431,7 +443,7 @@ export default class JiraService {
return result?.value;
} catch (err) {
if (!err.error?.errorMessages?.[0]?.includes("does not exist")) {
console.error(`Failed to fetch property ${propertyKey} for sprint ${sprintId}:`, error);
console.error(`Failed to fetch property ${propertyKey} for sprint ${sprintId}:`, err);
}
return null;
}
Expand Down
Loading

0 comments on commit 15588fa

Please sign in to comment.